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

来源:互联网 发布:白鲨外设淘宝店 编辑:程序博客网 时间:2024/05/21 15:47

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

【UML图】

图1 Apater模式

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

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

 

【代码清单】

apatee.h

#ifndef APATEE_H#define APATEE_Hclass Apatee{public:    Apatee();public:    void draw(int x0, int y0, int x1, int y1);};#endif // APATEE_H


apatee.cpp

#include <QDebug>#include "apatee.h"Apatee::Apatee(){    qDebug()<<"construct Apatee";}void Apatee::draw(int x0, int y0, int x1, int y1){    qDebug()<<QString("Apatee::draw(int %1, int %2, int %3, int %4)").arg(x0).arg(y0).arg(x1).arg(y1);}

 

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

#include <QDebug>#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);}


【运行结果】

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类中直接调用父类方法。即将

apatee.draw(x, y, x, y);

替换为

draw(x, y, x, y);


【实例剖析】

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

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

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);


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

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

实现代码

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;    }    else    {        i = 0;    }    /* Buffer remaining input */    memcpy(&_buffer[index], &input[i], length - i);}/*    MD5 finalization. Ends an MD5 message-_digest operation, writing the    the message _digest and zeroizing the context.*/void MD5::final(){    byte bits[8];    uint32 oldState[4];    uint32 oldCount[2];    uint32 index, padLen;    /* Save current state and count. */    memcpy(oldState, _state, 16);    memcpy(oldCount, _count, 8);    /* Save number of bits */    encode(_count, bits, 8);    /* Pad out to 56 mod 64. */    index = (uint32)((_count[0] >> 3) & 0x3f);    padLen = (index < 56) ? (56 - index) : (120 - index);    update(PADDING, padLen);    /* Append length (before padding) */    update(bits, 8);    /* Store state in digest */    encode(_state, _digest, 16);    /* Restore current state and count. */    memcpy(_state, oldState, 16);    memcpy(_count, oldCount, 8);}


其余接口(公有的)采用适配器模式就可以了。

void MD5::update(const void *input, size_t length){    update((const byte*)input, length);}void MD5::update(const QString &str){    update((const byte*)str.toLatin1().data(), str.length());}void MD5::update(ifstream &in){    if (!in)    {        return;    }    std::streamsize length;    char buffer[BUFFER_SIZE];    while (!in.eof())    {        in.read(buffer, BUFFER_SIZE);        length = in.gcount();        if (length > 0)        {            update(buffer, length);        }    }    in.close();}


*所述实例,并不是示例代码中那样标准的适配器模式。当然可以进行改写,但我认为完全没有必要。设计模式的初衷就是使代码更为美观、高效。

 

 

【源码下载】

1 http://download.csdn.net/detail/tandesir/4490759

2 Qt设计模式1-8测试源码:http://download.csdn.net/detail/tandesir/4984275
 声明:该源码仅供学习交流,勿用于商业目的。

 

 

转载请标明出处,仅供学习交流,勿用于商业目的

Copyright @ http://blog.csdn.net/tandesir

 

 


 

 


 

 

原创粉丝点击