請原諒我提前僞代碼!
閱讀SOLID原則。使用接口的SOLID原則有幾個原因。接口允許你解耦你的依賴實現。您可以通過使用像StructureMap這樣的工具來進一步提高耦合度。
在那裏你可以用來
Widget widget1 = new Widget;
這明確表示,要創建控件的新實例。但是,如果您在另一個對象的方法中執行此操作,則您現在正在說另一個對象直接依賴於Widget的使用。所以我們可以這樣說
public class AnotherObject
{
public void SomeMethod(Widget widget1)
{
//..do something with widget1
}
}
我們仍然綁定在這裏使用Widget。但至少這是更可測試的,因爲我們可以將Widget的實現注入到SomeMethod中。現在,如果我們要使用接口,我們可以進一步解耦。
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
請注意,我們現在不需要Widget的特定實現,而是我們要求的任何內容符合IWidget接口。這意味着可以注入任何東西,這意味着在代碼的日常使用中我們可以注入一個實際的Widget實現。但是這也意味着,當我們想測試這個代碼時,我們可以注入一個假/模擬/存根(取決於你對這些術語的理解)並測試我們的代碼。
但是我們怎樣才能更進一步。通過使用StructureMap,我們可以更多地解耦這些代碼。有了上次的代碼示例我們調用代碼我是這個樣子
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
public class CallingObject
{
public void AnotherMethod()
{
IWidget widget1 = new Widget();
new AnotherObject().SomeMethod(widget1);
}
}
正如你在我們通過傳遞符合iWidget的物體移除了的someMethod的依賴上面的代碼中看到。但是在CallingObject()。AnotherMethod中我們仍然有依賴關係。我們也可以使用StructureMap去除這個依賴關係!
[PluginFamily("Default")]
public interface IAnotherObject
{
...
}
[PluginFamily("Default")]
public interface ICallingObject
{
...
}
[Pluggable("Default")]
public class AnotherObject : IAnotherObject
{
private IWidget _widget;
public AnotherObject(IWidget widget)
{
_widget = widget;
}
public void SomeMethod()
{
//..do something with _widget
}
}
[Pluggable("Default")]
public class CallingObject : ICallingObject
{
public void AnotherMethod()
{
ObjectFactory.GetInstance<IAnotherObject>().SomeMethod();
}
}
注意,在上面的代碼中沒有我們實例化AnotherObject的實際實現。因爲一切都爲StructurMap連線,所以我們可以根據代碼運行的時間和地點,允許StructureMap傳遞適當的實現。現在代碼非常靈活,我們可以通過配置或編程方式指定我們想要使用哪種實現。這種配置可以實時完成或作爲構建過程的一部分等,但不一定要在任何地方進行硬連線。
我不明白反對... – 2009-08-26 15:36:52
的論點,如果你需要向你的團隊解釋爲什麼接口是一個很好的編程標準,那麼你應該找到一份新的工作..沒有冒犯.. – 2009-08-26 15:37:18
我同意找到一個新的工作評論。 – Finglas 2009-08-26 15:42:21