C++设计模式系列之二结构型模式

1.Adapter模式


Adapter.hpp:

#ifndef _ADAPTER_HPP
#define _ADAPTER_HPP



//第三方库
namespace ThirdPartyNameSpace
{
	class ThirdPartyClass
	{
		public:
			ThirdPartyClass(){}
			~ThirdPartyClass(){}
			void ThirdPartyMethod(){}
	};
};

//我们内部定义好的接口
struct IMethod
{
	virtual void Method() = 0;
};

//内部实现的接口子类
class CustomMethod : public IMethod
{
	public:

		void Method(){}
};

//外部第三方适用我们配器实现接口统一
class ThirdPartyAdapter : public IMethod
{
	public:
		ThirdPartyAdapter( ThirdPartyNameSpace::ThirdPartyClass *p )
		{
			mp = p;
		}
		~ThirdPartyAdapter()
		{}

		void Method()
		{
			mp->ThirdPartyMethod();
		}
	private:

		ThirdPartyNameSpace::ThirdPartyClass *mp;
};

#endif


Main.cpp:


#include "Adapter.hpp"

作用:引用的第三方库方法根现有的接口不一致时,通过中间进行转换将接口保持一致( 记住这种思想即可,其实如何实现你可以自己定义 )
缺点:当接口函数很多时,中间层不得不每一个都去实现一次,哪怕非纯虚方法,到时候
中间层继承的接口暴露许多无用方法,这样很容易出错,感觉其实adapter是折中的方案
既然选择第三方库了,那么项目立项的时候就要考虑进来,合理定义接口,如果是后期加入,
第三方库一般都是独立的库,和现有接口关系不是太大,即便是有关系,也可以通过其他的方案来解决
Adapter模式的特殊性比较强( 个人观点,不要为了设计模式而设计模式 )
//
int main()
{
	//内部实现的方案1
	IMethod *p = new CustomMethod;

	p->Method();

	//外部第三方库实现的方案2
	ThirdPartyNameSpace::ThirdPartyClass *ptp = new ThirdPartyNameSpace::ThirdPartyClass;
	//给内部适配器
	IMethod *p2 = new ThirdPartyAdapter( ptp );

	//废了这么大劲只是为了接口一致( 强烈建议自己实现满足自己项目的解决方案,有这种思想即是设计模式,当然如果该例子满足最好 )
	p2->Method();

	delete p2;
	delete ptp;
	delete p;

	return 0;
}


2.Facade模式


Facade.hpp:


#ifndef _FACADE_HPP
#define _FACADE_HPP


//注意A,B,C,D 系统之间没有直接的关系
class ASystem
{
	public:

		ASystem(){}

		~ASystem(){}

		void DoSomething(){}
};

class BSystem
{
	public:

		BSystem(){}

		~BSystem(){}

		void DoSomething(){}
};

class CSystem
{
public:

	CSystem(){}

	~CSystem(){}

	void DoSomething(){}
};

class DSystem
{
public:

	DSystem(){}

	~DSystem(){}

	void DoSomething(){}
};


//测试ab系统模块
class TestAB
{
	public:

		TestAB()
		{
			mpa = new ASystem;
			mpb = new BSystem;
		}
		
		virtual ~TestAB()
		{
			delete mpa;
			delete mpb;
		}

		//外部只关心调用Test方法,A,B系统内部我们不关心,这里只做聚合功能模块
		void Test()
		{
			mpa->DoSomething();
			mpb->DoSomething();
		}

	private:

		ASystem *mpa;
		BSystem *mpb;
};

//测试cd系统模块
class TestCD
{
public:

	TestCD()
	{
		mpc = new CSystem;
		mpd = new DSystem;
	}

	virtual ~TestCD()
	{
		delete mpc;
		delete mpd;
	}

	void Test()
	{
		mpc->DoSomething();
		mpd->DoSomething();
	}

private:

	CSystem *mpc;
	DSystem *mpd;
};

#endif

Main.cpp:


#include "Facade.hpp"

//作用:将我们实现的各类对象系统,抽取出来并且封装聚合在一个类中完成特定的功能
//记住这种思想即可,将各个功能类封装在另一个类中,通过这个聚合类,完成某种高级调用

int main()
{
	//例如测试AB系统,我们将AB封装在TestAB用来测试A和B的调用情况外部只需要调用一个接口即可,不关心A,B的底层实现
	//那么TestAB就是A和B的聚合组合,我们称之为Facade模式
	TestAB *ptab = new TestAB;

	//理由同上
	TestCD *ptcd = new TestCD;

	ptab->Test();

	ptcd->Test();

	delete ptcd;

	delete ptab;

	return 0;
}


3.Proxy模式


Proxy.hpp:


#ifndef _PROXY_HPP
#define _PROXY_HPP
#include <string>

typedef char c8;
typedef const char* cc8p;

//网络代理为典型例子( 包括但不限于例子 )
class Proxy
{
public:

	Proxy(){}

	~Proxy(){}

	//请求代理
	void ProxyLogin(
		cc8p pUsr,
		cc8p pPwd,
		cc8p pProxyIP,
		int ProxyPort,
		cc8p pProxyUsr,
		cc8p pProxyPwd,
		cc8p pTargetIp,
		int TargetPort
		){}

	//代理服务器回传数据
	void OnProxyRecv( void *p ){}
};

class LoginUI
{
	public:
		LoginUI(){}
		~LoginUI(){}
		void OnClickedLoginBtn()
		{
			cc8p pUsr = "test001";
			cc8p pPwd = "123456";
			strcpy( mUsr, pUsr );
			strcpy( mPwd, pPwd );
		}
		c8 mUsr[ 16 ];
		c8 mPwd[ 16 ];
};



#endif

Main.cpp:


#include "Proxy.hpp"

//作用:特定的功能委托或者转交给其他对象完成,我们称之为proxy代理模式
//例如:(智能指针委托管理对象生命周期,智能锁委托管理锁对象的锁定和解锁,或者其他大部分异步调用的过程)

//下面模拟网络上最常用的网络代理
int main()
{
	//登陆用户接口UI
	LoginUI *pUsrInterface = new LoginUI;

	//模拟用户点击登陆,得到输入的账号和密码
	pUsrInterface->OnClickedLoginBtn();

	//OK本地网络太卡了我们通过代理服务器连接游戏登陆服
	Proxy *pProxy = new Proxy;

	pProxy->ProxyLogin(
		pUsrInterface->mUsr,				//用户名数据
		pUsrInterface->mPwd,				//用户密码
		"xxx.xxx.xxx.xxx",				//代理服务器地址
		8564,							//代理服务器端口
		"proxyUID",						//代理账号
		"proxyPwd",						//代理密码
		"xxx.xxx.xxx.xxx",				//目标服务器地址
		5876							//目标服务器端口
		);

	//剩下的就是等待代理服务器返回数据触发pProxy->OnProxyRecv方法
	
	delete pProxy;
	delete pUsrInterface;

	return 0;
}


4.Flyweight模式


Flyweight.hpp:


#ifndef _FLY_WEIGHT_HPP
#define _FLY_WEIGHT_HPP

#include <string>
#include <vector>

typedef std::string xc;

class FlyWeight
{
public:
	FlyWeight(){}
	~FlyWeight(){};
	xc mKey;
};

class FlyWeightMgr
{
public:
	FlyWeightMgr(){};
	virtual ~FlyWeightMgr()
	{
		for( size_t i = 0; i < mFlyWeights.size(); ++i )
		{
			delete mFlyWeights[i];
		}
		mFlyWeights.clear();
	};

	FlyWeight* GetFlyWeight( const xc &key )
	{
		for( size_t i = 0; i < mFlyWeights.size(); ++i )
		{
			if( mFlyWeights[i]->mKey == key )
			{
				return mFlyWeights[i];
			}
		}
		FlyWeight *p = new FlyWeight;
		p->mKey = key;
		mFlyWeights.push_back( p );
		return p;
	}

private:

	std::vector< FlyWeight* > mFlyWeights;
};

#endif

Main.cpp:


#include "FlayWeight.hpp"

//作用:共享实例,已存在就返回,不存在就新建,然后追加到缓冲池中等待被使用
//这种模式,我们应该经常使用,只是不知道叫什么名字而已
//一般这种模式,我们会对对象的创建和销毁内部进行管理

int main()
{
	//典型管理器
	FlyWeightMgr *pMgr = new FlyWeightMgr;

	//获取值为xfx的组件
	FlyWeight *p1 = pMgr->GetFlyWeight("xfx");
	FlyWeight *p2 = pMgr->GetFlyWeight("xfx");

	//这两个值必然相等为true
	bool b = p1 == p2;

	delete pMgr;
	return 0;
}

5.Bridge模式


Bridge.hpp:


#ifndef _BRIDGE_HPP
#define _BRIDGE_HPP
//移动
class Move
{
public:
	Move(){}
	virtual ~Move(){}
	virtual void move() = 0;
};

//地面单位移动
class LandMove : public Move
{
public:
	LandMove(){}
	~LandMove(){}
	void move(){}
};

//空中单位移动
class AirMove : public Move
{
public:
	AirMove(){}
	~AirMove(){}
	void move(){}
};

class Unit
{
public:
	Unit( Move *p )
	{
		mp = p;
	}
	virtual ~Unit(){}
	virtual void move()
	{
		mp->move();
	}
	//...其他方法
protected:
	Move *mp;

	//...其他属性
};


//scv 地面单位
class SCV : public Unit
{
public:
	SCV( Move *p )
		:Unit( p )
	{}
	~SCV(){}
};

//坦克 地面单位
class Tank : public Unit
{
public:
	Tank( Move *p )
		:Unit( p )
	{}
	virtual ~Tank(){}
};

//维京 空中单位
class Viking : public Unit
{
public:
	Viking( Move *p )
		:Unit( p )
	{}
	~Viking(){}
};

//渡鸦 空中单位
class Raven : public Unit
{
public:
	Raven( Move *p )
		:Unit( p )
	{}
	~Raven(){}
};

#endif

Main.cpp:


#include "Bridge.hpp"

//作用:将本来录属于对象的行为,单独抽象出来成类,通过接口提供
//这样做的好处是,可以降低耦合,当行为发生改变时,原来的对象我们根本不用去管
//例如星际争霸2中的单位例子:

int main()
{
	//地面单位移动算法,需要检测碰撞什么的
	Move *pLandMove = new LandMove;
	Unit *pScv = new SCV( pLandMove );
	Unit *pTank = new Tank( pLandMove );

	//空中单位移动算法,基本不需要检测地图碰撞
	Move *pAirMove = new AirMove;
	Unit *pViking = new Viking( pAirMove );
	Unit *pRaven = new Raven( pAirMove );

	pScv->move();
	pTank->move();

	pViking->move();
	pRaven->move();

	delete pScv;
	delete pTank;
	delete pViking;
	delete pRaven;

	delete pLandMove;
	delete pAirMove;

	return 0;
}


6.Decorator模式


Decorator.hpp:

#ifndef _DECORATOR_HPP
#define _DECORATOR_HPP
#include <stdio.h>

class Component
{
public:
	Component(){}
	virtual ~Component(){}
	virtual void Operate(){}
};

//默认的职责,只有文件压缩
class File7z : public Component
{
public:
	File7z(){}
	~File7z(){}
	virtual void Operate()
	{
		printf( "7z文件压缩中...\n" );
	}
};

class Algorithm : public Component
{
public:
	Algorithm( Component *p )
	{
		mp = p;
	}
	virtual ~Algorithm()
	{
		delete mp;
	}
protected:
	//上一个操作对象
	Component *mp;
};



class AES256 : public Algorithm
{
public:
	AES256( Component *p )
		:Algorithm( p )
	{}
	~AES256(){}
	virtual void Operate()
	{
		//上一个职责
		mp->Operate();
		printf( "aes256加密中..\n" );
	}
};

class CheckError : public Algorithm
{
public:
	CheckError( Component *p )
		:Algorithm( p )
	{}
	~CheckError(){}
	virtual void Operate()
	{
		//上一个职责
		mp->Operate();
		printf( "检测文件包是否出错中...\n" );
	}
};

#endif

Main.cpp:


#include "Decorator.hpp"

//作用:给一个对象的行为添加新的职责,两两直接可以相互组合成新的职责,而不用在定义新的组合功能类
//例如文件压缩过程 压缩->加密->检测 等等例子可能不是太恰当,记住这种添加职责的思想即可
int main()
{
    //默认只有文件压缩
    Component *pFile7z = new File7z;

    //给pFile7z添加加密
    Component *pAes256 = new AES256( pFile7z );

    //给pFile7z加密后检测是否出错
    Component *pCheck = new CheckError( pAes256 );

    //执行
    pCheck->Operate();
    delete pCheck;
    
    //或者直接链式操作
    printf( "----\n" );
    pCheck = new CheckError( new AES256( new File7z ) );
    pCheck->Operate();

    delete pCheck;
    return 0;
}


未完待续...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值