工厂模式
动机
在软件系统中,经常面临着创建对象的工作;由于需求的变化, 需要创建的对象的具体类型经常变化。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一 种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
解决方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类。 工厂模式使得一个类的实例化延迟(目的:解耦, 手段:虚函数)到子类。我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式。
文件分割例子
class ISplitter
{
public:
virtual void split() = 0;
virtual ~ISplitter(){}
};
class BinarySplitter: public ISplitter
{
void split()
{
cout << "BinarySplitter" << endl;
}
};
class TxtSplitter: public ISplitter
{
void split()
{
cout << "TxtSplitter" << endl;
}
};
class PictureSplitter: public ISplitter
{
void split()
{
cout << "PictureSplitter" << endl;
}
};
class VideoSplitter: public ISplitter
{
void split()
{
cout << "VideoSplitter" << endl;
}
};
class MainForm: public Form
{
public:
void Button1_Click()
{
ISplitter *splitter = new BinarySplitter(); // 依赖具体类
splitter->split();
}
};
例子中创建需要new具体类。
简单工厂模式例子
该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。
class ISplitter
{
public:
virtual void split() = 0;
virtual ~ISplitter(){}
};
class BinarySplitter: public ISplitter
{
void split()
{
cout << "BinarySplitter" << endl;
}
};
class TxtSplitter: public ISplitter
{
void split()
{
cout << "TxtSplitter" << endl;
}
};
class PictureSplitter: public ISplitter
{
void split()
{
cout << "PictureSplitter" << endl;
}
};
class VideoSplitter: public ISplitter
{
void split()
{
cout << "VideoSplitter" << endl;
}
};
// 简单工厂
class SplitterFactory
{
public:
ISplitter* CreateSplitter(string type)
{
if (type == "Binary")
{
return new BinarySplitter();
}
else if (type == "Txt")
{
return new TxtSplitter();
}
else if (type == "Picture")
{
return new PictureSplitter();
}
else if (type == "Video")
{
return new VideoSplitter();
}
return nullptr;
}
virtual ~SplitterFactory(){}
};
class MainForm: public Form
{
SplitterFactory splitterFactory;
public:
void Button1_Click()
{
ISplitter *splitter = splitterFactory.CreateSplitter("Binary"); // 封装了创建逻辑
splitter->split();
}
};
工厂方法模式例子
工厂方法模式将生成具体产品的任务分发给具体的产品工厂。
// 抽象类
class ISplitter
{
public:
virtual void split() = 0;
virtual ~ISplitter(){}
};
// 工厂基类
class SplitterFactory
{
public:
virtual ISplitter* CreateSplitter() = 0;
virtual ~SplitterFactory(){}
};
// 具体类
class BinarySplitter: public ISplitter
{
void split()
{
cout << "BinarySplitter" << endl;
}
};
class TxtSplitter: public ISplitter
{
void split()
{
cout << "TxtSplitter" << endl;
}
};
class PictureSplitter: public ISplitter
{
void split()
{
cout << "PictureSplitter" << endl;
}
};
class VideoSplitter: public ISplitter
{
void split()
{
cout << "VideoSplitter" << endl;
}
};
// 具体工厂
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 MainForm: public Form
{
SplitterFactory *splitterFactory; // 工厂
public:
MainForm(SplitterFactory *splitterFactory)
{
this->splitterFactory = splitterFactory;
}
void Button1_Click()
{
ISplitter *splitter = splitterFactory->CreateSplitter(); // 多态new
splitter->split();
}
};
优缺点
优点: 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。