在界面类中要分割一个文件,文件分割器负责从主界面中获取path和要分割的分数。

//分割器
class BinarySplitter
{
public:
    ...void split()
    {
        cout << "开始文件分割..." << endl;
    }
};
 1 //界面类
 2 class   MainForm
 3 {
 4   public:
 5       ...
 6       void button_click()
 7       {
 8            //传入文件路径和分割的份数
 9            FileSplitter *splitter = new FileSplitter(...);
10            //开始分割
11            splitter->split();
12       }
13 }

  面向接口编程告诉我们,一个对象的类型应该声明为抽象类,不应该是具体的类,如果声明的是具体类就说明不支持未来的变化(第9行)。所以要反过来判断是否有需求的变化。

  如果文件分割器除了对二进制文件进行分割,还要对文本文件、图片文件、视频文件进行分割(他们内部的算法不一样)

 1 //提起一个抽象基类
 2 class ISplitter
 3 {
 4 public:
 5     virtual void split() = 0;
 6     virtual ~ISplitter(){}
 7 
 8 };
 9 //二进制文件分割器
10 class BinarySplitter:public ISplitter
11 {
12 public:
13     
14     void split()
15     {
16         cout << "二进制文件分割方法" << endl;
17     }
18 
19 };
20 //文本文件分割器
21 class TxtSplitter:public BinarySplitter
22 {
23 public:
24     
25     void split()
26     {
27         cout << "文本文件分割方法" << endl;
28     }
29 
30 };
31 //图片文件分割器
32 class PictureSplitter:public BinarySplitter
33 {
34 public:
35     
36     void split()
37     {
38         cout << "图片文件分割方法" << endl;
39     }
40 
41 };
42 //视频文件分割器
43 class VideoSplitter:public BinarySplitter
44 {
45 public:
46     
47     void split()
48     {
49         cout << "视频文件分割方法" << endl;
50     }
51 
52 };

  根据依赖导致原则:依赖(编译时依赖)抽象(稳定)不应该依赖实现细节(不稳定),也是面向接口编程的思想,将界面类中第9行修改如下:

ISplitter *splitter = new BinarySplitter(...);

  splitter是一个抽象类型,但是new 后面是一个具体类型,所以这行代码依旧是一个细节依赖,不符合依赖倒置原则。这就是工厂方法模式需要解决的问题。需要绕开new,因为new带来的是细节依赖。也是面向接口编程的一个必然需求。

  怎么绕开new来创建一个对象?无论是在堆上还在栈上都需要依赖具体的类。

  可以通过一个方法来返回一个对象。

 //添加一个抽象工厂
class SplitterFactory 
{
public:
    virtual ISplitter * CreatSplitter() = 0;
    virtual ~SplitterFactory(){}
};

//每一种分割器对应一个具体工厂
class BinarySplitterFactory :public SplitterFactory
{
public:
    virtual ISplitter * CreatSplitter()
    {
        return new BinarySplitter;
    }
};
class TxtSplitterFactory :public SplitterFactory
{
public:
    virtual ISplitter * CreatSplitter()
    {
        return new TxtSplitter;
    }
};
class PictureSplitterFactory :public SplitterFactory
{
public:
    virtual ISplitter * CreatSplitter()
    {
        return new PictureSplitter;
    }
};
class VideoSplitterFactory :public SplitterFactory
{
public:
    virtual ISplitter * CreatSplitter()
    {
        return new VideoSplitter;
    }
};

  修改一下界面类

 //界面类
 class   MainForm
 {
   public:
       SpliiterFactory *m_factory;
       //从外界传入一个具体的工厂
       MainForm(SpliiterFactory *factory):m_factory(factory){}
       void button_click()
       {
          //通过工厂创建对象,绕开new,实现依赖抽象
           FileSplitter *splitter = factory->CreatSplitter(); //多态new
  
            splitter->split();
       }
          ...
 }

  最后在分析一下工厂方法的定义:定义一个用于创建对象的接口(SplitterFactory类中的虚函数CreatSplitter),让子类(具体的工厂)决定实例化哪一个类。目的是为了解耦,解new和具体类之间的耦合。

  结构图