设计模式-03-结构型模式详解

承接上一篇博客设计模式-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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值