我的问题是,如何重新设计抽象工厂。
例如,我获得了下一个车辆抽象:
interface IEngine { int Power(); }
class Gasoline : IEngine { public int Power() {return 150; }}
class Diesel : IEngine { public int Power() { return 50; }}
interface IFrame { string Name(); }
class Boxed : IFrame { public string Name() { return "Boxed frame"; }}
class Hat : IFrame { public string Name() { return "Hat frame"; }}
interface TransportFactory {
IEngine CreateEngine();
IFrame CreateChassis();
}
class TrailerCar : TransportFactory {
public IEngine CreateEngine() { return new Diesel(); }
public IFrame CreateChassis() { return new Boxed(); }
}
class PrivateCar : TransportFactory {
public IEngine CreateEngine() { return new Gasoline(); }
public IFrame CreateChassis() { return new Hat(); }
}
现在,我可以实例化私人或拖车。
有人建议我改变:拖车车的发动机可以通过涡轮增压或混合动力。仅适用于预告片!对于私家车柴油和汽油发动机仍然是通常的柴油发动机 所以,如果我做了改变:
public enum EngineType { Hybrid, Turbo, }
interface TransportFactory
{
IEngine CreateEngine(EngineType t);
IFrame CreateChassis();
}
我可以添加课程:
class GasolineHybrid : IEngine
{
public int Power()
{
return 70;
}
}
class GasolineTurbo : IEngine
{
public int Power()
{
return 170;
}
}
class DieselHybrid : IEngine
{
public int Power()
{
return 60;
}
}
class DieselTurbo : IEngine
{
public int Power()
{
return 98;
}
}
很好,但(!!!)私家车与它无关!
我可以使用什么样的设计?旧抽象不正确?
非常感谢!!!
答案 0 :(得分:1)
怎么样:
class GasolineHybridTrailerCar : TransportFactory
{
public IEngine CreateEngine()
{
return new GasolineHybrid();
}
...
}
class GasolineTurboTrailerCar : TransportFactory
{
public IEngine CreateEngine()
{
return new GasolineTurbo();
}
...
}
class DieselHybridTrailerCar : TransportFactory
{
public IEngine CreateEngine()
{
return new DieselHybrid();
}
...
}
class DieselTurboTrailerCar : TransportFactory
{
public IEngine CreateEngine()
{
return new DieselTurbo();
}
...
}
产生大量课程背后的想法是消除客户做错选择的能力。既然你说混合动力和涡轮增压发动机对私家车没有意义,那么保持 IEngine CreateEngine(EngineType t); 将要求私家车厂额外努力拒绝不正确的论据。
我不确定你的意思,但是班级名称表明汽车是工厂的产品。在经典关系中,它将是factory --produce--> product
。如何通过泛化来表达它是一种淫乱和有趣的事情,但其他人却难以辨认。模式的美妙之处在于,一旦你听到一个单词的名字,你就会对实现所暗示的所有内部结构充满信心。
有模式Builder。它会更适合您的设计吗?
答案 1 :(得分:0)
请记住,参数不必是接口的一部分,它们可以传递给实现的构造函数。所以你仍然可以保留旧界面:
interface TransportFactory
{
IEngine CreateEngine();
IFrame CreateChassis();
}
但将EngineType
传递给TrailerCar
构造函数:
class TrailerCar : TransportFactory {
private readonly EngineType engineType;
public TrailerCar(EngineType engineType)
{
this.engineType = engineType;
}
public IEngine CreateEngine()
{
if (engineType == EngineType.Hybrid) return new DieselHybrid();
else return new DieselTurbo();
}
public IFrame CreateChassis() { return new Boxed(); }
}