削足适履是一个成语,大概的是很笨的意思。
但是这里用它形容 adaptor,因为过程很像。
如果我们要用了一个我们没什么权力和必要性修改的类库。要把它的接口给我们做适配,就要用到这种模式。
其实这是比较自然的。
通过一个转换,把要复用的第三方类库的接口置入我们的接口中,就可以实现。
适配的意思,就是把不对榫的物料削一削,塑塑形
class Shape
{
public:
virtual void draw() = 0;
};
class Circle: public Shape
{
public:
void draw() {
}
};
class OtherShapeTool
{
public:
void virtual paint(); // draw a perticular shape
};
class Adaptor: public Shape
{
public:
Adaptor(OtherShapTool * tool) {
this->tool = tool;
}
virtual void draw() {
tool->paint();
// do somthing
}
private:
OtherShapeTool *tool;
};
上面的代码中,OtherShapeTool上有一个画特别图形的接口,假设它实现很复杂,我们要拿过来复用,但是接口和 我们定义的 draw 不一样,于是,我们在派生某个类(适配器里)中通过组合的方式把 OtherShapeTool 对象拿过来,构造函数可以设置一个 OtherShapeTool 的参数,然后在 Adaptor的 draw的实现中调 第三方的paint函数。
成功适配。
另一种办法,不用组合,使用多重继承。
C++支持多重继承。
但是为了表明,适配器 Adaptor 是 Shape的子类,但不是 OtherShapeTool的子类,我们要做点操作,那就是
继承 Shape 是 public 公有继承,表明 Adaptor还是 Shape的子类型
继承 OtherShapeTool 使用 private 私有继承
public 继承接口,而private可以继承实现但不继承接口
上面的代码变成这样
class Adaptor: public Shape, private OtherShapeTool
{
public:
void draw() {
paint(); //调用 OtherShapeTool的 paint函数
}
}
看起来多重继承更简单一点,但是组合的方式却更加灵活,如果OtherShapeTool 是一个抽象类,我们还可以扩展 OtherShapeTool ,但是继承的方法却做不到。
总结
适配器是一种比较简单的模式,所见的代码中, 用组合的方式较为隐式,通常持有的第三者是悄悄的,适配器也没有命名成 adaptor,但是我们不用刻意识别它。
因为这样写代码实际上太过自然,以至于我们在很多类库中看见它,没有意识到它竟然是23中设计模式之一,哈哈。
多重继承的方法不太常见,如果存在,比较容易看出来这是一种技巧。
适配器能够将某些模块之间的关系划分得比较清晰,比方说,模块A依赖一个第三方组件的一系列接口,这个组件的维护不可控制,那么就应该定义个适配器,把所有需要的接口统一按照我方的习惯和规范做好,这样当组件有变化,甚至更换另一个组件时,我们只需要维护适配器即可。而不需要改动模块A的代码。
网友评论