我有class A{}
class B:A{}
class C:A{}
和class D{}
D有方法需要使用B和需要使用C
的方法。
将来我可能会有更多继承自A
需要使用的D
的课程
D
应该有如下构造函数:
公开D(B b, C c)
或A
应该获得一个简单的工厂(F)
,它将返回
正确的课程。然后构造函数将是public D(F f)
F
将使用CreateInstance
方法获取枚举并返回正确的类型。
完全注射将保留组合物中的所有根。 简单的工厂会简化构造函数。
答案 0 :(得分:2)
您需要注意的问题是通过工厂方法引入不透明的依赖项。
此时,D依赖于B 和 C.使用如下构造函数:
public D(B b, C c)
{
}
使依赖项透明。即它清楚这个班级需要做什么工作,这些东西可以直接提供。此外,自动化测试更容易,因为您可以直接提供假货,而无需提供假冒工厂提供其他假货。
使用工厂降低了这种清晰度,但通过减少必须传递的依赖项数量,确实增加了便利性和一定程度的面向未来。
就个人而言,我会坚持直接提供依赖项,直到构造函数签名不实用或明显需要更高级别的抽象,如工厂。这个类依赖于 B
和 C
的事实发出了一个明确的设计信息,即工厂之类的抽象可能会模糊不清。
答案 1 :(得分:1)
在我看来,在B和C实现相同界面的情况下,正确的方法是传递factory
。此外,我会避免依赖具体类型,而是依赖于接口。如果您必须专门获取这些2或者为每个其他接口添加并依赖于该接口,或者去工厂。
(有关更完整的示例,请参阅this question )
public enum XTypes
{
A,B,C...
}
public interface IXFactory
{
IX GetX(XTypes xType);
}
public interface IX
{
void SomeMethod()
}
//And I'd do A as an abstract class and rename to XBase
public class A : IX
{
public void SomeMethod() {}
}
public class D
{
public D(IXFactory xFactory)
{
XFactory = xFactory;
}
public void SomeMethod()
{
var x1 = XFactory.GetX(XTypes.A);
var x2 = XFactory.GetX(XTypes.C);
}
public IXFactory XFactory { get; set; }
}
我个人不会在下列情况下出厂:
IEnumerable<IDependency>
此外,让IX
本身声明他的密钥(在本例中为enum
)然后工厂的实现非常干净是很好的。
同样 - 在Castle Windosr
中(我确信在其他Ioc容器中也是如此),您可以通过实施{{1}来操纵TypedFactoryFacility
然后你甚至不需要自己实施工厂。
*如果代替ITypedFactoryComponentSelector
您将拥有一个对象,则可以将enum
更改为IX
,然后IX<XRequestBase>
将自动映射并运行:)