1、组合实体模式(Composite)
介绍
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性
举个例子,比如文件夹和文件的关系。一个文件夹里可能还有其他文件夹和文件,文件夹和文件都要提供一些共同的功能,比如查看大小和属性。这时,文件夹就属于组合类,文件属于叶子类。
角色
- 一个抽象的内容类,提供组合和叶子一致使用的接口
- 叶子类,继承内容类
- 组合类,继承内容类,拥有一个内容类的集合的容器,这个容器可能有叶子或集合。
简单来说就是同样的对象,可能是单个的实例,也可能是实例的组合,用这种方法来使他们使用起来具有一致性。
代码实现
#include<iostream>
#include<vector>
using namespace std;
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;
}
};
class Leaf:public Component{
public:
Leaf(){}
virtual ~Leaf(){}
virtual void Operation(){
cout<<"Operation by Leaf"<<endl;
}
};
class Composite:public Component {
public:
Composite(){}
virtual ~Composite(){
for(auto p:m_ListOfComponents){
delete p;
}
}
virtual void Operation(){
cout<<"Operation by Composite"<<endl;
}
virtual void Add(Component *pChild){
m_ListOfComponents.push_back(pChild);
}
virtual void Remove(Component* pChild){
for(int i=0;i<m_ListOfComponents.size();i++){
if(m_ListOfComponents[i]==pChild){
m_ListOfComponents.erase(m_ListOfComponents.begin()+i);
}
}
}
virtual Component *GetChild(int nIndex){
if(nIndex<=0||nIndex>=m_ListOfComponents.size()){
return NULL;
}
return m_ListOfComponents[nIndex];
}
private:
vector <Component*> m_ListOfComponents;
};
int main(){
Leaf* pLeaf1=new Leaf();
Leaf* pLeaf2=new Leaf();
Composite* pComposite=new Composite();
pComposite->Add(pLeaf1);
pComposite->Add(pLeaf2);
pComposite->Operation();
pComposite->GetChild(1)->Operation();
delete pComposite;
}
2、享元模式
简介
为了避免程序中使用了过多重复的对象而造成过大的内存开销,让重复的对象共享一个对象。将对象的状态分为外部状态和内部状态,可以共享的状态作为内部状态存储在对象中。
角色
- 一个享元工厂类,用于创建享元类,在使用它创建享元对象时,先检查是否已经创建过相同的对象,如有则返回,如没有则创建一个新的对象。
- 抽象的享元类,提供统一的接口
- 享元类(可共享类),继承抽象的享元类
- 非享元类(不可共享类),继承抽象的享元类
代码实现
#include <string>
#include<list>
#include<iostream>
using namespace std;
class Flyweight{
public:
virtual ~Flyweight(){}
string GetIntrinsicState(){
return m_state;
}
virtual void Operation(string& ExtrinsicState)=0;
protected:
Flyweight(const string& state):m_state(state){}
private:
string m_state;
} ;
class ConcreateFlyweight:public Flyweight{
public:
ConcreateFlyweight(const string& state):Flyweight(state){}
virtual ~ConcreateFlyweight(){}
virtual void Operation(string& ExtrinsicState){
cout<<GetIntrinsicState()<<" and "<<ExtrinsicState<<endl;
}
};
class FlyweightFactory{
public:
FlyweightFactory(){}
~FlyweightFactory(){
for(auto it1=m_list.begin(),tem=m_list.begin(), it2=m_list.end();it1!=it2;){
tem=it1;
++it1;
delete(*tem);
}
m_list.clear();
}
Flyweight* GetFlyweight(const string& key){
for(auto it1=m_list.begin(), it2=m_list.end();it1!=it2;++it1){
if((*it1)->GetIntrinsicState()==key){
cout<<"The Flyweight :"<<key<<"already exist"<<endl;
return (*it1);
}
}
cout<<"creating a new Flyweight: "<<key<<endl;
Flyweight* fw=new ConcreateFlyweight(key);
m_list.push_back(fw);
return fw;
}
private:
list<Flyweight*> m_list;
};
int main(){
FlyweightFactory ff;
auto fw1=ff.GetFlyweight("hello");
string str="okok";
fw1->Operation(str);
auto fw2=ff.GetFlyweight("world");
auto fw3=ff.GetFlyweight("world");
fw3->Operation(str);
return 0;
}
3.外观模式
简介
有一些接口,分散在不同的独立模块中,客户不需要知道它们具体都是在哪里实现的,需要将这些接口组合在一起。
比如说KTV中有电视、音响、灯光等设备,都有各自的开关,就可以实现一个总开关的功能。
代码实现
#include<iostream>
using namespace std;
class TV{
public:
void on(){
cout<<"TV on"<<endl;
}
void off(){
cout<<"TV off"<<endl;
}
};
class Light{
public:
void on(){
cout<<"Light on"<<endl;
}
void off(){
cout<<"Light off"<<endl;
}
};
class AU{
public:
void on(){
cout<<"AU on"<<endl;
}
void off(){
cout<<"AU off"<<endl;
}
};
class KTV{
public:
KTV(){
pTV=new TV;
pLT=new Light;
pAU=new AU;
}
void on(){
pTV->on();
pLT->on();
pAU->on();
}
void off(){
pTV->off();
pLT->off();
pAU->off();
}
~KTV(){
delete pTV;
delete pAU;
delete pLT;
}
private:
TV* pTV;
Light* pLT;
AU* pAU;
};
int main(){
KTV* k=new KTV;
k->on();
}
3、代理模式
简介
指为其他对象提供一种代理,以控制对这个对象的访问。 代理对象在客服端和目标对象之间起到中介作用。
比如一个操作系统,提供运行的接口,我可以实现一个用户登录功能,登录成功之后再运行,这就是一个代理模式。
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
代码实现
#include<iostream>
using namespace std;
class AbstractCommonInterface{
public:
virtual void run()=0;
};
class MySystem:public AbstractCommonInterface{
public:
virtual void run(){
cout<<"Operation run..."<<endl;
}
};
class MySystemProxy:public AbstractCommonInterface{
public:
MySystemProxy(string name,string pass):name(name),pass(pass){
psys=new MySystem;
}
bool check(){
if(name=="admin"&&pass=="admin"){
return true;
}
return false;
}
virtual void run(){
if(check()==true){
cout<<"check pass"<<endl;
psys->run();
}else{
cout<<"wrong pass"<<endl;
}
}
~MySystemProxy(){
if(psys!=NULL){
delete psys;
}
}
private:
string name;
string pass;
MySystem *psys;
};
int main(){
MySystemProxy* pro=new MySystemProxy("admin","admin");
pro->run();
return 0;
}