设计模式-03-结构型模式详解

承接上一篇博客设计模式-02-创建型模式详解,本篇讨论结构型模式的相关内容

一.适配器模式

双方都不适合修改的时候,可以考虑使用适配器模式

设计模式-03-结构型模式详解_第1张图片

代码举例:

//例一
#include 
using namespace std;

class Target
{
public:
    virtual void Request()
    {
        cout<<"普通的请求"<class Adaptee
{
public:
    void SpecificalRequest()
    {
        cout<<"特殊请求"<class Adapter :public  Target
{
private:
    Adaptee* ada;
public:
    virtual void Request()
    {
        ada->SpecificalRequest();
        Target::Request();
    }
    Adapter()
    {
        ada=new Adaptee();
    }
    ~Adapter()
    {
        delete ada;
    }
};

//客户端:
int main()
{
    Adapter * ada=new Adapter();
    ada->Request();
    delete ada;
    return 0;
}
//例二
#include 
#include 
using namespace std;

class Player
{
protected:
    string name;
public:
    Player(string strName) { name = strName; }
    virtual void Attack()=0;
    virtual void Defense()=0;
};

class Forwards : public Player
{
public:
    Forwards(string strName):Player(strName){}
public:
    virtual void Attack()
    {
        cout<"前锋进攻"<virtual void Defense()
    {
        cout<"前锋防守"<public Player
{
public:
    Center(string strName):Player(strName){}
public:
    virtual void Attack()
    {
        cout<"中场进攻"<virtual void Defense()
    {
        cout<"中场防守"<//为中场翻译
class TransLater: public Player
{
private:
    Center *player;
public:
    TransLater(string strName):Player(strName)
    {
        player = new Center(strName);
    }
    virtual void Attack()
    {
        player->Attack();
    }
    virtual void Defense()
    {
        player->Defense();
    }
};

//客户端
int main()
{
    Player *p=new TransLater("小李");
    p->Attack();
    return 0;
}

二.桥接模式

将抽象部分与实现部分分离,使它们可以独立变化。
这里说的意思不是让抽象基类与具体类分离,而是现实系统可能有多角度分类,每一种分类都有可能变化,那么把这种多角度分离出来让它们独立变化,减少它们之间的耦合性,即如果继承不能实现“开放-封闭原则”的话,就应该考虑用桥接模式。

设计模式-03-结构型模式详解_第2张图片

代码举例:

#include 
#include 
#include 
using namespace std;

//手机软件
class HandsetSoft
{
public:
    virtual void Run()=0;
};

//游戏软件
class HandsetGame : public HandsetSoft
{
public:
    virtual void Run()
    {
        cout<<"运行手机游戏"<//通讯录软件
class HandSetAddressList : public HandsetSoft
{
public:
    virtual void Run()
    {
        cout<<"手机通讯录"<//手机品牌
class HandsetBrand
{
protected:
    HandsetSoft* m_soft;
public:
    void SetHandsetSoft(HandsetSoft* temp)
    {
        m_soft = temp;
    }
    virtual void Run()=0;
};

//M品牌
class HandsetBrandM : public HandsetBrand
{
public:
    virtual void Run()
    {
        m_soft->Run();
    }
};

//N品牌
class HandsetBrandN : public HandsetBrand
{
public:
    virtual void Run()
    {
        m_soft->Run();
    }
};

//客户端
int main()
{
    HandsetBrand *brand;
    brand = new HandsetBrandM();
    brand->SetHandsetSoft(new HandsetGame());
    brand->Run();
    brand->SetHandsetSoft(new HandSetAddressList());
    brand->Run();

    return 0;
}

三.组合模式

整体和部分可以被一致对待(如WORD中复制一个文字、一段文字、一篇文章都是一样的操作)

设计模式-03-结构型模式详解_第3张图片

代码举例:

#include 
#include 
#include 
using namespace std;

class Component
{
public:
    string m_strName;
    Component(string strName)
    {
        m_strName = strName;
    }
    virtual void Add(Component* com)=0;
    virtual void Display(int nDepth)=0;
};

class Leaf : public Component
{
public:
    Leaf(string strName): Component(strName){}

    virtual void Add(Component* com)
    {
        cout<<"leaf can't add"<virtual void Display(int nDepth)
    {
        string strtemp;
        for(int i=0; i < nDepth; i++)
        {
            strtemp+="-";
        }
        strtemp += m_strName;
        cout<class Composite : public Component
{
private:
    vector m_component;
public:
    Composite(string strName) : Component(strName){}

    virtual void Add(Component* com)
    {
        m_component.push_back(com);
    }

    virtual void Display(int nDepth)
    {
        string strtemp;
        for(int i=0; i < nDepth; i++)
        {
            strtemp+="-";
        }
        strtemp += m_strName;
        cout<vector::iterator p=m_component.begin();
        while (p!=m_component.end())
        {
            (*p)->Display(nDepth+2); 
            p++;
        }
    }

};

//客户端
#include "Model.h"

int main()
{
    Composite* p=new Composite("小王");
    p->Add(new Leaf("小李"));
    p->Add(new Leaf("小赵"));

    Composite* p1 = new Composite("小小五");
    p1->Add(new Leaf("大三"));

    p->Add(p1);
    p->Display(1);
    return 0;
}

四.装饰器模式

动态地给一个对象添加一些额外的职责(不重要的功能,只是偶然一次要执行),就增加功能来说,装饰模式比生成子类更为灵活。建造过程不稳定,按正确的顺序串联起来进行控制。
当你向旧的类中添加新代码时,一般是为了添加核心职责或主要行为。而当需要加入的仅仅是一些特定情况下才会执行的特定的功能时(简单点就是不是核心应用的功能),就会增加类的复杂度。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

设计模式-03-结构型模式详解_第4张图片

代码举例:

#include 
#include 
using namespace std;
//人
class Person
{
private:
    string m_strName;
public:
    Person(string strName)
    {
        m_strName=strName;
    }
    Person(){}
    virtual void Show()
    {
        cout<<"装扮的是:"<//装饰类
class Finery :public Person
{
protected:
    Person* m_component;
public:
    void Decorate(Person* component)
    {
        m_component=component;
    }
    virtual void Show()
    {
           m_component->Show();
    }
};
//T恤
class TShirts: public Finery
{
public:
    virtual void Show()
    {
        cout<<"T Shirts"<Show();
    }
};
//裤子
class BigTrouser :public  Finery
{
public:
    virtual void Show()
    {
        cout<<" Big Trouser"<Show();
    }
};

//客户端
int main()
{
    Person *p=new Person("小李");
    BigTrouser *bt=new BigTrouser();
    TShirts *ts=new TShirts();

    bt->Decorate(p);
    ts->Decorate(bt);
    ts->Show();
    return 0;
}

五.外观模式

为子系统的一组接口提供一个一致的界面。使用户使用起来更加方便。

设计模式-03-结构型模式详解_第5张图片

代码举例:

#include
#include 
using namespace std;

class SubSysOne
{
public:
    void MethodOne()
    {
        cout<<"方法一"<class SubSysTwo
{
public:
    void MethodTwo()
    {
        cout<<"方法二"<class SubSysThree
{
public:
    void MethodThree()
    {
        cout<<"方法三"<//外观类
class Facade
{
private:
    SubSysOne* sub1;
    SubSysTwo* sub2;
    SubSysThree* sub3;
public:
    Facade()
    {
        sub1 = new SubSysOne();
        sub2 = new SubSysTwo();
        sub3 = new SubSysThree();
    }
    ~Facade()
    {
        delete sub1;
        delete sub2;
        delete sub3;
    }

    void FacadeMethod()
    {
        sub1->MethodOne();
        sub2->MethodTwo();
        sub3->MethodThree();
    }
};

//客户端
int main()
{
    Facade* test = new Facade();
    test->FacadeMethod();
    return 0;
}

六.享元模式

运用共享技术有效地支持大量细粒度的对象(对于C++来说就是共用一个内存块啦,对象指针指向同一个地方)。
如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销就应该考虑使用。
还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用较少的共享对象取代多组对象,此时可以考虑使用享元。

设计模式-03-结构型模式详解_第6张图片

代码举例:

#include 
#include 
#include 
using namespace std;

//抽象的网站
class WebSite
{
public:
    virtual void Use()=0;
};

//具体的共享网站
class ConcreteWebSite : public WebSite
{
private:
    string name;
public:
    ConcreteWebSite(string strName)
    {
        name = strName;
    }
    virtual void Use()
    {
        cout<<"网站分类:"<//不共享的网站
class UnShareWebSite : public WebSite
{
private:
    string name;
public:
    UnShareWebSite(string strName)
    {
        name = strName;
    }
    virtual void Use()
    {
        cout<<"不共享的网站:"<//网站工厂类,用于存放共享的WebSite对象
class WebFactory
{
private:
    vector websites;
public:
    WebSite* GetWeb()
    {
        vector::iterator p = websites.begin();
        return *p;
    }
    WebFactory()
    {
        websites.push_back(new ConcreteWebSite("测试"));
    }
};

//客户端
int main()
{
    WebFactory* f= new WebFactory();
    WebSite* ws= f->GetWeb();
    ws->Use();

    WebSite* ws2 = f->GetWeb();
    ws2->Use();

    //不共享的类
    WebSite* ws3 = new UnShareWebSite("测试");
    ws3->Use();
    return 0;
}

七.代理模式

远程代理:可以隐藏一个对象在不同地址空间的事实
虚拟代理:通过代理来存放需要很长时间实例化的对象
安全代理:用来控制真实对象的访问权限
智能引用:当调用真实对象时,代理处理另外一些事

设计模式-03-结构型模式详解_第7张图片

代码举例:

#include 
#include 
using namespace std;
//定义接口
class Interface
{
public:
    virtual void Request()=0;
};
//真实类
class RealClass : public Interface
{
public:
    virtual void Request()
    {
        cout<<"真实的请求"<//代理类
class ProxyClass : public Interface
{
private:
    RealClass* m_realClass;
public:
    virtual void Request()
    {
        m_realClass= new RealClass();
        m_realClass->Request();
        delete m_realClass;
    }
};

客户端:
int main()
{
    ProxyClass* test=new ProxyClass();
    test->Request();
    return 0;
}

你可能感兴趣的:(算法/数据结构)