现在的位置: 首页 > 综合 > 正文

设计模式中结构型模式

2017年12月07日 ⁄ 综合 ⁄ 共 9510字 ⁄ 字号 评论关闭

 

结构图:

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


抱歉!评论已关闭.