设计模式(三)

1.责任链模式

避免将一个请求的发送者和接收者耦合在一起,让多个对象都有机会处理请求。将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止。

链上的每一个对象都是请求的处理者,客户端要做的仅仅是发送请求,不需要关心请求的处理细节过程。

职责链模式将请求者和请求的接收者解耦。

以下以“副经理和经理处理资金”为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<iostream>
#include<string>
#include<vector>

// 请求
class Fund
{
public:
    Fund(int account)
    {
        this->account = account;
    }
    int GetAccount()const
    {
        return account;
    }
private:
    int account;
};

// 抽象处理者
class Approver
{
public:
    Approver(){}
    virtual ~Approver(){}

    // 设置责任链的上级
    void setSuperior(Approver *iSuperior)
    {
        this->superior = iSuperior;
    }

    // 处理请求
    virtual void handleRequest(Fund*) = 0;

protected:
    // 处理者的“上级”,此处较像链表结构
    Approver *superior;
};

// 具体处理者
class ViceManager:public Approver
{
public:
    ViceManager(){}
    void handleRequest(Fund* fund)
    {
        if(fund->GetAccount()<100)
        {
            std::cout<<"The fund has been disposed by vice manager,$"<<fund->GetAccount()<<std::endl;
        }
        else
        {
            std::cout<<"Deliver to manager"<<std::endl;
            superior->handleRequest(fund);
        }
    }
};

class Manager:public Approver
{
public:
    Manager(){}
    void handleRequest(Fund* fund)
    {
        std::cout<<"The fund has been disposed by manager,$"<<fund->GetAccount()<<std::endl;
    }
};

int main()
{
    Approver *viceManager,*manager;
    viceManager = new ViceManager();
    manager = new Manager();

    // 建立责任链,注意要遵循一定的逻辑顺序
    viceManager->setSuperior(manager);

    // 统一委派给低层处理
    Fund *fund = new Fund(5);
    viceManager->handleRequest(fund);
    std::cout<<std::endl;

    fund = new Fund(500);
    viceManager->handleRequest(fund);

    delete viceManager;
    delete manager;
    delete fund;
}
1
2
3
4
5
6
结果:

The fund has been disposed by vice manager,$5

Deliver to manager
The fund has been disposed by manager,$500

2.命令模式

定义

将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化。

内含抽象命令类,具体命令类,调用者和接收者。

以下以“控制电视和空调的遥控器”为例:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include<iostream>
#include<string>

// 接收者
class TV
{
public:
    TV ()
    {
        isOpen = false;
    }
    void on()
    {
        isOpen = true;
        std::cout<<"TV on"<<std::endl;
    }
    void off()
    {
        isOpen = false;
        std::cout<<"TV off"<<std::endl;
    }
    bool getState()
    {
        return isOpen;
    }
private:
    bool isOpen;
};

// 接收者
class AC
{
public:
    AC ()
    {
        isOpen = false;
    }
    void on()
    {
        isOpen = true;
        std::cout<<"AC on"<<std::endl;
    }
    void off()
    {
        isOpen = false;
        std::cout<<"AC off"<<std::endl;
    }
    bool getState()
    {
        return isOpen;
    }
private:
    bool isOpen;
};

// 抽象命令
class Command
{
public:
    Command(){}
    virtual ~Command(){}
    virtual void execute() = 0;
};

// 具体命令
class TVCommand:public Command
{
public:
    TVCommand()
    {
        tv = new TV();
    }
    ~TVCommand()
    {
        delete tv;
    }
    void execute() override
    {
        if(tv->getState())
        {
            tv->off();
        }
        else
        {
            tv->on();
        }
    }
private:
    TV *tv;
};

// 具体命令
class ACCommand:public Command
{
public:
    ACCommand()
    {
        ac = new AC();
    }
    ~ACCommand()
    {
        delete ac;
    }
    void execute() override
    {
        if(ac->getState())
        {
            ac->off();
        }
        else
        {
            ac->on();
        }
    }
private:
    AC *ac;
};

// 调用者
class RemoteControl
{
public:
    RemoteControl(){}
    void set(Command *command)
    {
        this->command = command;
    }
    void execute()
    {
        command->execute();
    }
private:
    Command *command;
};

int main()
{
    RemoteControl *remoteControl = new RemoteControl();
    Command *tvCmd = new TVCommand();
    remoteControl->set(tvCmd);
    remoteControl->execute();
    remoteControl->execute();
}

结果:

TV on TV off

3.迭代器模式

定义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。通过引入迭代器,可以将数据的遍历功能从聚合对象中分离出来,这样一来,聚合对象只需负责存储数据,而迭代器对象负责遍历数据。

包含抽象迭代器、具体迭代器、抽象容器、具体容器。

以下以“CD机”为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<iostream>
#include<string>
#include<vector>

class Iterator;
// 容器类
class CD
{
public:
    CD(std::vector<std::string> CDlist)
    {
        this->CDlist = CDlist;
    }
    void play(int i)
    {
        std::cout<<CDlist[i]<<std::endl;
    }
    int getLen()
    {
        return CDlist.size();
    }
private:
    std::vector<std::string> CDlist;
};

// 迭代器类
class Iterator
{
public:
    Iterator(){}
    void set(CD* cd)
    {
        this->cd = cd;
        this->len = cd->getLen();
    }
    void first()
    {
        cursor = 0;
    }
    void last()
    {
        cursor = len - 1;
    }
    void next()
    {
        cursor++;
    }
    void play()
    {
        cd->play(cursor);
    }

private:
    int cursor;
    int len;
    CD* cd;
};

int main()
{
    std::vector<std::string> CDlist = { "lost rivers","bad apple","the new island" };
    CD *cd = new CD(CDlist);
    Iterator *it = new Iterator();
    it->set(cd);

    it->first();
    it->play();
    it->next();
    it->play();
    it->last();
    it->play();

    delete cd;
    delete it;
}

结果:

lost rivers bad apple the new island

4.中介者模式

定义

定义一个对象来封装一系列对象的交互。中介者模式使各个对象之间不需要显示地相互引用,从而使其耦合松散,而且用户可以独立地改变它们之间的交互。

通过中介者,对象之间的多对多关系就简化了相对更简单的一对多关系。中介者在结构上起中转作用,在行为上起协调作用。

包含抽象中介者、具体中介者、抽象同事类、具体同事类。

以下以“二手车平台中间商”为例:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <iostream>
#include <string>
#include <vector>

enum class PersonType
{
    CUSTOMER,
    MERCHANT
};

class Person;

class Mediator
{
public:
    Mediator(){}
    virtual ~Mediator(){}
    virtual void operation(Person*) = 0;
    virtual void registerMethod(Person*) = 0;
};

// 抽象同事类
class Person
{
public:
    Person(){}
    virtual ~Person(){}
    PersonType getType()
    {
        return type;
    }
    void setMediator(Mediator* mediator)
    {
        this->mediator = mediator;
    }
    virtual void ask() = 0;
    virtual void answer() = 0;
protected:
    PersonType type;
    Mediator* mediator;
};

class Merchant:public Person
{
public:
    Merchant(std::string name, int price)
    {
        this->name = name;
        this->price = price;
        this->type = PersonType::MERCHANT;
    }

    void ask()override
    {
        std::cout<<"all customer info: "<<std::endl;
        this->mediator->operation(this);
    }
    void answer()override
    {
        std::cout<<"name: "<<name<<" price: "<<price<<std::endl;
    }
private:
    std::string name;
    int price;
};

class Customer:public Person
{
public:
    Customer(std::string name)
    {
        this->name = name;
        this->type = PersonType::CUSTOMER;
    }
    void ask()override
    {
        std::cout<<"all merchant info: "<<std::endl;
        this->mediator->operation(this);
    }
    void answer()override
    {
        std::cout<<"name: "<<name<<std::endl;
    }
private:
    std::string name;
};

class ConcreteMediator:public Mediator
{
public:
    ConcreteMediator(){}
    void registerMethod(Person *person) override
    {
        if(person->getType() == PersonType::CUSTOMER)
        {
            customerList.push_back((Customer*)person);
        }
        else if(person->getType() == PersonType::MERCHANT)
        {
            merchantList.push_back((Merchant*)person);
        }
    }
    void operation(Person* person) override
    {
        if(person->getType() == PersonType::CUSTOMER)
        {
            for(int i = 0;i<merchantList.size();i++)
            {
                merchantList[i]->answer();
            }
        }
        else if(person->getType() == PersonType::MERCHANT)
        {
            for(int i = 0;i<customerList.size();i++)
            {
                customerList[i]->answer();
            }
        }
    }
private:
    std::vector<Merchant*> merchantList;
    std::vector<Customer*> customerList;
};

int main()
{
    Mediator *mediator = new ConcreteMediator();

    Person *merchant1 = new Merchant("foo company",1000);
    Person *merchant2 = new Merchant("bar company",500);

    merchant1->setMediator(mediator);
    merchant2->setMediator(mediator);

    Person *customer1 = new Customer("foo");
    Person *customer2 = new Customer("bar");

    customer1->setMediator(mediator);
    customer2->setMediator(mediator);

    mediator->registerMethod(merchant1);
    mediator->registerMethod(merchant2);
    mediator->registerMethod(customer1);
    mediator->registerMethod(customer2);

    merchant1->ask();
    customer2->ask();

    delete mediator;
    delete merchant1;
    delete merchant2;
    delete customer1;
    delete customer2;
}

结果:

all customer info: name: foo name: bar all merchant info: name: foo company price: 1000 name: bar company price: 500

5.备忘录模式

定义

在不破坏封装的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

包含原发器、备忘录和管理者。

以下以“自制git”为例:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <iostream>
#include <string>
#include <vector>

// 备忘录
class Memento
{
public:
    Memento() {}
    Memento(int version, std::string date, std::string message)
    {
        this->version = version;
        this->date = date;
        this->message = message;
    }
    void setVersion(int version)
    {
        this->version = version;
    }
    void setDate(std::string date)
    {
        this->date = date;
    }
    void setMessage(std::string message)
    {
        this->message = message;
    }
    int getVersion()
    {
        return version;
    }
    std::string getDate()
    {
        return date;
    }
    std::string getMessage()
    {
        return message;
    }

private:
    int version;
    std::string date;
    std::string message;
};

// 原生器
class Originator
{
public:
    Originator(int version, std::string date, std::string message)
    {
        this->version = version;
        this->date = date;
        this->message = message;
    }
    void setVersion(int version)
    {
        this->version = version;
    }
    void setDate(std::string date)
    {
        this->date = date;
    }
    void setMessage(std::string message)
    {
        this->message = message;
    }
    int getVersion()
    {
        return version;
    }
    std::string getDate()
    {
        return date;
    }
    std::string getMessage()
    {
        return message;
    }
    Memento *save()
    {
        return new Memento(version, date, message);
    }
    void reset(Memento* memento)
    {
        setVersion(memento->getVersion());
        setDate(memento->getDate());
        setMessage(memento->getMessage());
    }

private:
    int version;
    std::string date;
    std::string message;
};

// 管理者
class Git
{
public:
    Git(Originator* originator) 
    {
        this->originator = originator;
    }
    void commit()
    {
        Memento *m = originator->save();
        std::cout << "commit: " << m->getVersion() << ' ' << m->getDate() << ' ' << m->getMessage() << std::endl;
        mementoList.push_back(m);
    }
    void reset(int index)
    {
        mementoList.erase(mementoList.begin() + mementoList.size() - index, mementoList.end());
        originator->reset(mementoList[mementoList.size() - 1]);
    }
    void log()
    {
        for (int i = 0; i < mementoList.size(); i++)
        {
            std::cout << mementoList[i]->getVersion() << ' ' << mementoList[i]->getDate() << ' ' << mementoList[i]->getMessage() << std::endl;
        }
    }

private:
    std::vector<Memento *> mementoList;
    Originator* originator;
};

int main()
{
    Originator* originator = new Originator(1,"2021-08-27","Initial Commit");
    Git *git = new Git(originator);
    git->commit();

    originator->setVersion(2);
    originator->setDate("2021-08-28");
    originator->setMessage("add a function");
    git->commit();

    originator->setVersion(3);
    originator->setDate("2021-08-29");
    originator->setMessage("fix a bug");
    git->commit();

    std::cout<<std::endl;
    git->log();
    git->reset(1);

    std::cout<<std::endl;
    git->log();
}

结果:

commit: 1 2021-08-27 Initial Commit commit: 2 2021-08-28 add a function commit: 3 2021-08-29 fix a bug

1 2021-08-27 Initial Commit 2 2021-08-28 add a function 3 2021-08-29 fix a bug

1 2021-08-27 Initial Commit 2 2021-08-28 add a function

6.观察者模式

定义

定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。

在该模式中,发生改变的对象称为“观察目标”,被通知的对象称为“观察者”。一个观察目标可以有很多个观察者。

观察者和观察目标相互引用。

以下以“软件的发布者与订阅者”为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include<iostream>
#include<string>
#include<list>

// 抽象观察者
class Observer
{
public:
    virtual void update(std::string info) = 0;
    virtual ~Observer(){}
};

// 抽象目标
class Subject
{
public:
    virtual void attach(Observer* obs) = 0;
    virtual void detach(Observer* obs) = 0;
    // 声明通知方法
    virtual void notify() = 0;
    virtual void CreateMessage(std::string) = 0;
    virtual ~Subject(){}
protected:
    // 观察者列表
    std::list<Observer*>obsList;
    std::string info;
};

// 具体观察者
class Subscriber:public Observer
{
public:
    Subscriber(Subject *s,std::string name):subject(s),name(name)
    {
        this->subject->attach(this);
    }
    void update(std::string info)override
    {
        this->info = info;
        std::cout<<name<<':'<<"a new message->"<<this->info<<std::endl;
    }
private:
    Subject* subject;
    std::string name;
    std::string info;
};

// 具体目标
class Publisher :public Subject
{
public:
    void attach(Observer* obs) override
    {
        obsList.push_back(obs);
    }
    void detach(Observer* obs) override
    {
        obsList.remove(obs);
    }
    void CreateMessage(std::string info) override
    {
        this->info = info;
        std::cout << "A new info was released:" << info << std::endl;
    }
    // 实现通知方法
    void notify()override
    {
        for (auto item:obsList)
        {
            item->update(info);
        }
    }
};

int main()
{
    Subject  *publisher = new Publisher();
    Observer *subscriber1 = new Subscriber(publisher,"Alice");
    Observer *subscriber2 = new Subscriber(publisher,"Bob");
    
    publisher->CreateMessage("a new edition has been published");
    publisher->notify();

    std::cout<<std::endl;
    Observer *subscriber3 = new Subscriber(publisher,"Carol");
    publisher->CreateMessage("a bug has been fixed");
    publisher->notify();
    return 0;
}

结果:

A new info was released:a new edition has been published Alice:a new message->a new edition has been published Bob:a new message->a new edition has been published

A new info was released:a bug has been fixed Alice:a new message->a bug has been fixed Bob:a new message->a bug has been fixed Carol:a new message->a bug has been fixed

7.状态模式

定义

状态模式将一个对象的状态从对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化。

包含上下文类、抽象状态类和具体状态类。

以下以“斗地主身份设置”为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>

class Context;

// 抽象状态类
class State
{
protected:
    Context *context;
public:
    State(){}
    virtual ~State(){}
    void set(Context* context)
    {
        this->context = context;
    }
    virtual void handle() = 0;
};

// 具体状态类
class ConcreteState1 :public State
{
public:
    void handle()override
    {
        std::cout<<"Farmer: I have 17 cards"<<std::endl;
    }
};

// 具体状态类
class ConcreteState2 :public State
{
public:
    void handle()override
    {
        std::cout<<"Landlord: I have 20 cards"<<std::endl;
    }
};

// 上下文类
class Context
{
private:
    State *state;
public:
    Context(){}
    void set(State* state)
    {
        this->state = state;
    }
    void request()
    {
        this->state->handle();
    }
};

int main()
{
    Context *context = new Context();
    State* state= new ConcreteState1();
    context->set(state);
    context->request();

    state = new ConcreteState2();
    context->set(state);
    context->request();

    delete context;
    delete state;
}

结果:

Farmer: I have 17 cards Landlord: I have 20 cards

8.解释器模式

定义

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。

包含抽象表达式、终结符表达式、非终结符表达式、上下文类。

以下以“文字加减法处理”为例:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
#include<iostream>
#include<string>
#include<regex>

std::regex re("(.*)\\ (.*)\\ (.*)");
std::smatch base_match;

// 抽象表达式
class AbstractExpression
{
public:
    AbstractExpression(){}
    virtual ~AbstractExpression(){}
    virtual char interpret() = 0;
};

// 具体表达式:数值
class Value:public AbstractExpression
{
public:
    Value(){}
    Value(std::string value)
    {
        this->value = std::atoi(value.c_str());
    }
    char interpret()override
    {
        return value;
    }

private:
    int value;
};

// 具体表达式:运算符
class Operator:public AbstractExpression
{
public:
    Operator(){}
    Operator(std::string op)
    {
        this->op = op;
    }
    char interpret()override
    {
        if(op=="plus")
        {
            return '+';
        }
        else if(op=="minus")
        {
            return '-';
        }
        return 0;
    }

private:
    std::string op;
};

// 上下文类
class Context
{
public:
    Context(){}
    void set(std::string input)
    {
        this->input = input;
    }
    void handle()
    {
        AbstractExpression *left;
        AbstractExpression *right;
        AbstractExpression *op;
        if (std::regex_match(input, base_match, re))
        {
            left = new Value(base_match[1].str());
            op = new Operator(base_match[2].str());
            right = new Value(base_match[3].str());

            if(op->interpret() == '+')
            {
                result = left->interpret()+right->interpret();
            }
            else if(op->interpret() == '-')
            {
                result = left->interpret()-right->interpret();
            }
            std::cout<<result<<std::endl;

            delete left;
            delete op;
            delete right;
        }
    }
private:
    std::string input;
    int result;
};

int main()
{
    Context *context = new Context();
    std::string input1 = "1 plus 1";
    std::string input2 = "4 minus 5";
    context->set(input1);
    context->handle();
    context->set(input2);
    context->handle();
    delete context;
}

结果:

2 -1

9.策略模式

定义

定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法可以独立于使用它的客户而变化。

包含上下文类、抽象策略类、具体策略类。

以下以“面向对象的加减法”为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<iostream>

// 抽象策略类
class Strategy
{
public:
    Strategy(){}
    virtual ~Strategy(){}
    virtual int calculate(int a,int b)=0;
};

// 具体策略类
class Plus:public Strategy
{
public:
    Plus(){}
    int calculate(int a,int b)override
    {
        return a+b;
    }
};

// 具体策略类
class Minus:public Strategy
{
public:
    Minus(){}
    int calculate(int a,int b)override
    {
        return a-b;
    }
};

// 上下文类
class Context
{
public:
    Context(){}
    Context(int a,int b)
    {
        this->a = a;
        this->b = b;
    }
    void set(Strategy* strategy,int a,int b)
    {
        this->strategy = strategy;
        this->a = a;
        this->b = b;
    }
    void getResulet()
    {
        std::cout<<strategy->calculate(a,b)<<std::endl;
    }
private:
    int a,b;
    Strategy* strategy;
};

int main()
{
    Context *context = new Context();
    Strategy* strategy = new Plus();
    context->set(strategy,1,2);
    context->getResulet();

    strategy = new Minus();
    context->set(strategy,4,6);
    context->getResulet();

    delete context;
    delete strategy;
}

结果:

3 -2

10.模板方法模式

定义

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法基于继承与派生。

以下以“Linux的GUI发行版”为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string>

// 基类
class Linux
{
public:
    Linux() {}
    virtual ~Linux() {}
    // 公共方法
    void Kernel()
    {
        std::cout << "Linux kernel load successfully." << std::endl;
    }
    virtual void GUI() = 0;
    void play()
    {
        Kernel();
        GUI();
    }

private:
    std::string terminal;
};

// 派生类
class CentOS : public Linux
{
public:
    CentOS() {}
    void GUI() override
    {
        std::cout << "Using: CentOS style GUI" << std::endl;
    }
};

// 派生类
class Ubuntu : public Linux
{
public:
    Ubuntu() {}
    void GUI() override
    {
        std::cout << "Using: Ubuntu style GUI" << std::endl;
    }
};

int main()
{
    Linux *linux = new Ubuntu();
    linux->play();

    linux = new CentOS();
    linux->play();

    delete linux;
}

结果:

Linux kernel load successfully. Using: Ubuntu style GUI Linux kernel load successfully. Using: CentOS style GUI

Built with Hugo
Theme Stack designed by Jimmy
visitors: total visits: time(s) reads: time(s)