设计模式中结构型模式

 

结构图:

结构型模式涉及到如何组合类和对象以获得更大的结构。
结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而
实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有
更大的灵活性,而这种机制用静态类组合是不可能实现的。
定义: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本身。

本章用两个实例分别讲述类适配器模式和对象适配器模式。

对于结构型模式,由于需要用到一些结构,因此这里先贴出来,部分只有申明无实现是因为还未被用到,用到时会逐步补上去的。

 一、类适配器

//  BasicClass.h: interface for the BasicClass class.
//
//

#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中功能增强的一种方式。

代码如下:

 

//  Adapter.h: interface for the Adapter class.
//
//

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永远的麦田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值