抽象改变了吗?

时间:2012-08-01 08:17:30

标签: oop design-patterns solid-principles abstract-factory

我的问题是,如何重新设计抽象工厂。

例如,我获得了下一个车辆抽象:

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;
    }
}
很好,但(!!!)私家车与它无关! 我可以使用什么样的设计?旧抽象不正确?

非常感谢!!!

2 个答案:

答案 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(); }
}