桥接(Bridge)模式

合成/聚合复用原则

在进行功能拓展时,应首先考虑合成/聚合,其次采用继承。

  1. 合成:一种较强的‘包含’关系,严格的部分和整体的关系,有相同的生命周期。如:大雁与翅膀
  2. 聚合:一种较弱的‘包含’关系,种类上的包含,A包含B,B不一定包含与A。如:大雁与雁群
  3. 可以有效的控制类层次的规模。

桥接模式

将抽象与实现分离,是它们可以独立变化。

抽象与实现分离并非抽象基类与派生类之间的关系。抽象是指产品的不同分类方法;实现指具体产品。如:手机的各种品牌是抽象,而具体手机的软件则是实现。

举个例子: 我们有OPPO与VIVO两种手机,每种手机上的软件大同小异,有两种基本功能:打电话、玩游戏。如果使用继承机制按树形继承,当我们需要增加品牌或功能时,需要产生大量的类。我们发现手机与软件之间是一种“聚合”关系。也就是,手机需要有多个软件组成.在两个相对独立的基类中,其实隐含着一个一对多的关系,我们可一使用合成/聚合原则将其解耦开来。完成对类层次规模的控制。

Bridge

图中可以看出,‘桥’是指聚合桥(一对多),桥的左边是抽象,包含的一方为主体,桥的右边是实现。
我们发现,若按照继承的方案来做,应该是cellphone->brand->software的三层结构,合成/聚合复用原则就是尽可能用类之间的组合来代替继承.

//software.hpp

#include <iostream>
#ifndef _DESIGN_PATTERN_BRIDGE_SOFTWARE_HPP_
#define _DESIGN_PATTERN_BRIDGE_SOFTWARE_HPP_

namespace design_pattern
{
	class Software
	{
	public:
		virtual void Operation() = 0;

		virtual ~Software() {}
};

class CallSoftware : public Software
{
public:
	void Operation()
	{
		std::cout << "Calling xxx!!!" << std::endl;
	}
};

class GameSoftware : public Software
{
public:
	void Operation()
	{
		std::cout << "Playing Game!!!" << std::endl;
	}
};
}

#endif // !_DESIGN_PATTERN_BRIDGE_SOFTWARE_HPP_

//brand.hpp

#include "software.hpp"
#ifndef _DESIGN_PATTERN_BRIDGE_BRAND_HPP_
#define _DESIGN_PATTERN_BRIDGE_BRAND_HPP_

namespace design_pattern
{

class Brand
{
protected:
	Software *psoft_;
public:
	
	void set_psoft(Software * const ptr)
	{
		psoft_ = ptr;
	}

	virtual void Operation() = 0;
	virtual ~Brand() {}
};

class OPPO : public Brand
{
public:

	void Operation()
	{
		psoft_->Operation();
	}
};

class VIVO : public Brand
{
public:

	void Operation()
	{
		psoft_->Operation();
	}
};
}

#endif // !_DESIGN_PATTERN_BRIDGE_BRAND_HPP_

//bridge_main.cpp

#include "brand.hpp"
#include "software.hpp"
#include <memory>
#include <typeinfo>
using std::cout;
using std::endl;
using std::unique_ptr;
using std::make_unique;
using namespace design_pattern;

int main()
{
	
	unique_ptr<Software> ptr(new CallSoftware);
	OPPO oppo;
	Brand *poppo = &oppo;
	cout << ptr.get() << endl;
	poppo->set_psoft(ptr.get());
	poppo->Operation();

	ptr.reset(new GameSoftware);
	VIVO vivo;
	Brand *pvivo = &vivo;
	pvivo->set_psoft(ptr.get());
	pvivo->Operation();

	return 0;
}

语法tips
  • std中的智能指针对有继承关系的类使用时,智能指针不具有继承关系,所以先进行类型转换,在make_xxx生成智能指针。
  • C++运行时类型查看
    1. 头文件
    2. typeid(var).name()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值