zoukankan      html  css  js  c++  java
  • c++ 设计模式8 (Factory Method 工厂方法)

    5. “对象创建”类模式

    通过“对象创建”类模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。

    5.1 工厂方法

    动机:

    在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。

    如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?

    代码示例:

    仍然考虑文件分割器案例,不考虑与创建对象无关的代码部分,暂时忽略内存管理,专注于工厂方法模式的应用。

    在实现代码1中,不同类型的文件分割器类(File,Pic,Video等)继承文件分割器抽象基类。

    在MainForm中,MainForm类依赖(编译时依赖)了具体的类BinarySpitter,违背了依赖倒置原则。此时即出现了动机中说明的创建对象过程中导致的紧耦合。

    采用工厂方法模式的解决方案见代码2,考虑过程如下:

    1.利用new方法创建的对象必须依赖于具体类,不可取;所以考虑创建一个类,利用其中方法的返回值作为创建对象的结果;

    2.然而单纯的返回一个具体类的对象仍然没有解决依赖倒置的问题,所以考虑将该类设计为一个抽象类,具体的返回由其子类来确定。

    3.依照上述思想创建工厂基类SplitterFactory(抽象类),具体工厂(BinarySplitterFactory等)返回具体的对象。

    4.MainForm使用过程中,声明一个工厂字段,在具体创建对象过程中采用统一的依赖于抽象的创建方法,即

    ISplitter * splitter= factory->CreateSplitter(); //相当于多态new

    而factory具体指向的对象类型由MainForm构造函数通过外界传入。

    注:可以从上述分析和代码中看出,工厂方法模式的使用,并不是为了消除变化(事实上变化不可能消除),而是将变化排除在MainForm之外(类比将变化赶到一个小范围),使其更加可控,从而使文件分割器的设计和使用满足面向对象设计原则,在应对变化时表现出优势。

    复制代码
     1 //FileSpiltter1.cpp
     2 class ISplitter{
     3 public:
     4     virtual void split()=0;
     5     virtual ~ISplitter(){}
     6 };
     7 
     8 class BinarySplitter : public ISplitter{
     9     
    10 };
    11 
    12 class TxtSplitter: public ISplitter{
    13     
    14 };
    15 
    16 class PictureSplitter: public ISplitter{
    17     
    18 };
    19 
    20 class VideoSplitter: public ISplitter{
    21     
    22 };
    23 
    24 //MaiForm1.cpp
    25 class MainForm : public Form
    26 {
    27     TextBox* txtFilePath;
    28     TextBox* txtFileNumber;
    29     ProgressBar* progressBar;
    30 
    31 public:
    32     void Button1_Click(){
    33 
    34 
    35         
    36         ISplitter * splitter=
    37             new BinarySplitter();//依赖具体类
    38         
    39         splitter->split();
    40 
    41     }
    42 };
    复制代码
    复制代码
     1 //ISpiltterFactory.cpp
     2 
     3 //抽象类
     4 class ISplitter{
     5 public:
     6     virtual void split()=0;
     7     virtual ~ISplitter(){}
     8 };
     9 
    10 
    11 //工厂基类
    12 class SplitterFactory{
    13 public:
    14     virtual ISplitter* CreateSplitter()=0;
    15     virtual ~SplitterFactory(){}
    16 };
    17 
    18 //FileSpiltter2.cpp
    19 
    20 //具体类
    21 class BinarySplitter : public ISplitter{
    22     
    23 };
    24 
    25 class TxtSplitter: public ISplitter{
    26     
    27 };
    28 
    29 class PictureSplitter: public ISplitter{
    30     
    31 };
    32 
    33 class VideoSplitter: public ISplitter{
    34     
    35 };
    36 
    37 //具体工厂
    38 class BinarySplitterFactory: public SplitterFactory{
    39 public:
    40     virtual ISplitter* CreateSplitter(){
    41         return new BinarySplitter();
    42     }
    43 };
    44 
    45 class TxtSplitterFactory: public SplitterFactory{
    46 public:
    47     virtual ISplitter* CreateSplitter(){
    48         return new TxtSplitter();
    49     }
    50 };
    51 
    52 class PictureSplitterFactory: public SplitterFactory{
    53 public:
    54     virtual ISplitter* CreateSplitter(){
    55         return new PictureSplitter();
    56     }
    57 };
    58 
    59 class VideoSplitterFactory: public SplitterFactory{
    60 public:
    61     virtual ISplitter* CreateSplitter(){
    62         return new VideoSplitter();
    63     }
    64 };
    65 
    66 //MainForm2.cpp
    67 class MainForm : public Form
    68 {
    69     SplitterFactory*  factory;//工厂
    70 
    71 public:
    72     
    73     MainForm(SplitterFactory*  factory){
    74         this->factory=factory;
    75     }
    76     
    77     void Button1_Click(){
    78 
    79         
    80         ISplitter * splitter=
    81             factory->CreateSplitter(); //多态new
    82         
    83         splitter->split();
    84 
    85     }
    86 };
    复制代码

    模式定义:

    定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使得一个类的实例化延迟(目的:解耦 ,手段:虚函数)到子类。

    类图:

    总结:

    Factory Method模式用于隔离类对象的使用者与具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。

    Factory Method模式通过面向对象的手法,将所有创建的具体对象延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。

    Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。

  • 相关阅读:
    Palindrome Linked List 解答
    Word Break II 解答
    Array vs Linked List
    Reverse Linked List II 解答
    Calculate Number Of Islands And Lakes 解答
    Sqrt(x) 解答
    Find Median from Data Stream 解答
    Majority Element II 解答
    Binary Search Tree DFS Template
    188. Best Time to Buy and Sell Stock IV
  • 原文地址:https://www.cnblogs.com/yechanglv/p/6931011.html
Copyright © 2011-2022 走看看