zoukankan      html  css  js  c++  java
  • 设计模式系列之抽象工厂模式

    重新思考一下前两篇文章提到的芯片设计软件,factory method模式可以通过实例化 RoundFactory,RecFactory和TriFactory来分别实现 MaskRound, MaskRec和MaskTri对象,将在掩模上设计圆形,矩形和三角形的功能延迟到子类当中,不过 MaskRound,MaskRec和MaskTri都继承自同一种Mask,假设现在光刻技术有了新的突破,需要在新的类型的Mask上设计芯片图形,factory method就无能为力了,这就要用到本文讲的abstract factory模式。

    假设现在有两种掩模,maskA和maskB,abstract factory模式的类结构图如下:

    maskA和maskB是两个独立的产品系列,具有独立的 MaskRound,MaskRec和MaskTri子类。 FigureFactory分别定义 CreateFigureA和 CreateFigureB创建maksA和maskB的图形。

    代码实现如下:

    //maskA.hpp
    #ifndef MASKA_HPP
    #define MASKA_HPP
    
    class MaskAFigure{
      public:
        virtual ~MaskAFigure()=0;
      protected:
        MaskAFigure();
    };
    
    class MaskARound:public MaskAFigure {
      public:
        MaskARound();
        ~MaskARound();
    };
    
    class MaskARec:public MaskAFigure {
      public:
        MaskARec();
        ~MaskARec();
    };
    
    class MaskATri:public MaskAFigure {
      public:
        MaskATri();
        ~MaskATri();
    };
    #endif
    //maskA.cpp
    #include <iostream>
    #include "maskA.hpp"
    
    using std::cout;
    using std::endl;
    
    MaskAFigure::MaskAFigure() {
    
    }
    
    MaskAFigure::~MaskAFigure() {
    
    }
    
    MaskARound::MaskARound() {
      cout<<"Draw roundness on MaskA"<<endl;
    }
    
    MaskARound::~MaskARound() {
    
    }
    
    MaskARec::MaskARec() {
      cout<<"Draw rectangle on MaskA"<<endl;
    }
    
    MaskARec::~MaskARec() {
    
    }
    
    MaskATri::MaskATri() {
      cout<<"Draw triangle on MaskA"<<endl;
    }
    
    MaskATri::~MaskATri() {
    
    }
    //maskB.hpp
    #ifndef MASKB_HPP
    #define MASKB_HPP
    
    class MaskBFigure{
      public:
        virtual ~MaskBFigure()=0;
      protected:
        MaskBFigure();
    };
    
    class MaskBRound:public MaskBFigure {
      public:
        MaskBRound();
        ~MaskBRound();
    };
    
    class MaskBRec:public MaskBFigure {
      public:
        MaskBRec();
        ~MaskBRec();
    };
    
    class MaskBTri:public MaskBFigure {
      public:
        MaskBTri();
        ~MaskBTri();
    };
    
    #endif
    //maskB.cpp
    #include <iostream>
    #include "maskB.hpp"
    
    using std::cout;
    using std::endl;
    
    MaskBFigure::MaskBFigure() {
    
    }
    
    MaskBFigure::~MaskBFigure() {
    
    }
    
    MaskBRound::MaskBRound() {
      cout<<"Draw roundness on MaskB"<<endl;
    }
    
    MaskBRound::~MaskBRound() {
    
    }
    
    MaskBRec::MaskBRec() {
      cout<<"Draw rectangle on MaskB"<<endl;
    }
    
    MaskBRec::~MaskBRec() {
    
    }
    
    MaskBTri::MaskBTri() {
      cout<<"Draw triangle on MaskB"<<endl;
    }
    
    MaskBTri::~MaskBTri() {
    
    }
    //abstractfactory.hpp
    #ifndef ABSTRACT_MASKFACTORY_HPP
    #define ABSTRACT_MASKFACTORY_HPP
    
    #include "maskB.hpp"
    #include "maskA.hpp"
    
    class FigureFactory {
     public:
      virtual ~FigureFactory()=0;
      virtual MaskAFigure* CreateFigureA()=0;
      virtual MaskBFigure* CreateFigureB()=0;
     protected:
      FigureFactory();
    };
    
    class RoundFactory:public FigureFactory {
     public:
      RoundFactory();
      ~RoundFactory();
      MaskARound* CreateFigureA();
      MaskBRound* CreateFigureB();
    };
    
    class RecFactory:public FigureFactory {
     public:
      RecFactory();
      ~RecFactory();
      MaskARec* CreateFigureA();
      MaskBRec* CreateFigureB();
    };
    
    class TriFactory:public FigureFactory {
     public:
      TriFactory();
      ~TriFactory();
      MaskATri* CreateFigureA();
      MaskBTri* CreateFigureB();
    };
    
    #endif
    //abstractfactory.cpp
    #include <iostream>
    #include "abstractfactory.hpp"
    
    using std::cout;
    using std::endl;
    
    FigureFactory::FigureFactory() {
    
    }
    
    FigureFactory::~FigureFactory() {
    
    }
    
    RoundFactory::RoundFactory() {
      cout<<"Init RoundFactory"<<endl;
    }
    
    RoundFactory::~RoundFactory() {
    
    }
    
    MaskARound* RoundFactory::CreateFigureA() {
      return new MaskARound();
    }
    
    MaskBRound* RoundFactory::CreateFigureB() {
      return new MaskBRound();
    }
    
    RecFactory::RecFactory() {
      cout<<"Init RecFactory"<<endl;
    }
    
    RecFactory::~RecFactory() {
    
    }
    
    MaskARec* RecFactory::CreateFigureA() {
      return new MaskARec();
    }
    
    TriFactory::TriFactory() {
      cout<<"Init TriFactory"<<endl;
    }
    
    TriFactory::~TriFactory() {
    
    }
    
    MaskATri* TriFactory::CreateFigureA() {
      return new MaskATri();
    }
    
    MaskBTri* TriFactory::CreateFigureB() {
      return new MaskBTri();
    }
    //main.cpp
    #include <iostream>
    #include <memory>
    #include "abstractfactory.hpp"
    
    using std::cout;
    using std::endl;
    using std::shared_ptr;
    
    
    int main() {
      shared_ptr<RoundFactory> rof(new RoundFactory());
      shared_ptr<MaskARound>    maro(rof->CreateFigureA());
      shared_ptr<MaskBRound>    mbro(rof->CreateFigureB());
    
      shared_ptr<RecFactory>   ref(new RecFactory());
      shared_ptr<MaskARec>    mare(ref->CreateFigureA());
      shared_ptr<MaskBRec>    mbre(ref->CreateFigureB());
    
      shared_ptr<TriFactory>  tif(new TriFactory());
      shared_ptr<MaskATri>    matr(tif->CreateFigureA());
      shared_ptr<MaskBTri>    mbtr(tif->CreateFigureB());
    }

    abstract factory适用于:

    1. 系统独立于产品创建,组合和表示时

    2. 系统具有多个产品系列

    3. 强调一系列相关产品的设计

    4. 使用产品类库,只想显示接口

    同时具有一些优缺点:

    1. 方便更换产品系列,只要更换factory对象即可。

    2. 有利于产品的一致性,每种factory只支持创建一个系列对象。

    3. 难以支持新新产品。继承的接口确定了可以被创建的对象集合,有新添加的类型时,必须扩展接口,涉及到所有子类的改变,一个更加灵活但不太安全的方法是参数化创建对象的函数。

    Abstract factory大部分情况下是用factory method模式实现的,但是也可以用上篇文章中的prototype模式实现。由于每个factory都负责同一系列对象创建,通常实现为singleton。

  • 相关阅读:
    c语言博客作业04--数组
    C博客作业03--函数
    c博客作业02--循环结构
    C博客作业01--顺序分支结构
    我的第一篇博客
    java--购物车程序的面向对象设计
    c博客作业05--指针
    C博客作业04--数组
    C博客作业03--函数
    C博客作业02--循环结构
  • 原文地址:https://www.cnblogs.com/coderkian/p/3965226.html
Copyright © 2011-2022 走看看