2017-04-12 12 views
0

我目前正在從一個服務器發送數據到下一個服務的服務結構解決方案。當處理web請求時使用SOLID方法

我正在發送具有多個屬性的類。這個類是一種數據傳輸對象。我想用一種可靠的方法來防止使用導致切換邏輯的整數。

即。我不想這樣:

public void ExecuteFunctionForType(IntegerTypedClass myClass, IInterface myinterface) 
{ 
    switch(myClass.typeInt) 
    { 
     case 1: 
      // Do shizzle for type 1 
      myinterface.execute1(); 
      break; 
     case 2: 
      // do shizzle for type 2 
      myinterface.execute2(); 
      break; 
    } 
} 

而是我想實現一個SOLID方法。浮現在腦海的一個如下圖所示:

public abstract class AbstractTypedClass 
{ 
    public abstract void ExecuteInheritedFunction(IInterface myinterface); 
} 

public class FirstTypedClass : AbstractTypedClass 
{ 
    public override void ExecuteInheritedFunction(IInterface myinterface) 
    { 
     // do shizzle for the first typed class 
     myinterface.execute1(); 
    } 
} 

public class SecondTypedClass : AbstractTypedClass 
{ 
    public override void ExecuteInheritedFunction(IInterface myinterface) 
    { 
     // do shizzle for the second typed class 
     myinterface.execute2(); 
    } 
} 

這種方法的問題是,AbstractTypedClass,它的所有的孩子都會對IInterface,我不想依賴。這是由於它是一個服務結構接口,它帶來了很多其他的依賴關係。 我希望有一個解決方案,你可以使用固體原則,而不是建立在不同的庫的依賴,這將弄亂我的解決方案

事情我不能使用:

部分類,因爲他們需要要在同一assemvly

擴展方法,因爲默認的方法被調用:

public static class TypedClassExtensions 
{ 
    public static void executeExtension(this AbstractTypedClass request, IInterface myinterface) 
    { 
     throw new NotImplementedException(); 
    } 
    public static void executeExtension(this FirstTypedClass request, IInterface myinterface) 
    { 
     myinterface.execute1(); 
    } 
} 

// when calling the code like so, the not implemented exception is thrown: 
public void execute(AbstractTypedClass myclass, IInterface myinterface) 
{ 
    myclass.executeExtension(myinterface); 
} 
+0

嘗試戰略模式http://blogs.microsoft.co.il/gilf/2009/11/22/applying-strategy-pattern-instead-of-using-switch-statements/ – Nkosi

+0

是不是什麼策略我剛剛描述過?如果我使用策略,我仍然堅持依賴於接口。我正在尋找一種方法來消除依賴關係 – martijn

+0

向我們展示您所需的設計輸出。它不必工作..只是爲了得到想法。因爲你說過你不需要'interface'依賴。 – niksofteng

回答

1

在C#7,您可以使用模式匹配避免使用策略或訪問者模式。這會導致代碼更清晰,因爲您不必將相同的方法添加到所有具體類,或使用雙派遣。

void ExecuteFunctionForType(AbstractTypedClass myClass, IInterface myinterface) 
{ 
    switch(myClass) 
    { 
     case FirstTypedClass it1: 
      // Do shizzle for type 1 
      myinterface.execute1(it1.Prop1); 
      break; 
     case SecondTypedClass it2: 
      // do shizzle for type 2 
      myinterface.execute2(it2.Prop2); 
      break; 
    } 
} 

假設接口和實現是這樣的:

interface IInterface {void execute1(string input);void execute2(int input);} 

class SomeClass:IInterface 
{ 
    public void execute1(string input) => Console.WriteLine($"1 {input}"); 
    public void execute2(int input) => Console.WriteLine($"2 {input}"); 
} 

像這樣的類:

public abstract class AbstractTypedClass{ } 

public class FirstTypedClass : AbstractTypedClass 
{ 
    public string Prop1 =>"First"; 
} 

public class SecondTypedClass : AbstractTypedClass 
{ 
    public int Prop2 =>500; 
} 

你可以調用每個類型與執行switch語句不同的方法模式匹配類型。以下代碼:

var it=new SomeClass(); 
ExecuteFunctionForType(new FirstTypedClass(),it); 
ExecuteFunctionForType(new SecondTypedClass(),it); 

會產生:

1 First 
2 500 

模式上類型的匹配返回匹配類型的強類型的變量。每個具體類型的成員都可以使用,而不需要對接口或抽象類進行定義。

+0

我喜歡這種方法。不幸的是,我們尚未使用C#7.0 – martijn

0

採用固體原則,我覺得你的方法是這樣的:

的依賴倒置原則,建議您僅依賴於你需要的功能的接口。所以在你的抽象類中,我會簡單地使它成爲泛型,並在抽象類的實現中定義依賴關係。這樣,如果你可以在不同的程序集中實現不同的版本,那些程序集就不會有不必要的依賴關係。

// ------------ Assembly A ----------------- 
public abstract class AbstractTypedClass<T> 
{ 
    public abstract void ExecuteInheritedFunction(T obj); 
} 

// ------------ Assembly B ----------------- 
IHugeDependency 
{ 
    void execute1(); 
    ...more 
} 

public class FirstTypedClass : AbstractTypedClass<IHugeDependency> 
{ 
    public override void ExecuteInheritedFunction(IHugeDependency obj) 
    { 
     // do shizzle for the first typed class 
     obj.execute1(); 
    } 
} 

// ------------ Assembly C ----------------- 
ISmallerDependency 
{ 
    void execute2(); 
} 

public class SecondTypedClass : AbstractTypedClass<ISmallerDependency> 
{ 
    public override void ExecuteInheritedFunction(ISmallerDependency obj) 
    { 
     // do shizzle for the second typed class 
     obj.execute2(); 
    } 
} 

使用這種方法大會B和C都對一個依賴,但乙& C未無故彼此的依賴。