设计模式:Factory Method

本文深入探讨了工厂方法模式,一种创建型设计模式,用于解决在软件系统中创建对象时的依赖问题。通过定义一个创建对象的接口,让子类决定实例化哪一个类,实现了对象创建的解耦。

工厂方法-Factory Method

动机-Motivation

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

例子

文件分割器

代码

class ISplitter{
public:
    virtual void split()=0;
    virtual ~ISplitter(){}
};

class BinarySplitter : public ISplitter{
    
};

class TxtSplitter: public ISplitter{
    
};

class PictureSplitter: public ISplitter{
    
};

class VideoSplitter: public ISplitter{
    
};


class MainForm : public Form
{
	TextBox* txtFilePath;
	TextBox* txtFileNumber;
	ProgressBar* progressBar;

public:
	void Button1_Click(){


        
		ISplitter * splitter=
            new BinarySplitter();//依赖具体类
        
        splitter->split();

	}
};




为了支持多种的文件分割方式,写出一个抽象基类ISplitter,提供分割接口。同时让各类格式下的分割如文本格式分割下文件分割、图片格式下的文件分割、视频格式下的文件分割等继承自ISplitter,实现不同的分割方式。
但在具体使用时,任然需要细节依赖(如new BinarySplitter()),依赖具体类,违背依赖倒置原则。
考虑重构代码,使用某种方法去返回一个对象,来避免对象创建时对细节的依赖。
创建一个SplitterFactory类,定义一个方法,返回类型为ISplitter,return 具体类(如new BinarySplitter())。
但此时的工厂类依赖具体实现,而MainForm依赖工厂,最后MainFrom仍然依赖于具体实现。
考虑改变工厂创建函数,使该函数成为一个pure Virtual函数,延迟需求至运行时。所以可以不必提供具体实现,避免编译时依赖。
MainForm需要使用工厂类指针(通常放在类内作数据成员,通过构造器赋值),通过该指针去创建类型。创建具体实现的工厂类去继承抽象工厂,去实现各类的创建函数,返回对应类型的对象。
每一个具体类,都有一个对应的具体工厂,去继承抽象工厂,来完成对象创建工作。
让MainForm依赖工厂基类,而不是依赖具体类,可以实现MainForm的独立编译。

版本2



//具体类
class BinarySplitter : public ISplitter{
    
};

class TxtSplitter: public ISplitter{
    
};

class PictureSplitter: public ISplitter{
    
};

class VideoSplitter: public ISplitter{
    
};

//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new BinarySplitter();
    }
};

class TxtSplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new TxtSplitter();
    }
};

class PictureSplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new PictureSplitter();
    }
};

class VideoSplitterFactory: public SplitterFactory{
public:
    virtual ISplitter* CreateSplitter(){
        return new VideoSplitter();
    }
};

//抽象类
class ISplitter{
public:
    virtual void split()=0;
    virtual ~ISplitter(){}
};


//工厂基类
class SplitterFactory{
public:
    virtual ISplitter* CreateSplitter()=0;
    virtual ~SplitterFactory(){}
};
class MainForm : public Form
{
    SplitterFactory*  factory;//工厂

public:
    
    MainForm(SplitterFactory*  factory){
        this->factory=factory;
    }
    
	void Button1_Click(){

        
		ISplitter * splitter=
            factory->CreateSplitter(); //多态new
        
        splitter->split();

	}
};

总结

定义一个用于创建对象的接口,让子类去实现如何创建对象。
让子类的对象的创建从编译时延迟至运行时,将紧耦合(需要具体类创建)变为松耦合(未来创建对象类)。
变化始终存在,只是做了隔离。
当新的需求发生时(另一种文件分割方式),MainForm的多态new不需要变动,继续让新的具体类继承ISplitter抽象类,并创建对应类的工厂继承工厂基类,实现创建对象方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值