对象创建模式
- 通过对象创建模式绕开NEW,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
工厂模式
- 为了提高内聚和松耦合,我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。
- 很容易出现一个问题N多的子类继承自父类抽象基类,我们不得不在每次要用到子类的地方就编写诸如new的代码
- 工厂模式两个重要功能:1)定义创建对象的接口 2)使得具体化类的工作延迟到了子类中
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
};
//宸ュ巶鍩虹被
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter()=0;
virtual ~SplitterFactory(){}
};
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 MainForm : public Form
{
SplitterFactory* factory;//工厂
public:
MainForm(SplitterFactory* factory){ //利用传入参数来决定用什么文件分割器,这就把"变化"的范围限制在MainForm之外了
this->factory=factory;
}
void Button1_Click(){
ISplitter * splitter=
factory->CreateSplitter(); //创造性的做出了一个多态的new
splitter->split();
}
};
- Factory 模式在实际开发中应用非常广泛,面向对象的系统经常面临着对象创建问题:要创建的类实在是太多了。而 Factory 提供的创建对象的接口封装(第一个功能), 以及其将类的实例化推迟到子类(第二个功能) 都部分地解决了实际问题。 一个简单的例子就是笔者开开发 VisualCMCS 系统的语义分析过程中, 由于要为文法中的每个非终结符构造一个类处理,因此这个过程中对象的创建非常多,采用 Factory 模式后系统可读性性和维护都变得elegant 许多
抽象模式
- AbstractFactory 模式就是用来解决这类问题的:要创建一组相关或者相互依赖的对象。
- AbstractFactory 模式关键就是将这一组对象的创建封装到一个用于创建对象的类( ConcreteFactory)中, 维护这样一个创建类总比维护 n 多相关对象的创建过程要简单的多。
//数据库访问有关的基类。面向接口编程
class IDBConnection{
};
class IDBConnectionFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
};
class IDBCommand{
};
class IDBCommandFactory{
public:
virtual IDBCommand* CreateDBCommand()=0;
};
class IDataReader{
};
class IDataReaderFactory{
public:
virtual IDataReader* CreateDataReader()=0;
};
//支持SQL Server
class SqlConnection: public IDBConnection{
};
class SqlConnectionFactory:public IDBConnectionFactory{
};
class SqlCommand: public IDBCommand{
};
class SqlCommandFactory:public IDBCommandFactory{
};
class SqlDataReader: public IDataReader{
};
class SqlDataReaderFactory:public IDataReaderFactory{
};
//支持Oracle
class OracleConnection: public IDBConnection{
};
class OracleCommand: public IDBCommand{
};
class OracleDataReader: public IDataReader{
};
class EmployeeDAO{
IDBConnectionFactory* dbConnectionFactory;
IDBCommandFactory* dbCommandFactory;
IDataReaderFactory* dataReaderFactory;
public:
vector<EmployeeDO> GetEmployees(){
IDBConnection* connection =
dbConnectionFactory->CreateDBConnection();
connection->ConnectionString("...");
IDBCommand* command =
dbCommandFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection); //关联性
IDBDataReader* reader = command->ExecuteReader(); //关联性
while (reader->Read()){
}
}
};
- AbstractFactory 模式是为创建一组( 有多类) 相关或依赖的对象提供创建接口, 而 Factory 模式正如我在相应的文档中分析的是为一类对象提供创建接口或延迟对象的创建到子类中实现
- AbstractFactory 模式通常都是使用 Factory 模式实现
接口隔离模式
原型模式
- 工厂模式 和原型模式解决的问题都是一样的,绕开new。不同点:原型模式解决更复杂的中间方法,工厂模式解决几步就可以解决的问题
-
使用一个原型实例指定创建对象的种类,通过复制这个原型创建对象。
-
仍然考虑文件分割器,我们类比工厂方法。原型模式是一种特殊的创建,通过克隆(复制构造)来进行创建。
class MainForm : public Form { ISplitter* prototype;// public: MainForm(ISplitter* prototype){ this->prototype=prototype; //让原型对象指向传过来的原型 } void Button1_Click(){ ISplitter * splitter= prototype->clone(); //克隆原型 splitter->split(); } };
建构器
(不常用)
- 将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示
门面模式
- 为子系统的一组接口提供一个一致的界面,门面模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用)
代理模式
- 为其他对象提供一种代理以控制对这个对象的访问
class ISubject{
public:
virtual void process();
};
//Proxy的设计
class SubjectProxy: public ISubject{
public:
virtual void process(){
//对RealSubject的一种间接访问,可以添加一些操作
//....
}
};
class ClientApp{
ISubject* subject;
public:
ClientApp(){
subject=new SubjectProxy();
}
void DoTask(){
//...
subject->process();
//....
}
};
适配器
- 将一个类的接口转换成客户希望的另一个接口。使原本不兼容的可以一起工作
//目标接口(新接口)
class ITarget{
public:
virtual void process()=0;
};
//遗留接口(老接口)
class IAdaptee{
public:
virtual void foo(int data)=0;
virtual int bar()=0;
};
//遗留类型
class OldClass: public IAdaptee{
//....
};
//对象适配器
class Adapter: public ITarget{ //继承
protected:
IAdaptee* pAdaptee;//组合
public:
Adapter(IAdaptee* pAdaptee){
this->pAdaptee=pAdaptee;
}
virtual void process(){
int data=pAdaptee->bar();
pAdaptee->foo(data);
}
};
//类适配器
class Adapter: public ITarget,
protected OldClass{ //多继承
}
int main(){
IAdaptee* pAdaptee=new OldClass();
ITarget* pTarget=new Adapter(pAdaptee);
pTarget->process();
}
class stack{
deqeue container;
};
class queue{
deqeue container;
};
中介者
- 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立改变他们之间的交互
网友评论