c++设计模式之桥接模式

                                                                                             c++设计模式之桥接模式     

 

作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化。将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化。

 

                     

桥接模式就将实现与抽象分离开来,使得RefinedAbstraction依赖于抽象的实现,这样实现了依赖倒转原则,而不管左边的抽象如何变化,只要实现方法不变,右边的具体实现就不需要修改,而右边的具体实现方法发生变化,只要接口不变,左边的抽象也不需要修改。

 

#include <iostream>
using namespace std;


/*
 * 桥接模式
 */


/*
 * 实现基类
 */ 
class AbstractionImp {
public:
	virtual void operation() = 0;  
	virtual ~AbstractionImp()
	{
	}
};
class ConcreteAbstractionImpA : public AbstractionImp {
public:
	void operation()
	{
		cout << " ConcreteAstractionImpA" << endl;
	}


	~ConcreteAbstractionImpA()
	{
		cout << "ConcreteAbstractionImpA's ~" << endl;
	}
};
class ConcreteAbstractionImpB : public AbstractionImp {
public:
	void operation()
	{
		cout << " ConcreteAstractionImpB" << endl;
	}


	~ConcreteAbstractionImpB()
	{
		cout << "ConcreteAbstractionImpB's ~" << endl;
	}
};


/*
 * 抽象基类
 */ 
class Abstraction {
private:
	  AbstractionImp *aImp;  
public:
	Abstraction( AbstractionImp *aImp )
	{
		this->aImp = aImp;  
	}


	virtual void operation() = 0;


	virtual ~Abstraction()
	{
	}


	void inter()
	{
		aImp->operation();
	}


	 
};
class RefindAbstraction1 : public Abstraction {
public:
	RefindAbstraction1( AbstractionImp * aImp ) : Abstraction( aImp )
	{
	}


	void operation()
	{
		     cout << "RefindAbstraction1 is on";
		 inter();
	}


	~RefindAbstraction1()
	{
		cout << "RefindAbstraction1's ~" << endl;
	}
};
class RefindAbstraction2 : public Abstraction {
public:
	RefindAbstraction2( AbstractionImp * aImp ) : Abstraction( aImp )
	{
	}


	void operation()
	{
		cout << "RefindAbstraction2 is on";
		inter();
	}


	~RefindAbstraction2()
	{
		cout << "RefindAbstraction2's ~" << endl;
	}
};
int main( void )
{
	ConcreteAbstractionImpA *cAIa	= new ConcreteAbstractionImpA();
	Abstraction		*Ra1	= new RefindAbstraction1( cAIa );
	Ra1->operation();  
	delete cAIa;
	delete Ra1;  
	return(0);
}

例子:

手机品牌和软件是两个概念,不同的软件可以在不同的手机上,不同的手机可以有相同的软件,两者都具有很大的变动性。如果我们单独以手机品牌或手机软件为基类来进行继承扩展的话,无疑会使类的数目剧增并且耦合性很高

 

常用的场景
1.当一个对象有多个变化因素的时候,考虑依赖于抽象的实现,而不是具体的实现。如上面例子中手机品牌有2种变化因素,一个是品牌,一个是功能。

2.当多个变化因素在多个对象间共享时,考虑将这部分变化的部分抽象出来再聚合/合成进来,如上面例子中的通讯录和游戏,其实是可以共享的。

3.当我们考虑一个对象的多个变化因素可以动态变化的时候,考虑使用桥接模式,如上面例子中的手机品牌是变化的,手机的功能也是变化的,所以将他们分离出来,独立的变化。

优点
1.将实现抽离出来,再实现抽象,使得对象的具体实现依赖于抽象,满足了依赖倒转原则。

2.将可以共享的变化部分,抽离出来,减少了代码的重复信息。

3.对象的具体实现可以更加灵活,可以满足多个因素变化的要求。

缺点
1.客户必须知道选择哪一种类型的实现。

 

 

 

考虑装操作

系统,

有多种配置的计算机,

同样也有多款操作系统。

如何运用桥接模式呢?可以将操作系统和

计算机分别抽象出来,让它们各自发展,减少它们的耦合度。当然了,两者之间有标准的接口。

这样设计,不论是对于计算机,还是操作系统都是非常有利的。

考虑装操作系统,有多种配置的计算机,同样也有多款操作系统。如何运用桥接模式呢?可以将操作系统和计算机分别抽象出来,让它们各自发展,减少它们的耦合度。当然了,两者之间有标准的接口。这样设计,不论是对于计算机,还是操作系统都是非常有利的。

                  

 

#include <iostream>
using namespace std;


/*
 * 实现基类 
 */
class Os {
public:
	virtual void install_imp() = 0;


	virtual ~Os()
	{
	};
};


/*
 * 具体实现类 
 */ 
class LinuxOS : public Os {
public:
	void install_imp()
	{
		cout << "安装linux系统!!" << endl;
	}
};
class windowsOS : public Os {
public:
	void install_imp()
	{
		cout << "安装windows系统!!" << endl;
	}
};
class unixOS : public Os {
public:
	void install_imp()
	{
		cout << "安装unix系统!!" << endl;
	}
};


/*
 * 抽象基类 
 */ 
class computer {
private:
	Os	* os;
	string	name;
public:
	computer( Os *os, string name )
	{
		this->os	= os;
		this->name	= name;
	}


	virtual void install() = 0;


	void inter()
	{
		   cout << name << ":";
		os->install_imp();
	}
};


/*
 * 具体抽象类 
 */ 
class Applecomputer : public computer {
public:
	Applecomputer( Os *os ) : computer( os, "Applecomputer" )
	{
	}  
	void install()
	{
		inter();
	}
};
class dellcomputer : public computer {
public:
	dellcomputer( Os *os ) : computer( os, "dellcomputer" )
	{
	}  
	void install()
	{
		inter();
	}
};
class lenovocomputer : public computer {
public:
	lenovocomputer( Os *os ) : computer( os, "lenovocomputer" )
	{
	}  
	void install()
	{
		inter();
	}
};
int main( void )
{
	Os		* po1	= new windowsOS();
	Os		* po2	= new LinuxOS();
	computer	* pc1	= new lenovocomputer( po1 );
	computer	* pc2	= new dellcomputer( po2 );
	pc1->install();
	pc2->install();
	delete po1;
	delete po2;
	delete pc1;
	delete pc2;
	return(0);
}


 

备注:

由于实现的方式有多种,桥接模式的核心就是把这些实现独立出来,让他们各自变化。

将抽象部分与它的实现部分分离:实现系统可能有多角度(维度)分类,每一种分类都可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。

在发现需要多角度去分类实现对象,而只用继承会造成大量的类增加,不能满足开放-封闭原则时,就要考虑用Bridge桥接模式了。

合成/聚合复用原则:尽量使用合成/聚合,精良不要使用类继承。
优先使用对象的合成/聚合将有助于保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值