1、桥接模式
介绍
将抽象部分与实现部分分离,使它们都可以独立的变化。
桥接模式的核心意图就是把这些实现对立出来,让它们各自变化。这就使得每一种实现的变化不会影响其他实例。
比如说我实现了A手机品牌上某个软件的类,但是如果客户需求改变,需要改为B手机品牌上实现,明天又改变软件的需求,这样的话如果都放在一个类里实现,就会很混乱。我可以设计一个手机品牌的抽象类和一个手机软件的抽象类,不同的手机品牌和软件继承他们的抽象类,具体的手机品牌中拥有手机软件的指针。
意义
- 桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。
- 对于两个独立变化的维度,使用桥接模式再适合不过了。
- 分离抽象接口及其实现部分。提高了比继承更好的解决方案
代码实现
#include<iostream>
#include<list>
using namespace std;
class SoftWare{
public:
virtual void run(){}
virtual ~SoftWare(){}
//protected:
SoftWare() {}
string m_name;
};
class Game:public SoftWare{
public:
Game(string name){
m_name=name;
}
~Game(){}
void run(){
cout<<"Game "<<m_name<<" running..."<<endl;
}
};
class AddressList:public SoftWare{
public:
AddressList(string name){
m_name=name;
}
~AddressList(){}
void run(){
cout<<"AddressList: "<<m_name<<" running..."<<endl;
}
};
class Phone{
public:
void addSoft(SoftWare* soft){
m_soft.push_back(soft);
}
virtual void run()=0;
virtual ~Phone(){}
protected:
Phone() {}
list<SoftWare*> m_soft;
};
class PhoneA:public Phone{
public:
~PhoneA(){}
void run(){
cout<<"PhoneA run..."<<endl;
for(auto i:m_soft){
i->run();
}
}
};
int main(){
Phone *p=new PhoneA();
p->addSoft(new Game("game1"));
p->addSoft(new Game("game2"));
p->addSoft(new Game("game3"));
p->addSoft(new AddressList("list1"));
p->addSoft(new AddressList("list2"));
p->run();
return 0;
}
2.适配器模式
概念
它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。
可以采用组合或继承的方式实现适配器模式。
简单来说就是把客户需求的对象用一个自己实现的适配器以组合或继承的方式包装一下,然后自己去使用这个适配器来操作需求的对象。
代码实现
#include<iostream>
using namespace std;
class Target{
public:
Target(){}
virtual ~Target(){}
virtual void Request(){
cout<<"Target::Request()"<<endl;
}
};
class Adaptee{
public:
Adaptee(){}
~Adaptee(){}
void SpecificRequest(){
cout<<"Adaptee::SpecificRequest()"<<endl;
}
};
class Adapter:public Target{
public:
Adapter(Adaptee *ade):ade(ade){}
~Adapter(){}
void Request(){
cout<<"Adapter::Request()"<<endl;
ade->SpecificRequest();
}
private:
Adaptee *ade;
};
int main(){
Adaptee *ade=new Adaptee();
Target *adt=new Adapter(ade);
adt->Request();
return 0;
}
3.装饰器模式
概念
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。
角色
-
Component(被装饰对象的基类)定义一个对象接口,可以给这些对象动态地添加职责。
-
ConcreteComponent(具体被装饰对象)定义一个对象,可以给这个对象添加一些职责。
-
Decorator(装饰者抽象类)维持一个指向Component实的引用,并定义一个与Component接口一致的接口
-
ConcreteDecorator(具体装饰者)具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。
代码实现
这里我假设有一个人的抽象类,和一个有装备的人的抽象类,有什么装备也没有的RealMan,和装备了武器的人EquipedWithArm
这个装备了武器的人,继承自人,还拥有一个人的指针,当调用show时,会启动自己额外的功能addition,在addition中会访问拥有的“人”来更新父类的“人”。
#include<iostream>
using namespace std;
class Man{
public:
virtual void show(){
cout<<"height="<<height<<" weight="<<weight<<" iq="<<iq<<endl;
}
int height;
int weight;
int iq;
};
class RealMan:public Man{
public:
RealMan(){
height=1;
weight=1;
iq=1;
}
};
class equipedMan:public Man{
public:
equipedMan(Man* m){
this->man=m;
}
Man* man;
};
class EquipedWithArm:public equipedMan{
public:
EquipedWithArm(Man* man):equipedMan(man){
}
void show(){
Addtion();
Man::show();
}
void Addtion(){
cout<<"After equiped"<<endl;
this->height=man->height*2;
this->weight=man->weight*2;
this->iq=man->iq*2;
}
};
int main(){
Man* man=new RealMan();
man->show();
cout<<endl;
Man* eman=new EquipedWithArm(man);
eman->show();
}