设计模式(6)-适配器模式(Apater) (一)

2014-11-24 09:58:07 · 作者: · 浏览: 3

【描述】适配器模式将某个对象的接口适配为另一个对象所期望的接口。

【UML图】

\

图1 Apater模式

(1) 已知Apatee类,该类提供了画线的函数实现;

(2) 现在用户要求绘制点,我们知道如果将画线函数起点和终点坐标取一致,实际上就相当于绘制了点。于是决定采用适配器模式将画线函数适配为画点函数。

【代码清单】

apatee.h

[html]
#ifndef APATEE_H
#define APATEE_H

class Apatee
{
public:
Apatee();

public:
void draw(int x0, int y0, int x1, int y1);
};

#endif // APATEE_H

#ifndef APATEE_H
#define APATEE_H

class Apatee
{
public:
Apatee();

public:
void draw(int x0, int y0, int x1, int y1);
};

#endif // APATEE_H

apatee.cpp

[html]
#include
#include "apatee.h"

Apatee::Apatee()
{
qDebug()<<"construct Apatee";
}

void Apatee::draw(int x0, int y0, int x1, int y1)
{
qDebug()< }

#include
#include "apatee.h"

Apatee::Apatee()
{
qDebug()<<"construct Apatee";
}

void Apatee::draw(int x0, int y0, int x1, int y1)
{
qDebug()< }

apater.h

[html]
#ifndef APATER_H
#define APATER_H

#include "apatee.h"

class Apater : public Apatee
{
public:
Apater(Apatee adaptee);

private:
Apatee apatee;

public:
void draw_dot(int x, int y);
};

#endif // APATER_H

#ifndef APATER_H
#define APATER_H

#include "apatee.h"

class Apater : public Apatee
{
public:
Apater(Apatee adaptee);

private:
Apatee apatee;

public:
void draw_dot(int x, int y);
};

#endif // APATER_H

apater.cpp

[html]
#include
#include "apater.h"

Apater::Apater(Apatee adaptee)
{
qDebug()<<"construct Apater";
this->apatee = apatee;
}

void Apater::draw_dot(int x, int y)
{
qDebug()<<(QString("Apater::draw_dot(int %1, int %2)").arg(x).arg(y));
apatee.draw(x, y, x, y);
}

#include
#include "apater.h"

Apater::Apater(Apatee adaptee)
{
qDebug()<<"construct Apater";
this->apatee = apatee;
}

void Apater::draw_dot(int x, int y)
{
qDebug()<<(QString("Apater::draw_dot(int %1, int %2)").arg(x).arg(y));
apatee.draw(x, y, x, y);
}

【运行结果】

[html]
construct Apatee
construct Apatee
construct Apatee
construct Apater
"Apater::draw_dot(int 1, int 2)"
"Apatee::draw(int 1, int 2, int 1, int 2)"

construct Apatee
construct Apatee
construct Apatee
construct Apater
"Apater::draw_dot(int 1, int 2)"
"Apatee::draw(int 1, int 2, int 1, int 2)"

【分析】
适配器模式实际上,也可采用继承实现。继承Apatee类后,Apater类中直接调用父类方法。即将

[html]
apatee.draw(x, y, x, y);

apatee.draw(x, y, x, y);替换为

[html] view plaincopyprint draw(x, y, x, y);

draw(x, y, x, y);
【实例剖析】

MD5算法的Qt实现一文代码中,update()函数实际上就是应用了适配器模式的思想。

我们要实现的update接口包括:

[html]
private:
void update(const byte* input, size_t length);
public:
void update(const void* input, size_t length);
void update(const QString& str);
void update(ifstream& in);

private:
void update(const byte* input, size_t length);
public:
void update(const void* input, size_t length);
void update(const QString& str);
void update(ifstream& in);

但实际上,我们只需实现一个接口(这个接口是私有的):

[html]
void update(const byte* input, size_t length);

void update(const byte* input, size_t length);
实现代码

[html] view plaincopyprint void MD5::update(const byte *input, size_t length)
{
uint32 i, index, partLen;

_finished = false;

/* Compute number of bytes mod 64 */
index = (uint32)((_count[0] >> 3) & 0x3f);//0x3f = 63

/* update number of bits */
if ((_count[0] += ((uint32)length << 3)) < ((uint32)length << 3))
{
++_count[1];

}
_count[1] += ((uint32)length >> 29);

//qDebug()<<_count[0]<<_count[1];

partLen = 64 - index;

/* transform as many times as possible. */
if (length >= partLen)
{

memcpy(&_buffer[index], input, partLen);
transform(_buffer);

for (i = partLen; i + 63 < length; i += 64)
{
transform(&input[i]);
}
index = 0;

}
e