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模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。

  • 相关阅读:
    PHP面向对象编程入门
    PHP错误处理机制
    PHP数组深入
    PHP 表单
    多重背包之单调队列优化理论性总结
    二分查找理论性总结
    大连海事大学第十届程序设计竞赛 题解
    Codeforces Round #603 (Div. 2) E. Editor (线段树维护前缀和最值)
    Educational Codeforces Round 77 (Rated for Div. 2) E. Tournament (DP)
    Leetcode1256 加密数字(手动找规律)
  • 原文地址:https://www.cnblogs.com/yechanglv/p/6931011.html
Copyright © 2011-2022 走看看