首页前端开发HTML设计模式-适配器模式(Apater)

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

时间2024-01-26 16:02:03发布访客分类HTML浏览322
导读:收集整理的这篇文章主要介绍了设计模式-适配器模式(Apater ,觉得挺不错的,现在分享给大家,也给大家做个参考。 【描述】适配器模式将某个对象的接口适配为另一个对象所期望的接口。 【UML图】 图1 Apater模式 (1 已知Ap...
收集整理的这篇文章主要介绍了设计模式-适配器模式(Apater),觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

#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

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

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

【运行结果】

[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]
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 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);
}
其余接口(公有的)采用适配器模式就可以了。

[html]
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();  
}  

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

 作者:tandesir
 

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

ClassconstHTMLRestStatethis

若转载请注明出处: 设计模式-适配器模式(Apater)
本文地址: https://pptw.com/jishu/586974.html
HTML5新增的form属性简介 完善:HTML5表单新特征简介与举例

游客 回复需填写必要信息