设计模式——适配器模式

原创 2013年12月01日 21:45:58

结构性模式:处理多个类组合的关系。

动机:一些现存在的对象放在新环境中,新环境要求的 接口是这个现存的对象不满足的。

定义:适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。它包括类适配器和对象适配器。


对象适配器:

#include<iostream>
#include <list>

using namespace std;

//这个是需要适配的类,这个类已经非常稳定。 
class Deque  
{  
public:  
	void push_back(int x) { cout<<"Deque push_back"<<endl; }  
	void push_front(int x) { cout<<"Deque push_front"<<endl; }  
	void pop_back() { cout<<"Deque pop_back"<<endl; }  
	void pop_front() { cout<<"Deque pop_front"<<endl; }  
}; 


//这个是客户希望的接口,只有push和pop两个方法,但是Deque没有这两个方法。
class Sequence  
{  
public:  
	virtual void push(int x) = 0;  
	virtual void pop() = 0;  
}; 

//这个是第一个适配器。实现了栈
class Stack: public Sequence  
{  
public:  
	void push(int x) { deque.push_back(x); }  
	void pop() { deque.pop_back(); }  
private:  
	Deque deque; //双端队列  
};

//这是第二个适配器,实现了队列  
class Queue: public Sequence  
{  
public:  
	void push(int x) { deque.push_back(x); }  
	void pop() { deque.pop_front(); }  
private:  
	Deque deque; //双端队列  
}; 
#include "Test.h"

int main()  
{  
	Sequence *s1 = new Stack();  
	Sequence *s2 = new Queue();  
	s1->push(1); //调用适配器的接口,接口转换工作由适配器去完成。
	s1->pop();  
	s2->push(1); 
	s2->pop();  
	delete s1; delete s2;  
	return 0;  
}


类适配器

例子2:

#include<iostream>
#include <vector>

using namespace std;

class CShape  //一个绘图模型
{
public:
	~CShape() {};

	virtual void Draw() = 0;
};

class CRectangle : public CShape  //可以绘长方形
{
public:
	void Draw() { cout << "Draw a rectangle." << endl; };
};


class CSquare : public CShape  //可以绘正方形。
{
public:
	void Draw() { cout << "Draw a square." << endl; };
};

class CView : public CShape
{
public:
	~CView()
	{
		while(!m_vShape.empty())
		{
			CShape *pShape = (CShape*)m_vShape.back();
			m_vShape.pop_back();
			delete pShape;
		}
	}

	void Draw()
	{
		cout << "Draw a view." << endl;

		for (vector<CShape*>::const_iterator it = m_vShape.begin(); it != m_vShape.end(); ++it)
		{
			(*it)->Draw();
		}
			
	}

	void AddShape(CShape *pShape)
	{
		if (pShape)
		{
			m_vShape.push_back(pShape);
		}		
	}

private:
	vector<CShape*> m_vShape;
};
#include "Test.h"

int main()  
{  
	CView view;

	CRectangle *pRectangle = new CRectangle;
	view.AddShape(pRectangle);

	CSquare *pSquare = new CSquare;
	view.AddShape(pSquare);

	view.Draw(); 
	return 0;  
}

变化:现在需要绘制文本类,有一个现存的类,但是没有对应的接口。

class CContext  //绘制文本基类
{
public:
    ~CContext() {};

    virtual void DrawText() = 0;  //这个类与上面的绘图类接口不一致。
};

// 这里也以输出一句话来代替具体的draw过程

class CText : public CContext
{
public:
    void DrawText() { cout << "Draw a text." << endl; };
};


由于类CText 的父类不是CShape,而且接口跟我们想要的接口不一样。为了在我们的系统中使用类CText 来显示文本,就可以使用适配器模式创建一个类CText 的adapter,使CText 的接口适应我们已经写好的视图系统。

用类适配器实现。

class CShapeText : public CShape, private CText
{
public:
	void Draw() { DrawText(); };  //这里实现Cshape的接口

private:
	void DrawText()             //这里实现CTest的接口
	{
		CText::DrawText();

		// 这里可以改变父类的部分行为。而不是简单的直接调用。
		cout << "  It is a text adapter." << endl;
	}
};

具体的使用:

int main()  
{  
	CView view;

	CRectangle *pRectangle = new CRectangle;
	view.AddShape(pRectangle);

	CSquare *pSquare = new CSquare;
	view.AddShape(pSquare);

	// 在这里CShapeText跟其他CShape的子类一样的使用
	// 完全融入到已开发好的视图系统中
	CShapeText *pText = new CShapeText;
	view.AddShape(pText);

	view.Draw(); 
	return 0;  
}

用对象适配的实现方式:

class CShapeText : public CShape
{
public:
    CShapeText(CContext *pText) { m_pText = pText; };

    void Draw() { m_pText->DrawText(); };  //这里去调用类的方法

private:
    CContext *m_pText;
};

具体的使用方式:

int main()  
{  
	CView view;

	CRectangle *pRectangle = new CRectangle;
	view.AddShape(pRectangle);

	CSquare *pSquare = new CSquare;
	view.AddShape(pSquare);

	// 这里的CShapeText一样可以很好的融入到已开发好的视图系统中
	CText *pText = new CText;
	CShapeText *pShapeText = new CShapeText(pText);
	view.AddShape(pShapeText);

	view.Draw(); 
	return 0;  
}

 类适配器:
    优点:可以重新定义被适配的类的部分行为。
    缺点:不能适配一个类以及它的子类。(暂时无法理解)
    对象适配器:
    优点:可以适配一个类以及它的所有子类。
    缺点:重新定义被适配的类的行为比较困难。
    因此,我们可以得出结论:如果要适配一个类以及它的子类,或者只是简单的包装以转换接口,那就使用对象适配器;其他情况就用类适配器。



Java设计模式----适配器模式

1. 适配器模式简介      适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。      ...
  • ymeng_bupt
  • ymeng_bupt
  • 2011年09月29日 12:42
  • 9472

23种设计模式(13):适配器模式

本文主要介绍设计模式中的适配器模式。
  • psp0001060
  • psp0001060
  • 2016年02月25日 16:21
  • 663

大话设计模式—适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口...
  • lmb55
  • lmb55
  • 2016年03月29日 19:47
  • 1769

五分钟一个设计模式之适配器模式

五分钟一个设计模式,用最简单的方法来描述设计模式。查看更多设计模式,请点击五分钟一个设计模式系列 http://blog.csdn.net/daguanjia11/article/category/...
  • daguanjia11
  • daguanjia11
  • 2015年06月09日 07:14
  • 1560

JAVA设计模式初探之适配器模式

1. 概述   将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。 2. 解决的问题   即Adapter模式使得原本由于接口不...
  • jason0539
  • jason0539
  • 2014年03月29日 07:53
  • 45769

java 设计模式-----适配器模式

现实中的问题 有一个插座,这个插座是三个口的,但是我们手上只有两个触角的插头,一种笨方法就是直接强行把两个触角掰弯,插进去(这种事情我就做过),还有一种方法就是找一个转换头来。 ...
  • yujin753
  • yujin753
  • 2015年05月31日 12:12
  • 1239

设计模式——适配器模式 Java源代码

适配器模式,《Head First Design Patterns》给的代码的例子是关于鸭子和火鸡,然而鸭子和火鸡离日常生活比较远。这次,我改编了实验楼网站上面的例子,关于插座和充电器。...
  • u013390476
  • u013390476
  • 2016年01月01日 16:02
  • 2552

设计模式之适配器模式(adaptor pattern)

1 适配器模式的定义在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起...
  • suifeng3051
  • suifeng3051
  • 2016年05月25日 11:32
  • 2988

大话设计模式——适配器模式

宏观导图 细节展示  结构图:  关键代码: 对比学习  重构统一接口VS适配器 小结...
  • u011500356
  • u011500356
  • 2015年01月06日 11:19
  • 1145

设计模式-适配器模式(Go语言描述)

在上一篇博客设计模式-策略模式(Go语言描述)中我们用最简单的代码用go语言描述了 设计模式中的策略模式,用最简单的实例来描述相信可以让初学者可以很轻松的掌握各种设计模式。继上篇博客,我们接着用同样...
  • qibin0506
  • qibin0506
  • 2016年01月28日 08:56
  • 6350
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式——适配器模式
举报原因:
原因补充:

(最多只允许输入30个字)