结构图:
结构型模式涉及到如何组合类和对象以获得更大的结构。
结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而
实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有
更大的灵活性,而这种机制用静态类组合是不可能实现的。
定义:Adapter:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本
由于接口不兼容而不能一起工作的那些类可以一起工作。
尽管Adapter模式的实现方式通常简单直接,但是仍需要注意以下一些问题:
在使用C++实现适配器类时,Adapter类应该采用公共方式继承Target类,并且用私有方式
继承Adaptee类。因此,Adapter类应该是Target的子类型,但不是Adaptee的子类型。
适配器模式有两种方法实现,一种是类适配器,一种是对象适配器。
类适配器和对象适配器有不同的权衡。类适配器
1、用一个具体的Adapter类对Adaptee和Target进行匹配。结果是当我们想要匹配生个类以
及所有它的子类时,类Adapter将不能胜任工作。
2、使得Adapter可以重定义Adapter的部分行为,因为Adapter是Adaptee的一个子类。
3、仅仅引入了一个对象,并不需要额外的指针以间接得到adaptee.
对象适配器则
1、允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类(如果有子类的话)
同时工作。Adapter也可以一次给所有的Adaptee添加功能。
2、使得重定义Adaptee的行为比较困难。这就需要生成Adaptee的子类并且使得Adapter引用
这个子类而不是引用adaptee本身。
本章用两个实例分别讲述类适配器模式和对象适配器模式。
对于结构型模式,由于需要用到一些结构,因此这里先贴出来,部分只有申明无实现是因为还未被用到,用到时会逐步补上去的。
一、类适配器
//
/**/ //
#if !defined(AFX_BASICCLASS_H__459C19CB_0047_4A50_855E_B7FDCFC6F3B0__INCLUDED_)
#define AFX_BASICCLASS_H__459C19CB_0047_4A50_855E_B7FDCFC6F3B0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//
// #include <iostream>
// using namespace std;
#include < iostream.h >
#define DEFAULT_LIST_CAPACITY 1000
template < class Item > class List
... {
public:
List(long size = DEFAULT_LIST_CAPACITY);
List(List&);
~List();
List& operator=(const List&);
long Count() const;
Item& Get(long index) const;
Item& First() const;
Item& Last() const;
bool Includes(const Item&) const;
void Append(const Item&);
void Prepend(const Item&);
void Remove(const Item&);
void RemoveLast();
void RemoveFirst();
void RemoveAll();
Item& Top() const;
void Push(const Item&);
Item& Pop();
} ;
template < class Item > class iterator
... {
public:
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() const = 0;
virtual Item CurrentItem() const = 0;
protected:
iterator();
} ;
template < class Item > class ListIterator: public iterator < Item >
... {
public:
ListIterator(const List<Item>* aList);
virtual void First();
virtual void Next();
virtual bool IsDone();
virtual Item CurrentItem() const;
} ;
// CPoint
typedef float Coord;
class Point ... {
public:
static const Point Zero;
Point(Coord x = 0.0,Coord y = 0.0);
Coord X() const;//得到x值
Coord Y() const;
void X(Coord x);//设置x值
void Y(Coord y);
Point operator+(const Point&);
Point operator-(const Point&);
Point operator*(const Point&);
Point operator/(const Point&);
void operator+=(const Point&);
void operator-=(const Point&);
void operator*=(const Point&);
void operator/=(const Point&);
bool operator==(const Point&);
bool operator!=(const Point&);
friend ostream& operator<<(ostream&, const Point&);
friend istream& operator>>(istream&, Point&);
private:
Coord m_x;
Coord m_y;
} ;
class Rect
... {
public:
static const Rect Zero;
Rect(Coord x, Coord y, Coord w, Coord h);
Rect(const Point& origin, const Point& extent);
Coord Width() const;
void Width(Coord);
Coord Height() const;
void Height(Coord);
Coord Left() const;
void Left(Coord);
Coord Bottom() const;
void Bottom(Coord);
Point& Origin() const;
void Origin(const Point&);
Point& Extent() const;
void Extent(const Point&);
void MoveTo(const Point&);
void MoveBy(const Point&);
bool IsEmpty() const;
bool Contains(const Point&) const;
} ;
#endif // !defined(AFX_BASICCLASS_H__459C19CB_0047_4A50_855E_B7FDCFC6F3B0__INCLUDED_)
// BasicClass.cpp: implementation of the BasicClass class.
//
/**/ //
#include " stdafx.h "
#include " BasicClass.h "
Point::Point(Coord x /**/ /* = 0.0 */ ,Coord y /**/ /* = 0.0 */ )
... {
m_x = x;
m_y = y;
}
Coord Point::X() const
... {
return m_x;
}
Coord Point::Y() const
... {
return m_y;
}
void Point::X(Coord x)
... {
m_x = x;
}
void Point::Y(Coord y)
... {
m_y = y;
}
Point Point:: operator + ( const Point & p)
... {
return Point(m_x+p.m_x, m_y + p.m_y);
}
Point Point:: operator - ( const Point & p)
... {
return Point(m_x-p.m_x, m_y-p.m_y);
}
Point Point:: operator * ( const Point & p)
... {
return Point(m_x* p.m_x, m_y* p.m_y);
}
Point Point:: operator / ( const Point & p)
... {
return Point(m_x/p.m_x, m_y/p.m_y);
}
void Point:: operator += ( const Point & p)
... {
m_x += p.m_x;
m_y += p.m_y;
}
// CPoint
void Point:: operator -= ( const Point & p)
... {
m_x -= p.m_x;
m_y -= p.m_y;
}
void Point:: operator *= ( const Point & p)
... {
m_x *= p.m_x;
m_y *= p.m_y;
}
void Point:: operator /= ( const Point & p)
... {
m_x /= p.m_x;
m_y /= p.m_y;
}
bool Point:: operator == ( const Point & p)
... {
return (m_x == p.m_x && m_y == p.m_y);
}
bool Point:: operator != ( const Point & p)
... {
return !(*this== p);
}
ostream & operator << (ostream & cout, const Point & p)
... {
cout<<p.m_x<<","<<p.m_y;
return cout;
}
istream & operator >> (istream & in , Point & p)
... {
in>>p.m_x>>p.m_y;
return in;
}
类适配器模式例,在这里,TextView认为是一个工具箱,没有源码,为了调用其中的功能,需要用一个类TextShape来调用TextView中的功能,这里TextShape就叫做适配器类,它的接口BoundingBox()调用TextView中的GetExtent(),实现通过一致的接口,完成GetExtent()功能的要求。CreateManipulator功能在原TextView中没有,这是对于原有TextView中功能增强的一种方式。
代码如下:
//
/**/ //
#if !defined(AFX_ADAPTER_H__02F2DD6D_CFF8_4E63_A14B_63C2E58ACB53__INCLUDED_)
#define AFX_ADAPTER_H__02F2DD6D_CFF8_4E63_A14B_63C2E58ACB53__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include " BasicClass.h "
class Manipulator;
class Shape;
class TextManipulator;
class TextShape;
class TextView;
class Manipulator
... {
public:
Manipulator()...{}
} ;
class TextManipulator: public Manipulator
... {
public:
TextManipulator(const Shape* sp)...{ m_pShape = (Shape*)sp; }
private:
Shape* m_pShape;
} ;
class Shape ... {
public:
Shape()...{}
virtual void BoundingBox(Point& bottomLeft,Point& topRight) const
...{
bottomLeft = m_bottomLeft;
topRight = m_topRight;
}
virtual Manipulator* CreateManipulator() const
...{
return new Manipulator();
}
private:
Point m_bottomLeft;
Point m_topRight;
} ;
class TextView
... {
public:
TextView(Point org =0, Coord width = 0, Coord height = 0);
void GetOrigin(Coord& x, Coord& y) const;
void GetExtent(Coord& width, Coord& height) const;
virtual bool IsEmpty() const;
private:
Point m_org;//原点
Coord m_width;//宽度
Coord m_height;//高度
} ;
class TextShape: public Shape, private TextView
... {
public:
TextShape()...{}
virtual void BoundingBox(Point& bottomLeft,Point& topRight) const;
virtual bool IsEmpty() const;
virtual Manipulator* CreateManipulator() const;
} ;
#endif // !defined(AFX_ADAPTER_H__02F2DD6D_CFF8_4E63_A14B_63C2E58ACB53__INCLUDED_)
// Adapter.cpp: implementation of the Adapter class.
//
/**/ //
#include " stdafx.h "
#include " Adapter.h "
/**/ //
// Construction/Destruction
/**/ //
//
TextView::TextView(Point org /**/ /* =0 */ , Coord width /**/ /* = 0 */ , Coord height /**/ /* = 0 */ )
... {
m_org = org;
m_width = width;
m_height = height;
}
void TextView::GetOrigin(Coord & x, Coord & y) const
... {
x = m_org.X();
y = m_org.Y();
}
void TextView::GetExtent(Coord & width, Coord & height) const
... {
width = m_width;
height = m_height;
printf("TextView::GetExtent() ");
}
bool TextView::IsEmpty() const
... {
return (m_width>0 && m_height>0);
}
/**/ //
// 通过BoundingBox调用TextShape()中的接口,达到适配的目的
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();
}
Manipulator * TextShape::CreateManipulator() const
... {
return new TextManipulator(this);
}
// testConfig.cpp : Defines the entry point for the console application.
//
#include " stdafx.h "
#include " BasicClass.h "
#include " Adapter.h "
int main( int argc, char * argv[])
... {
printf("Hello World! ");
TextShape ts;
Point p1(1,2);
Point p2(3,4);
ts.BoundingBox(p1,p2);
return 0;
}
二、对象适配器
对象适配器的功用和类适配器相同,不过它不是采用多重继承来实现,而是通过组合的方式,在适配器类中定义一个被适配的子对象(Adaptee),通过这个子对象完成适配的功能。
相关代码和前面代码类似,只需改动以下部分即可。
class TextShape: public Shape
... {
public:
TextShape(TextView* t)...{ _text = t; }
virtual void BoundingBox(Point& bottomLeft,Point& topRight) const;
virtual bool IsEmpty() const;
virtual Manipulator* CreateManipulator() const;
private:
TextView * _text;
} ;
// 通过BoundingBox调用TextShape()中的接口,达到适配的目的
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();
}
Manipulator * TextShape::CreateManipulator() const
... {
return new TextManipulator(this);
}
int main( int argc, char * argv[])
... {
printf("Hello World! ");
TextView tv;
TextShape ts(&tv);
Point p1(1,2);
Point p2(3,4);
ts.BoundingBox(p1,p2);
return 0;
}