六、Adapter(适配器)
情景举例:
解决类之间由于接口不匹配而不能复用的情况。
代码示例:
/* 目标类
*/
class Shape {
public:
Shape();
virtual void BoundingBox(
Point& bottomLeft, Point& topRight
) const;
virtual Manipulator* CreateManipulator() const;
};
/* 待匹配类
*/
class TextView {
public:
TextView();
void GetOrigin(Coord& x, Coord& y) const;
void GetExtent(Coord& width, Coord& height) const;
virtual bool IsEmpty() const;
};
/* 类适配器:公有继承目标类,私有继承待匹配类
*/
class TextShape : public Shape, private TextView {
public:
TextShape();
virtual void BoundingBox(
Point& bottomLeft, Point& topRight
) const;
virtual bool IsEmpty() const;
virtual Manipulator* CreateManipulator() const;
};
/*
*/
void TextShape::BoundingBox (
Point& bottomLeft, Point& topRight
) const {
Coord bottom, left, width, height;
GetOrigin(bottom, left);
GetExtent(width, height);
/*
*/
bottomLeft = Point(bottom, left);
topRight = Point(bottom + height, left + width);
}
/* 常见的直接转发请求的用法
*/
bool TextShape::IsEmpty () const {
return TextView::IsEmpty();
}
/* 对象适配器:公有继承目标类,以一个待匹配类的实例作为私有成员变量
*/
class TextShape : public Shape {
public:
TextShape(TextView*);
virtual void BoundingBox(
Point& bottomLeft, Point& topRight
) const;
virtual bool IsEmpty() const;
virtual Manipulator* CreateManipulator() const;
private:
TextView* _text;
};
/*
*/
TextShape::TextShape (TextView* t) {
_text = t;
}
/*
*/
void TextShape::BoundingBox (
Point& bottomLeft, Point& topRight
) const {
Coord bottom, left, width, height;
_text->GetOrigin(bottom, left);
_text->GetExtent(width, height);
bottomLeft = Point(bottom, left);
topRight = Point(bottom + height, left + width);
}
/*
*/
bool TextShape::IsEmpty () const {
return _text->IsEmpty();
}
个人理解:
适配器模式只是简单改变类的接口的模式,主要分析下类适配器与对象适配器的区别。
类适配器由于私有继承了待匹配类,则可以重定义其部分操作。而对象适配器不能。对象适配器可以应用在需要匹配某一父类和其全部子类的情况下,而类适配器则不能胜任。