我熟悉这些模式,但仍然不知道如何处理以下情况:
public class CarFactory
{
public CarFactory(Dep1,Dep2,Dep3,Dep4,Dep5,Dep6)
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(Dep1,Dep2,Dep3);
break;
case B:
return new Car2(Dep4,Dep5,Dep6);
break;
}
}
}一般来说,问题在于需要注入的引用量。如果有更多的汽车,情况会更糟。
我想到的第一种方法是在工厂构造函数中注入Car1和Car2,但这与工厂方法背道而驰,因为工厂总是返回相同的对象。第二种方法是注入servicelocator,但它到处都是反模式的。如何解决这个问题?
编辑:
备选办法1:
public class CarFactory
{
public CarFactory(IContainer container)
{
_container = container;
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return _container.Resolve<ICar1>();
break;
case B:
return _container.Resolve<ICar2>();
break;
}
}
}可供选择的方法2(由于树中的依赖关系太多而难以使用):
public class CarFactory
{
public CarFactory()
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(new Dep1(),new Dep2(new Dep683(),new Dep684()),....)
break;
case B:
return new Car2(new Dep4(),new Dep5(new Dep777(),new Dep684()),....)
break;
}
}
}发布于 2015-08-11 19:47:28
首先,您有一个混凝土工厂,IoC容器可能是一个替代方案,而不是帮助您的东西。
然后,只需重构工厂,以避免期望工厂构造函数中有一个完整的可能参数列表。这是主要问题--如果工厂方法不需要参数,为什么要传递这么多参数?
我宁愿将特定的参数传递给工厂方法。
public abstract class CarFactoryParams { }
public class Car1FactoryParams : CarFactoryParams
{
public Car1FactoryParams(Dep1, Dep2, Dep3)
{
this.Dep1 = Dep1;
...
}
public class Car2FactoryParams
...
public class CarFactory
{
public ICar CreateCar( CarFactoryParams params )
{
if ( params is Car1FactoryParams )
{
var cp = (Car1FactoryParams)params;
return new Car1( cp.Dep1, cp.Dep2, ... );
}
...
if ( params is ...通过将参数列表封装到特定的类中,您只需让客户端提供特定工厂方法调用所需的这些参数。
编辑:
不幸的是,从你的帖子中还不清楚这些Dep1是什么.以及你如何使用它们。
因此,我建议采用将工厂提供程序与实际工厂实现分开的方法。这种方法称为本地工厂模式:
public class CarFactory
{
private static Func<type, ICar> _provider;
public static void SetProvider( Func<type, ICar> provider )
{
_provider = provider;
}
public ICar CreateCar(type)
{
return _provider( type );
}
}工厂本身没有任何实现,它是为了为您的域API设置基础,您希望只使用这个API创建car实例。
然后,在复合根中(在配置实际容器的应用程序的起点附近),配置提供程序:
CarFactory.SetProvider(
type =>
{
switch ( type )
{
case A:
return _container.Resolve<ICar1>();
case B:
return _container.Resolve<ICar2>();
..
}
);注意,工厂提供程序的此示例实现使用委托,但接口也可以用作实际提供程序的规范。
这个实现基本上是你编辑的问题中的#1,但是它没有任何特别的缺点。客户仍然打电话给:
var car = new CarFactory().CreareCar( type );https://stackoverflow.com/questions/31950362
复制相似问题