c++设计模式之桥接模式
2015-05-28 15:24
405 查看
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桥接模式了。
合成/聚合复用原则:尽量使用合成/聚合,精良不要使用类继承。
优先使用对象的合成/聚合将有助于保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化。将抽象(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桥接模式了。
合成/聚合复用原则:尽量使用合成/聚合,精良不要使用类继承。
优先使用对象的合成/聚合将有助于保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
相关文章推荐
- c++设计模式之桥接模式
- 设计模式---桥接模式(C++实现)
- 设计模式C++实现--桥接模式
- C++设计模式-桥接
- 设计模式C++版:第十二式桥接模式
- 设计模式_桥接模式(C++)
- 设计模式C++实现(10)——桥接模式
- C++设计模式之桥接模式
- 设计模式C++实现(10)——桥接模式
- C++设计模式之桥接模式(Bridge)
- C++设计模式-Bridge桥接模式
- 设计模式C++实现(10)——桥接模式
- c++ 设计模式之桥接模式(Bridge)
- 设计模式C++描述----09.桥接(Bridge)模式
- C++设计模式之桥接模式
- 设计模式C++实现(10)——桥接模式
- C++设计模式之桥接模式
- 23种设计模式C++实例之桥接模式
- C++设计模式-Bridge桥接模式
- 通过例子学设计模式之--桥接模式以及使用场景说明(C++实现)