这部分笔记,是对刘伟博客和书本做提炼和记录,方便自己查阅,更多是对设计模式的基础框架学习,细节都将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.适配器模式(Adapter)
前阵子从香港买了Mac mini,拆开发现电源线的插头和我们这边不匹配,根本不能插入我们这边的排插;百度之,立马入手一个公牛英式转接头,问题解决了。这个转接头便类似于设计模式中的适配器角色。适配器模式相当于将一个类的接口和另一个类的接口匹配起来,而不需要修改原有适配者接口和抽象目标类接口。
(1)定义
适配器模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。别名:包装器(Wrapper)。
适配器又分类适配器和对象适配器。下面来看他们各自的结构图,
1)首先是对象适配器结构图,它依赖于对象组合,如下图所示:
a) Target:定义Client使用的与特定领域相关的接口;
b) Client:与符合Target接口的对象协同;
c) Adapter:对Adaptee的接口与Target进行适配。
d) 看图写代码:
class Target
{
public:
virtual void Request() = 0;
};
//适配者
class Adaptee
{
public:
void SpecificRequest();
};
void Adaptee::SpecificRequest()
{
cout<<"SpecificRequest\n";
}
//适配器
class Adapter:public Target
{
public:
Adapter();
~Adapter();
virtual void Request();
private:
Adaptee* m_Adaptee;
};
Adapter::Adapter()
{
//构造函数注入适配者,或者直接生成
m_Adaptee = new Adaptee();
}
Adapter::~Adapter()
{
if(m_Adaptee != NULL)
{
delete m_Adaptee;
m_Adaptee = NULL;
}
}
void Adapter::Request()
{
//调用适配者的方法
m_Adaptee->SpecificRequest();
}
//客户端调用
int main()
{
Target *adapter = new Adapter();
adapter->Request();
delete adapter;
adapter = NULL;
return 0;
}
2)其次是类适配器结构图,它使用多重继承对一个接口与另一个接口进行匹配,如下图所示:
注意:类适配器和对象适配器对大的差别在于适配器和适配者之间的关系不同,对象适配器模式中适配器和适配者之间是关联关系,而类适配器模式中适配器和适配者是继承关系。
a) 看图写代码:
//target
class Target
{
public:
virtual void Request() = 0;
};
//适配者
class Adaptee
{
public:
void SpecificRequest();
};
void Adaptee::SpecificRequest()
{
cout<<"SpecificRequest\n";
}
//适配器
class Adapter:public Target,Adaptee//继承
{
public:
Adapter();
~Adapter();
virtual void Request();
};
Adapter::Adapter()
{
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
//调用适配者的方法
Adaptee::SpecificRequest();
}
//客户端不变
int main()
{
Target *adapter = new Adapter();
adapter->Request();
delete adapter;
adapter = NULL;
return 0;
}
(2)总结
1)类适配器
a) 用一个具体的Adapter类对Adaptee和Target进行匹配,当我们要匹配一个类(adaptee)以及所有他的子类时,Adapter将不能胜任工作。
b) Adapter可以重定义Adaptee的部分行为,因为他是Adaptee的子类。
c) 仅仅引入一个对象,并不需要额外的指针以间接得到adaptee。
2)对象适配器
a) 允许一个Adapter与多个Adaptee(即Adapter本身以及他的所有子类)同时工作,可以适配Adaptee的子类,也可以把不同的适配者适配到同一目标。
b) 使得重定义Adapter的行为比较困难,需要生成Adapter的子类并且使得Adapter引用这个子类而不是引用Adaptee本身。
c) 当Adaptee中添加新的抽象方法时,Adapter类不需要做任何调整,也能正确进行。
(3)使用场景
1)你想使用一个已经存在的类,但是他的接口不符合你的需求;
2)你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作;
3)(仅适用对象适配器)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化已匹配他们的接口,对象适配器可以适配他们的父类接口。
4)一般情况下,能使用对象组合方式就不使用多继承方式;对象适配器的耦合度更低。