美文网首页
设计模式——抽象工厂

设计模式——抽象工厂

作者: 东方胖 | 来源:发表于2023-08-12 23:01 被阅读0次

    抽象工厂的要点是
    在 context 中,我们不需要规定要创建那个具体的子类

    Provide and interface for creating families of related or dependent objects without specifying their concrete classes.

    比如我们有一组产品

    class AbstractProduct {
    };
    
    class ProductA: public AbstractProduct {
    };
    class ProductB: public AbstractProduct {
    };
    
    // 创建产品A、B的上下文
    AbstractProduct * pa = new ProductA();
    AbstractProduct * pb = new ProductB();
    

    抽象工厂是要把上面的 new ProductA() 隐藏。通过工厂方法也可以做到,
    上面的代码通过工厂方法变成下面这种调用方式,创建动作从接口出:

    Factory* factory = new MyFactory;
    fatory->createProductA(); 
    

    大概如此
    现在,
    设想产品出现更复杂的分类,如,现在有另一系列的 AbstractProduct2出现

    class AbstractProduct2
    {
    };
    
    class Product2A : public AbstractProduct2
    {
    };
    class Product2B : public AbstractProduct2
    {
    };
    

    这组产品有不同的抽象,所以无法在上面的工厂方法中共享接口。
    产品返回的 AbstractProduct * 类型。
    继承树是另一棵。

    所以,为了达到那个 隐藏 new ProductXXX(); 的目的,我们不得不再为它创建另一个工厂 MyFactory2,这个工厂针对是系列2的产品。

    于是创建产品2 代码可能是这样

    Factory * factory = new MyFactory2;
    factory->createProduct2A();
    

    用工厂方法,我们对每个系列的产品可以定义一个工厂,哇,这应该是可行的。

    现在,因为产品的树,每棵对应一个工厂,这样一系列的工厂诞生了,如果视工厂为一种“新的产品”,那么实际上我们使用工厂方法的时候,又凭空造出了一棵产品树,这些新产品还是用着暴露hardcode方式在context使用

    ProductFactory* factory =  new ProductFactory();
    

    抽象工厂模式的想法是,对这种新的工厂树施以工厂方法。隐藏上面那种 new XXXFactory()的代码。

    类似工厂方法,对工厂产品我们将抽象几个接口,然后具体的工厂在子类中实现之

    class AbstractFactory
    {
    public:
         AbstractProduct* createProduct() = 0;
         AbstractProduct2* createProduct2() = 0;
    };
    
    class ProductFactory: public AbstractFactory
    {
    public:
          AbstractProduct* createProduct()  {
               return new ProductA();
          }
          AbstractProduct2* createProduct2() {
              return new Product2A();
         }
    };
    

    client

    ProductFactory factory;
    createObject(&factory); // createObject(AbstractFactory &); 接口声明为如此,参数是个抽象工厂
    

    在 createObject 内部则不再关心 factory到底是哪个具体的工厂,这样做到了在 createObject的实现具有一种抽象作用。
    带了一些灵活性。

    抽象工厂一般会带来大量的class ,一棵产品树里每个节点都是一个类,同时具体的工厂对应每棵树也有一个类。

    扩展时 新建一个工厂,新建产品 即可

    总结

    抽象工厂和工厂方法的区别。

    • 它们都试图将代码中那种 new XXX();具体指定的硬编码抽象成接口,对调用的上下文隐藏起来,带来一种修改不影响client的代码的效果
    • 但是工厂方法一般只有一个产品系列,即被创建的类型一般就是一棵继承树,而抽象工厂不止一棵继承树
    • 通常工厂方法的特点是 createObject(type) 或者, 创建一个工厂 factory = new ConceretFactory();然后用factory的 虚函数接口创建所需要产品。
      而抽象工厂必有一个抽象的 Factory 作为某个创建函数的参数,然后把具体类型传入,在某个创建上下文中持有factory的句柄来操作,利用虚函数的特性来实现运行选择哪个工厂来创建。

    相关文章

      网友评论

          本文标题:设计模式——抽象工厂

          本文链接:https://www.haomeiwen.com/subject/uytfmdtx.html