Adapter模式起始就是把完成同样一个功能但是接口不能兼容的类桥接在一起使之可以在一起工作,这个模式使得复用旧的接口称为可能。
实现:
1.采用继承原有接口类的方法
//需要被Adapt的类
class Target
{
public:
Target(){}
virtual ~Target(){}
virtual void Request()
{ cout<<"Target::Request"<<endl; }
};
//与被Adapt对象提供不兼容接口的类
class Adaptee
{
public:
Adaptee(){}
~Adaptee(){}
void SpecificRequest()
{ cout<<"Adaptee::SpecificRequest"<<endl; }
};
//进行Adapt的类,采用继承原有接口类的方式
class Adapter:public Target,private Adaptee
{
public:
Adapter(){}
~Adapter(){}
void Request()
{ this->SpecificRequest(); }
};
int main()
{
Target* adt = new Adapter();
adt->Request();
return 0;
}
2. 采用组合原有接口类的方法
//需要被Adapt的类
class Target
{
public:
Target(){}
virtual ~Target(){}
virtual void Request()
{ cout<<"Target::Request"<<endl; }
};
//与被Adapt对象提供不兼容接口的类
class Adaptee
{
public:
Adaptee(){}
~Adaptee(){}
void SpecificRequest()
{ cout<<"Adaptee::SpecificRequest"<<endl; }
};
//进行Adapt的类,采用聚合原有接口类的方式
class Adapter:public Target
{
public:
Adapter(Adaptee* ade)
{ this->_ade = ade; }
~Adapter(){}
void Request()
{ _ade->SpecificRequest(); }
private:
Adaptee* _ade;
};
将抽象部分与实现部分分离,使他们都可以独立的变化
2)Implementor 实现类的抽象基类,定义了实现Abstraction的基本操作,而它的派生类实现这些接口
Implementor::OperationImpl 实定义了为实现Abstraction需要的基本操作,由Implementor的派生类实现之,而在Abstraction::Operation函数中根据不同的指针多态调用这个函数
bridge模式用于将表示和实现解耦,两者可以独立的变化。在Abstraction类中维护一个Implementor类指针,需要采用不同的方式的时候只需要传入不同的Implementor派生类就可以了。
而在使用的时候, 都把对这个类的使用封装在一个函数中, 在 Bridge 中是封装在 Director::Construct函数中, 因为装配不同部分的过程是一致的,而在 Bridge 模式中则是封装在 Abstraction::Operation 函数中,在这个函数中调用对应的 Implementor::OperationImp 函数.
就两个模式而言,Builder 封装了不同的生成组成部分的方式, 而 Bridge封装了不同的实现方式.
将对象组合成树形结构以表示“部分-整体”的层次结构,Composite使得用户对单个对象和组合对象的使用具有一致性。
Component: 为组合中的对象声明接口,声明了类共有接口的缺省行为(如这里的Add,Remove,GetChild函数),声明一个接口函数可以访问Component的子组件
4)Component::GetChild 获得子组件的指针
Component模式为解决组件之间的递归组合提供了解决的方法,它主要分为两个派生类,其中的Leaf是叶子节点,也就是不含有子组件的节点,而Composite是含有子组件的节点。
实现:
//组合中的抽象基类
class Component
{
public:
Component(){}
virtual ~Component(){}
//纯虚函数,只提供接口,没有默认的实现
virtual void Operation()=0;
//虚函数,提供接口,有默认的实现就是什么都不做
virtual void Add(Component* pChild){}
virtual void Remove(Component* pChild){}
virtual Component* GetChild(int nIndex)
{ return NULL; }
};
//派生自Component,是其中的叶子组件的基类
class Leaf:public Component
{
public:
Leaf(){}
virtual ~Leaf(){}
virtual void Operation()
{ cout<<"Operation by Leaf"<<endl; }
};
//派生自Component,是其中含有子间的组件的基类
class Composite:public Component
{
public:
Composite(){}
virtual ~Composite()
{
list<Component*>::iterator iter1,iter2,temp;
for(iter1=m_ListOfComponent.begin(),iter2=m_ListOfComponent.end();iter1!=iter2;)
{
temp = iter1;
++iter1;
delete(*temp);
}
}
virtual void Operation()
{
cout<<"Operation by Conposite"<<endl;
list<Component*>::iterator iter1,iter2;
for(iter1=m_ListOfComponent.begin(),iter2=m_ListOfComponent.end();
iter1!=iter2;++iter1)
(*iter1)->Operation();
}
virtual void Add(Component* pChild)
{ m_ListOfComponent.push_back(pChild);}
virtual void Remove(Component* pChild)
{
list<Component*>::iterator iter;
iter = find(m_ListOfComponent.begin(),m_ListOfComponent.end(),pChild);
if(m_ListOfComponent.end()!=iter)
{ m_ListOfComponent.erase(iter); }
}
virtual Component* GetChild(int nIndex)
{
if(nIndex<=0||nIndex>m_ListOfComponent.size())
return NULL;
list<Component*>::iterator iter1,iter2;
int i;
for(i=1,iter1=m_ListOfComponent.begin(),iter2=m_ListOfComponent.end();
iter1!=iter2;++iter1,++i)
{
if(i==nIndex)
break;
}
return *iter1;
}
private:
//采用list容器去保存子组件
list<Component*> m_ListOfComponent;
};
int main()
{
Leaf* pLeaf1 = new Leaf();
Leaf* pLeaf2 = new Leaf();
Composite* pComposite = new Composite;
pComposite->Add(pLeaf1);
pComposite->Add(pLeaf2);
pComposite->Operation();
pComposite->GetChild(2)->Operation();
delete pComposite;
return 0;
}
动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更加灵活。
2)Decorator 维持一个指向Component的指针,并且有一个和Component一致的接口函数
Component::Operation 这个接口函数由Component声明,因此Component的派生类都需要实现,可以在这个接口函数的基础上给它动态添加职责。
首先初始化一个ConcreteComponent类的对象(被装饰者),采用这个对象去生成一个Decorator对象,之后对Operation函数的调用则是对这个Decorator对象成员函数的多态调用。这里的实现要点是Decorator类和ConcreteComponent类都继承自Component,二者的接口函数是一样的;其次,Decorator维护了一个指向Component的指针,从而可以实现对Component::Operation函数的动态调用。
实现:
//抽象基类,定义一个对象接口,可以为这个接口动态的添加职责.
class Component
{
public:
Component(){}
virtual ~Component(){}
//纯虚函数,由派生类实现
virtual void Operation()=0;
};
//抽象基类,维护一个指向Component对象的指针
class Decorator:public Component
{
public:
Decorator(Component* com)
{ this->_com = com; }
virtual ~Decorator()
{ delete _com; }
void Operation(){}
protected:
Component* _com;
};
//派生自Component,在这里表示需要给它动态添加职责的类
class ConcreteComponent:public Component
{
public:
ConcreteComponent(){}
~ConcreteComponent(){}
void Operation()
{
cout<<"ConcreteComponent operator.."<<endl;
}
};
//派生自Decorator,这里代表为ConcreateComponent动态添加职责的类
class ConcreteDecorator:public Decorator
{
public:
ConcreteDecorator(Component* com):Decorator(com){}
virtual ~ConcreteDecorator(){}
virtual void Operation()
{
_com->Operation();
this->AddedBehavior();
}
void AddedBehavior()
{ cout<<"ConcreteDecorator::AddedBehavior..."<<endl; }
};
int main(){
//初始化一个 Component 对象
Component* com = new ConcreteComponent();
//采用这个Component对象去初始化一个Decorator对象,
//这样就可以为这个Component对象动态添加职责
Decorator* dec = new ConcreteDecorator(com);
dec->Operation();
delete dec;
return 0;
}
为其他对象提供一种代理以控制对这个对象的访问
1)Subject 定义了Proxy和RealSubject的公有接口,这样就可以在任何需要用到RealSubject的地方都使用Proxy了
Proxy起始是基于这样一种经常被使用的技术——某个对象直到它真正被使用到的时候才被初始化,在没有使用到的时候就暂时用Proxy作一个占位符。这个模式实现的要点是Proxy和RealSubject都继承自Subject,这样保证了两个的接口是一致的。
实现:
//定义了 Proxy 和 RealSubject 的公有接口,
//这样就可以在任何需要使用到RealSubject的地方都使用Proxy
class Subject
{
public:
Subject(){}
virtual ~Subject(){}
virtual void Request()=0;
};
//真正使用的实体
class RealSubject:public Subject
{
public:
RealSubject()
{
cout<<"construction of RealSubject"<<endl;
}
virtual ~RealSubject(){}
virtual void Request()
{
cout<<"Request by RealSubject"<<endl;
}
};
//代理类,含有一个指向RealSubject对象的指针
class Proxy:public Subject
{
public:
Proxy():m_pRealSubject(NULL)
{ cout<<"Construction a Proxy"<<endl; }
virtual ~Proxy()
{
delete m_pRealSubject;
m_pRealSubject = NULL;
}
virtual void Request()
{
//需要使用Real Subject的时候才去初始化
if(NULL==m_pRealSubject)
{
cout<<"Realquest by Proxy"<<endl;
m_pRealSubject = new RealSubject();
}
m_pRealSubject->Request();
}
private:
RealSubject* m_pRealSubject;
};
int main()
{
Subject* pProxy = new Proxy();
pProxy->Request();
delete pProxy;
return 0;
}
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
Facade模式对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便;实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件往往是紧耦合的,松耦合关系使得子系统的组件变化不会影响到它的客户
运用共享技术有效的支持大量细粒度对象。
FlyweightFactory 创建并管理flyweight对象。确保合理的共享flyweight,当用户请求一个flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
比如文档中有许多个字符,但这些字符都是属于[A-Za-z]的范围之内,则将[A-Za-z]范围内的字符(公共部分)构造对象,存放在共享池中,文档中的各个字符共享相对应的共享对象池中的对象。