承接上一篇博客设计模式-02-创建型模式详解,本篇讨论结构型模式的相关内容
##一.适配器模式
双方都不适合修改的时候,可以考虑使用适配器模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WsJyFyHS-1574489903543)(https://img-blog.csdn.net/20180228232653548?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZWFnbGV1bml2ZXJzaXR5ZXll/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]
####代码举例:
//例一
#include <iostream>
using namespace std;
class Target
{
public:
virtual void Request()
{
cout<<"普通的请求"<<endl;
}
};
class Adaptee
{
public:
void SpecificalRequest()
{
cout<<"特殊请求"<<endl;
}
};
class Adapter :public Target
{
private:
Adaptee* ada;
public:
virtual void Request()
{
ada->SpecificalRequest();
Target::Request();
}
Adapter()
{
ada=new Adaptee();
}
~Adapter()
{
delete ada;
}
};
//客户端:
int main()
{
Adapter * ada=new Adapter();
ada->Request();
delete ada;
return 0;
}
//例二
#include <iostream>
#include <string>
using namespace std;
class Player
{
protected:
string name;
public:
Player(string strName) { name = strName; }
virtual void Attack()=0;
virtual void Defense()=0;
};
class Forwards : public Player
{
public:
Forwards(string strName):Player(strName){}
public:
virtual void Attack()
{
cout<<name<<"前锋进攻"<<endl;
}
virtual void Defense()
{
cout<<name<<"前锋防守"<<endl;
}
};
class Center : public Player
{
public:
Center(string strName):Player(strName){}
public:
virtual void Attack()
{
cout<<name<<"中场进攻"<<endl;
}
virtual void Defense()
{
cout<<name<<"中场防守"<<endl;
}
};
//为中场翻译
class TransLater: public Player
{
private:
Center *player;
public:
TransLater(string strName):Player(strName)
{
player = new Center(strName);
}
virtual void Attack()
{
player->Attack();
}
virtual void Defense()
{
player->Defense();
}
};
//客户端
int main()
{
Player *p=new TransLater("小李");
p->Attack();
return 0;
}
##二.桥接模式
将抽象部分与实现部分分离,使它们可以独立变化。
这里说的意思不是让抽象基类与具体类分离,而是现实系统可能有多角度分类,每一种分类都有可能变化,那么把这种多角度分离出来让它们独立变化,减少它们之间的耦合性,即如果继承不能实现“开放-封闭原则”的话,就应该考虑用桥接模式。
####代码举例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//手机软件
class HandsetSoft
{
public:
virtual void Run()=0;
};
//游戏软件
class HandsetGame : public HandsetSoft
{
public:
virtual void Run()
{
cout<<"运行手机游戏"<<endl;
}
};
//通讯录软件
class HandSetAddressList : public HandsetSoft
{
public:
virtual void Run()
{
cout<<"手机通讯录"<<endl;
}
};
//手机品牌
class HandsetBrand
{
protected:
HandsetSoft* m_soft;
public:
void SetHandsetSoft(HandsetSoft* temp)
{
m_soft = temp;
}
virtual void Run()=0;
};
//M品牌
class HandsetBrandM : public HandsetBrand
{
public:
virtual void Run()
{
m_soft->Run();
}
};
//N品牌
class HandsetBrandN : public HandsetBrand
{
public:
virtual void Run()
{
m_soft->Run();
}
};
//客户端
int main()
{
HandsetBrand *brand;
brand = new HandsetBrandM();
brand->SetHandsetSoft(new HandsetGame());
brand->Run();
brand->SetHandsetSoft(new HandSetAddressList());
brand->Run();
return 0;
}
##三.组合模式
整体和部分可以被一致对待(如WORD中复制一个文字、一段文字、一篇文章都是一样的操作)
####代码举例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Component
{
public:
string m_strName;
Component(string strName)
{
m_strName = strName;
}
virtual void Add(Component* com)=0;
virtual void Display(int nDepth)=0;
};
class Leaf : public Component
{
public:
Leaf(string strName): Component(strName){}
virtual void Add(Component* com)
{
cout<<"leaf can't add"<<endl;
}
virtual void Display(int nDepth)
{
string strtemp;
for(int i=0; i < nDepth; i++)
{
strtemp+="-";
}
strtemp += m_strName;
cout<<strtemp<<endl;
}
};
class Composite : public Component
{
private:
vector<Component*> m_component;
public:
Composite(string strName) : Component(strName){}
virtual void Add(Component* com)
{
m_component.push_back(com);
}
virtual void Display(int nDepth)
{
string strtemp;
for(int i=0; i < nDepth; i++)
{
strtemp+="-";
}
strtemp += m_strName;
cout<<strtemp<<endl;
vector<Component*>::iterator p=m_component.begin();
while (p!=m_component.end())
{
(*p)->Display(nDepth+2);
p++;
}
}
};
//客户端
#include "Model.h"
int main()
{
Composite* p=new Composite("小王");
p->Add(new Leaf("小李"));
p->Add(new Leaf("小赵"));
Composite* p1 = new Composite("小小五");
p1->Add(new Leaf("大三"));
p->Add(p1);
p->Display(1);
return 0;
}
##四.装饰器模式
动态地给一个对象添加一些额外的职责(不重要的功能,只是偶然一次要执行),就增加功能来说,装饰模式比生成子类更为灵活。建造过程不稳定,按正确的顺序串联起来进行控制。
当你向旧的类中添加新代码时,一般是为了添加核心职责或主要行为。而当需要加入的仅仅是一些特定情况下才会执行的特定的功能时(简单点就是不是核心应用的功能),就会增加类的复杂度。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。
####代码举例:
#include <string>
#include <iostream>
using namespace std;
//人
class Person
{
private:
string m_strName;
public:
Person(string strName)
{
m_strName=strName;
}
Person(){}
virtual void Show()
{
cout<<"装扮的是:"<<m_strName<<endl;
}
};
//装饰类
class Finery :public Person
{
protected:
Person* m_component;
public:
void Decorate(Person* component)
{
m_component=component;
}
virtual void Show()
{
m_component->Show();
}
};
//T恤
class TShirts: public Finery
{
public:
virtual void Show()
{
cout<<"T Shirts"<<endl;
m_component->Show();
}
};
//裤子
class BigTrouser :public Finery
{
public:
virtual void Show()
{
cout<<" Big Trouser"<<endl;
m_component->Show();
}
};
//客户端
int main()
{
Person *p=new Person("小李");
BigTrouser *bt=new BigTrouser();
TShirts *ts=new TShirts();
bt->Decorate(p);
ts->Decorate(bt);
ts->Show();
return 0;
}
##五.外观模式
为子系统的一组接口提供一个一致的界面。使用户使用起来更加方便。
####代码举例:
#include<iostream>
#include <string>
using namespace std;
class SubSysOne
{
public:
void MethodOne()
{
cout<<"方法一"<<endl;
}
};
class SubSysTwo
{
public:
void MethodTwo()
{
cout<<"方法二"<<endl;
}
};
class SubSysThree
{
public:
void MethodThree()
{
cout<<"方法三"<<endl;
}
};
//外观类
class Facade
{
private:
SubSysOne* sub1;
SubSysTwo* sub2;
SubSysThree* sub3;
public:
Facade()
{
sub1 = new SubSysOne();
sub2 = new SubSysTwo();
sub3 = new SubSysThree();
}
~Facade()
{
delete sub1;
delete sub2;
delete sub3;
}
void FacadeMethod()
{
sub1->MethodOne();
sub2->MethodTwo();
sub3->MethodThree();
}
};
//客户端
int main()
{
Facade* test = new Facade();
test->FacadeMethod();
return 0;
}
##六.享元模式
运用共享技术有效地支持大量细粒度的对象(对于C++来说就是共用一个内存块啦,对象指针指向同一个地方)。
如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销就应该考虑使用。
还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用较少的共享对象取代多组对象,此时可以考虑使用享元。
####代码举例:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//抽象的网站
class WebSite
{
public:
virtual void Use()=0;
};
//具体的共享网站
class ConcreteWebSite : public WebSite
{
private:
string name;
public:
ConcreteWebSite(string strName)
{
name = strName;
}
virtual void Use()
{
cout<<"网站分类:"<<name<<endl;
}
};
//不共享的网站
class UnShareWebSite : public WebSite
{
private:
string name;
public:
UnShareWebSite(string strName)
{
name = strName;
}
virtual void Use()
{
cout<<"不共享的网站:"<<name<<endl;
}
};
//网站工厂类,用于存放共享的WebSite对象
class WebFactory
{
private:
vector<WebSite*> websites;
public:
WebSite* GetWeb()
{
vector<WebSite*>::iterator p = websites.begin();
return *p;
}
WebFactory()
{
websites.push_back(new ConcreteWebSite("测试"));
}
};
//客户端
int main()
{
WebFactory* f= new WebFactory();
WebSite* ws= f->GetWeb();
ws->Use();
WebSite* ws2 = f->GetWeb();
ws2->Use();
//不共享的类
WebSite* ws3 = new UnShareWebSite("测试");
ws3->Use();
return 0;
}
##七.代理模式
远程代理:可以隐藏一个对象在不同地址空间的事实
虚拟代理:通过代理来存放需要很长时间实例化的对象
安全代理:用来控制真实对象的访问权限
智能引用:当调用真实对象时,代理处理另外一些事
####代码举例:
#include <string>
#include <iostream>
using namespace std;
//定义接口
class Interface
{
public:
virtual void Request()=0;
};
//真实类
class RealClass : public Interface
{
public:
virtual void Request()
{
cout<<"真实的请求"<<endl;
}
};
//代理类
class ProxyClass : public Interface
{
private:
RealClass* m_realClass;
public:
virtual void Request()
{
m_realClass= new RealClass();
m_realClass->Request();
delete m_realClass;
}
};
客户端:
int main()
{
ProxyClass* test=new ProxyClass();
test->Request();
return 0;
}