抽象工厂设计模式与默认实现

时间:2013-01-21 08:36:28

标签: c++ design-patterns abstract-class

我必须根据客户类型创建对象族。 我有一个基本的抽象类ApplicationRulesFactory,它定义了 虚拟接口。很多具体的客户类都继承自这个类。

问题是,对于一些客户说CustomerB我们不使用对象Rule2和Rule3,因为应用程序中使用这些对象Rule2和Rule3的功能已从该客户的应用程序用户界面禁用,因此我们不是真的需要实例化这些对象。

简化代码在这里,即实际上ApplicationRulesFactory有更多虚拟方法,以及从中继承的更具体的客户类:

class ApplicationRulesFactory
{
  virtual Rule1*  GetRule1() = 0;
  virtual Rule2*  GetRule2() = 0;
  virtual Rule3*  GetRule3() = 0;   
  .....
};

class ACustomerRulesFactory : public ApplicationRulesFactory
{
   Rule1* GetRule1()
   {
     return new ACustomerRule1();
   }

  Rule2 * GetRule2()
  {
    return new ACustomerRule2();
  }  

 Rule3* GetRule3()
 {
   return new ACustomerRule3();
 }  
};  

class BCustomerRulesFactory : public ApplicationRulesFactory
{
    Rule1* GetRule1()
    {
      return new BCustomerRule1();
    }
    Rule2* GetRule2() // not needed
    {
      // what to return here ?
    }  
    Rule3* GetRule3() // not needed
    {
     // what to return here ?
    }
};

那我该怎么做呢:

1)在基类ApplicationRulesFactory中返回一些默认实现:

class ApplicationRulesFactory
{
  virtual Rule1*  GetRule1() = 0;
  virtual Rule2*  GetRule2()  { return new Rule2DefaultImpl();}
  virtual Rule3*  GetRule3()  { return new Rule3DefaultIml();}   
};

但是这似乎是错误的,从Rule1,Rule2继承新类(Rule1DefaultImpl,Rule2DefaultImpl),并且可能只是为了将它们作为返回它们的目的而使它们像ApplicationRulesFactory中的默认实现一样

2)或在具体类中返回默认实现并将这些方法保留为基类中的虚拟

class BCustomerRulesFactory : public ApplicationRulesFactory
{
  Rule1* GetRule1()
  {
     return new BCustomerRule1();
  }

  Rule2* GetRule2() 
  {
    return new Rule2DefaultImpl();
  }

 Rule3* GetRule3() 
 {
    return new Rule3DefaultImpl();
 }
};

这些解决方案在每个具体客户类中重新定义方法似乎也非常难看,尽管不需要它们。

3)我也有一种感觉,也许我不应该像这样使用继承,因为这违反了继承的IS-A规则,导致大量的方法不适用于所有具体的客户类,但是如果没有继承,就不怎么去实现它。

任何想法

3 个答案:

答案 0 :(得分:4)

如果ApplicationRulesFactory对某些Customers没有意义,那么它对你来说就不是正确的抽象。

您的域knows什么是有意义的,那么为什么会要求Rule2Rule3

让对象知道它只需要Rule1使用只给它Rule1的工厂。给它一个上下文,以便它可以得到它所需的工厂。

答案 1 :(得分:1)

您似乎将界面和工厂混合在一起。当然接口应该是一个类本身,各种规则在基类中具有默认行为,然后在派生类中重写行为,然后工厂返回指向实现正确规则的请求类的指针对于那种情况。

但也许我误解了你想要达到的目标......

答案 2 :(得分:0)

如果规则永远不会被使用,我建议只从基类实现返回一个空指针(大多数情况下你的选项,除了甚至不打扰默认实现,因为它永远不会被调用)。