Head First 设计模式 Design Pattern 9-10 Iterator and Composite, State

Section 9 迭代器与组合模式 Iterator and Composite

对象超集合 super collection 聚合 aggregate

>注意remove()在多线程中的状况

 


迭代器模式 提供一种方法顺序访问一个聚合对象中的各个元素, 不暴露其内部的表示.

>内部迭代器, 外部迭代器, 迭代器的数据结构可以是有序的, 无序的, 重复的.

设计原则 一个类应该只有一个引起变化的原因. (单一责任)

>类的每个责任都有改变的潜在区域. 超过一个责任, 意味着超过一个改变的区域.  避免类内的改变, 控制类的维护复杂度.

>内聚 conhesion 度量一个类或模块紧密地达到单一目的或责任. 高内聚: 类设计成只支持一组相关的功能; 低内聚: 类被设计成支持一组不相关的功能.

>策略-封装可互换的行为, 使用委托决定使用哪个; 适配器-改变一个或多个类的接口; 迭代器-提供一个方式来遍历集合, 无须暴露集合的实现; 外观-简化一群类的接口; 

组合-客户可以将对象的集合以及个别的对象一视同仁.; 观察者-当某个状态改变时, 允许一群对象被通知到.

组合模式 Composite Pattern 允许将对象组合成树形结构来表现'整体/部分'层次结构. 组合能让客户以一致的方式处理个别对象以及对象组合.

组合模式用树形方式创建对象结构, 包含了组合和个别对象. 可以把相同的操作应用在组合和个别对象上.

>Menu是节点, MenuItem是叶节点;


>组合模式以单一责任设计原则换取透明性(transparency), 元素是组合还是叶节点对客户是透明的.

>Java for/in语句遍历: for (Object obj : collection) 递归

Summary

>要点 迭代器允许访问聚合的元素, 不需要暴露内部结构; 迭代器将遍历聚合的工作封装进一个对象中; 依赖聚合提供遍历; 迭代器提供一个公用的接口来遍历聚合项, 编码使用

聚合的项时, 可以使用多态机制; 尽量一个类只分配一个责任; 组合模式提供一个结构, 可同时包容个别和组合对象, 一视同仁; 组合结构内的任意对象称为组件, 可以是组合, 也

可以是节点; 根据需要平衡透明性和安全性来选择不同的方式设计组合模式.

Composite/Components, Iteration/Implementation, Recursion, FactoryMethod, Leaf, SingleResponseibility, HashTable, Dessert

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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//***********Iterator & Composite**********
class MenuItem;
class MenuComponent;
                                      
class IIterator
{
public:
    virtual bool hasNext()= 0;
    virtual MenuComponent* next() = 0; 
    virtual void remove() = 0;
};
                                      
class NullIterator : public IIterator
{
public:
    NullIterator() {};  
    virtual bool hasNext() {return false;}
    virtual MenuComponent* next() {return NULL;} 
    virtual void remove() {cout << "Unsupported" << endl;}
};
                                      
class MenuComponent
{
public:
    MenuComponent() {};
    virtual void add(MenuComponent* menuComponent) {cout << "Unsupported" << endl;}
    virtual void remove(MenuComponent* menuComponent) {cout << "Unsupported" << endl;}
    virtual MenuComponent* getChild(int i) {cout << "Unsupported" << endl;}
    virtual string getName() {cout << "Unsupported" << endl;}
    virtual double getPrice() {cout << "Unsupported" << endl;}
    virtual void print() {cout << "Unsupported" << endl;}
    virtual IIterator* createIterator() = 0;
};
                                      
class MenuItem : public MenuComponent
{
public:
    MenuItem(string name, double price) : msName(name), mdPrice(price) {}
    string getName() {return msName;}
    double getPrice() {return mdPrice;}
    void print();
    virtual IIterator* createIterator() {return new NullIterator();}
private:
    string msName;
    double mdPrice;
};
                                      
typedef vector<MenuComponent*> MENUCOMPONENTVEC;
class Menu : public MenuComponent
{
public:
    Menu(string name) : msName(name) {};
    virtual IIterator* createIterator();
    void add(MenuComponent* menuCom) {menuComVec.push_back(menuCom);}
    void remove(MenuComponent* menuCom);
    MenuComponent* getChild(int i) { menuComVec.at(i); }
    virtual string getName() {return msName;}
    void print();      
private:
    MENUCOMPONENTVEC menuComVec;
    string msName;
};
                                      
typedef vector<MenuItem*> MENUITEMVEC;
class PancakeHouseMenu : public Menu
{
public:
    PancakeHouseMenu();
    MENUITEMVEC getMenuItems(){ return menuIVec; }
    virtual IIterator* createIterator();
private:
    void addItem(string name, double price);
    MENUITEMVEC menuIVec;
};
                                      
class DinerMenu : public Menu
{
public:
    DinerMenu();
    ~DinerMenu();
    MenuItem** getMenuItems() { return menuItems; }
    int getSize() { return miNumOfItems;}
    virtual IIterator* createIterator();
private:
    void addItem(string name, double price);
    MenuItem** menuItems;
    int miNumOfItems;
};
                                      
typedef map<string, MenuItem*> MENUMAP;
class CafeMenu : public Menu
{
public:
    CafeMenu();
    MENUITEMVEC getMenuItems() { return menuVec;}
    virtual IIterator* createIterator();
private:
    void addItem(string name, double price);
    MENUMAP menuMap;
    MENUITEMVEC menuVec;
};
                                      
class DinerMenuIterator : public IIterator
{
public:
    DinerMenuIterator(MenuItem** items, int size) : miPosition(0)
    {
        menuItems = items;
        miSize = size;
    }
    virtual bool hasNext();
    virtual MenuItem* next();
    virtual void remove();
private:
    MenuItem** menuItems;
    int miPosition;
    int miSize;
};
                                      
class PancakeHouseMenuIterator : public IIterator
{
public:
    PancakeHouseMenuIterator(MENUITEMVEC vec)
    {
        menuIVec = vec;
        mIter = menuIVec.begin();
    }
    virtual bool hasNext();
    virtual MenuItem* next();
    virtual void remove();
private:
    MENUITEMVEC menuIVec;
    MENUITEMVEC::iterator mIter;
};
                                      
class CafeMenuIterator : public IIterator
{
public:
    CafeMenuIterator(MENUITEMVEC vec)
    {
        menuVec = vec;
        mIter = menuVec.begin();
    }
    virtual bool hasNext();
    virtual MenuItem* next();
    virtual void remove();
private:
    MENUITEMVEC menuVec;
    MENUITEMVEC::iterator mIter;
};
                                      
typedef vector<Menu*> MENUSVEC;
class Waitness
{
public:
    Waitness();
    void setMenuComponent(MenuComponent* menuCom)
    {menuComponent = menuCom;}
    void setPCMenu(Menu* menu);
    void setDinerMenu(Menu* menu);
    void setCafeMenu(Menu* menu);
    void addMenus(Menu* menu);
    void printMenu();
    void printMenu(IIterator* iter);
    void printMenus();
    void printMenuComponent();
    void removeMenuComponent();
private:
    Menu* mpPancakeMenu;
    Menu* mpDinerMenu;
    Menu* mpCafeMenu;
    MENUSVEC menusVec;
    MenuComponent* menuComponent;
};
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
//***********Iterator & Composite**********
void MenuItem::print()
{
    cout<<"------MenuItem------"<< endl;
    cout << "Name:"<<getName() << endl;
    cout << "Price:"<<getPrice() << endl;
}
                                      
IIterator* Menu::createIterator()
{
    return new NullIterator();
}
                                      
void Menu::remove(MenuComponent* menuCom)
{
    MENUCOMPONENTVEC::iterator iter = menuComVec.begin();
    for (; iter != menuComVec.end(); iter++)
    {
        MenuComponent* menuComToCompare = *iter;
        if (menuComToCompare == menuCom)
        {
            iter = menuComVec.erase(iter);
            return;
        }
    }
}
                                      
void Menu::print()
{
    cout<<"------Menu------"<< endl;
    cout << "Name:"<<getName() << endl;
    MENUCOMPONENTVEC::iterator iter = menuComVec.begin();
    for (; iter != menuComVec.end(); iter++)
    {
        MenuComponent* menuCom = *iter;
        menuCom->print();
    }    
}
                                      
const int MAX_ITEMS = 6;
PancakeHouseMenu::PancakeHouseMenu()
: Menu("PancakeHouse")
{
    addItem("Regular Pancake Breakfast", 15.90);
    addItem("BlueBerry Pancake", 18.90);
}
                                      
void PancakeHouseMenu::addItem(string name, double price)
{
    MenuItem *item = new MenuItem(name, price);
    menuIVec.push_back(item);
}
                                      
IIterator*  PancakeHouseMenu::createIterator()
{
    return new PancakeHouseMenuIterator(menuIVec);
}
                                      
DinerMenu::DinerMenu()
: Menu("Diner"),
  miNumOfItems(0)
{
    //*menuItems = new MenuItem[MAX_ITEMS; //wrong: runtime creating, terminate error, only for assign the value, not new
    menuItems = new MenuItem*[MAX_ITEMS];
    addItem("Soup of the day", 5.00);
    addItem("Hotdog", 8.00);
}
                                      
DinerMenu::~DinerMenu()
{
    delete[] menuItems;
}
                                      
void DinerMenu::addItem(string name, double price)
{
    MenuItem* item = new MenuItem(name, price);
    if (MAX_ITEMS > miNumOfItems)
    {
        menuItems[miNumOfItems] = item;
        miNumOfItems++;
    }
    else
        cout << "Menu is full, can't add more." << endl;
}
                                      
IIterator* DinerMenu::createIterator()
{
    return new DinerMenuIterator(menuItems, miNumOfItems);
}
                                      
CafeMenu::CafeMenu()
: Menu("Cafe")
{
    addItem("Soup of the day", 3.59);
    addItem("Cappuccino ", 1.99);
}
                                      
void CafeMenu::addItem(string name, double price)
{
    MenuItem* item = new MenuItem(name, price);
    menuMap.insert(pair<string,MenuItem*>(name,item));
    menuVec.push_back(item);
}
                                      
IIterator* CafeMenu::createIterator()
{
    return new CafeMenuIterator(menuVec);
}
                                      
bool DinerMenuIterator::hasNext()
{
    if(miPosition >= miSize ||
      menuItems[miPosition] == NULL)
        return false;
    else
        return true;           
}
                                      
MenuItem* DinerMenuIterator::next()
{
    MenuItem* item = menuItems[miPosition];
    miPosition++;
    return item;
}
                                      
void DinerMenuIterator::remove()
{
    if(miPosition <= 0)
    {
        cout << "Can't remove the item" << endl;
        return;
    }
    if(menuItems[miPosition - 1] != NULL)
    {
        for(int i = miPosition - 1 ; i < miSize - 1; i++)
        {
            menuItems[miPosition] = menuItems[miPosition + 1];
        }
        menuItems[miSize - 1] = NULL;
        miSize--;
    }
}
                                      
bool PancakeHouseMenuIterator::hasNext()
{
    if(mIter == menuIVec.end())
        return false;
    else
        return true;        
}
                                      
MenuItem* PancakeHouseMenuIterator::next()
{
    MenuItem* item = *mIter;
    mIter++;
    return item;
}
                                      
void PancakeHouseMenuIterator::remove()
{
    if(mIter == menuIVec.end())
    {
        cout << "Can't remove the item" << endl;
        return;
    }
    if (NULL != *mIter)
        mIter = menuIVec.erase(mIter);
}
                                      
bool CafeMenuIterator::hasNext()
{
    if(mIter == menuVec.end())
        return false;
    else
        return true
}
                                      
MenuItem* CafeMenuIterator::next()
{
    MenuItem* item = *mIter;
    mIter++;
    return item;
}
                                      
void CafeMenuIterator::remove()
{
    if (mIter == menuVec.end())
    {
        cout << "Can't remove the item" << endl;
        return;
    }
    if (NULL != *mIter)
       mIter = menuVec.erase(mIter);
}
                                      
void Waitness::printMenu()
{
    if (mpPancakeMenu != NULL)
    {
        MENUITEMVEC menuVec = dynamic_cast<PancakeHouseMenu*>(mpPancakeMenu)->getMenuItems();
        MENUITEMVEC::iterator menuIter = menuVec.begin();
        cout << "----MenuItem for PancakeHouse----" << endl;
        for (; menuIter != menuVec.end(); menuIter++)
        {
            MenuItem *item = *menuIter;
            cout << "name:" << item->getName();
            cout << " price:" << item->getPrice() << endl;
        }
        IIterator* iterPcake = mpPancakeMenu->createIterator();
        cout << "----MenuItem Iterator for PancakeHouse----" << endl;
        printMenu(iterPcake);  
    }
    if (mpPancakeMenu != NULL)
    {
        DinerMenu* dinerMenu = dynamic_cast<DinerMenu*>(mpDinerMenu);
        MenuItem** menuItems = dinerMenu->getMenuItems();
        cout << "----MenuItem  for Diner:----" << endl;
        for (int i = 0; i < dinerMenu->getSize(); i++)
        {
            MenuItem* item = menuItems[i];
            cout << "name:" << item->getName();
            cout << " price:" << item->getPrice() << endl;
        }
        IIterator* iterDiner = mpDinerMenu->createIterator();
        cout << "----MenuItem Iterator for Diner:----" << endl;
        printMenu(iterDiner);
    }
    if (mpCafeMenu != NULL)
    {
        MENUITEMVEC menuVec = dynamic_cast<CafeMenu*>(mpCafeMenu)->getMenuItems();
        MENUITEMVEC::iterator menuIter = menuVec.begin();
        cout << "----MenuItem for Cafe----" << endl;
        for (; menuIter != menuVec.end(); menuIter++)
        {
            MenuItem *item = *menuIter;
            cout << "name:" << item->getName();
            cout << " price:" << item->getPrice() << endl;
        }
        IIterator* iterCafe = mpCafeMenu->createIterator();
        cout << "----MenuItem Iterator for Cafe----" << endl;
        printMenu(iterCafe);  
    }
}
                                      
Waitness::Waitness()
: mpPancakeMenu(NULL), mpDinerMenu(NULL), mpCafeMenu(NULL)
{
}
                                      
void Waitness::setPCMenu(Menu* menu)
{
    mpPancakeMenu = menu;
}
                                      
void Waitness::setDinerMenu(Menu* menu)
{
    mpDinerMenu = menu;
}
                                      
void Waitness::setCafeMenu(Menu* menu)
{
    mpCafeMenu = menu;
}
                                      
void Waitness::printMenu(IIterator* iter)
{
    while(iter->hasNext())
    {
        iter->remove();//test for remove
        MenuComponent* item = iter->next();
        iter->remove();
        cout << "name:" << item->getName();
        cout << " price:" << item->getPrice() << endl;
    }
}
                                      
void Waitness::addMenus(Menu* menu)
{
    menusVec.push_back(menu);
}
                                      
void Waitness::printMenus()
{
    MENUSVEC::iterator menusIter = menusVec.begin();
    cout << "----Print all menus----" << endl;
    int count = 1;
    for (; menusIter != menusVec.end(); menusIter++)
    {
        Menu *menu = *menusIter;
        IIterator* iter = menu->createIterator();
        cout << "----MenuItem "<<count<<"----" << endl;
        printMenu(iter);  
        count++;
    }
}
                                      
void Waitness::printMenuComponent()
{
    cout << "----Print menu component----" << endl;
    menuComponent->print();
}
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
//Iterator & Composite
cout<<"******exapmle1 GET******"<<endl;
PancakeHouseMenu* pancakeMenu = new PancakeHouseMenu();
DinerMenu* dinerMenu = new DinerMenu();
CafeMenu* cafeMenu = new CafeMenu();
Waitness* waitness = new Waitness();
waitness->setPCMenu(pancakeMenu);
waitness->setDinerMenu(dinerMenu);
waitness->setCafeMenu(cafeMenu);
waitness->printMenu();
cout<<"******example2 Iterator******"<<endl;
waitness->addMenus(dinerMenu);
waitness->addMenus(cafeMenu);
waitness->printMenus();
cout<<"******example3 Component******"<<endl;
MenuComponent* pancakeMenu3 = new Menu("PancakeHouse");
MenuComponent* cafeMenu3 = new Menu("Cafe");
MenuComponent* allMenus = new Menu("All Menus");
allMenus->add(pancakeMenu3);
allMenus->add(cafeMenu3);
pancakeMenu3->add(new MenuItem("Pasta", 3.98));
pancakeMenu3->add(cafeMenu3);
cafeMenu3->add(new MenuItem("chocolate", 1.98));
waitness->setMenuComponent(allMenus);
waitness->printMenuComponent();

---Section 9 End---

Section 10 状态模式 State

策略模式-状态模式

>Common Skill 对对象内的状态建模, 创建一个实例对象来持有状态值, 在方法内实现条件代码处理不同状态. 

>将每个状态的行为局部化到自己的类中; 避免难以维护的If语句; 每个状态对修改关闭, Context对扩展开放; 创建容易理解的类结构

状态模式 允许对象在内部状态改变时改变它的行为, 对象看起来好像修改了它的类


>客户不了解状态的内部变化

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
//***********State**********
class GumballMachine;
             
class IState
{
public:
    virtual void insertQuarter() = 0;
    virtual void ejectQuarter() = 0;
    virtual void turnCrank() = 0;
    virtual void dispense() = 0;
};
         
class SoldState : public IState
{
public:
    SoldState(GumballMachine* gumballM) { mpGumballM = gumballM; }
    virtual void insertQuarter() {cout << "Already giving a ball" << endl;};
    virtual void ejectQuarter() {cout << "Already turned the crank" << endl;};
    virtual void turnCrank() {cout << "Turn twice doesn't get another ball" << endl;};
    virtual void dispense();
private:
    GumballMachine* mpGumballM;
};
         
class SoldOutState : public IState
{
public:
    SoldOutState(GumballMachine* gumballM) { mpGumballM = gumballM; }
    virtual void insertQuarter() {cout << "Out of balls" << endl;};
    virtual void ejectQuarter() {cout << "No quarter" << endl;};
    virtual void turnCrank() {cout << "Out of balls" << endl;};
    virtual void dispense() {cout << "Out of balls" << endl;};
private:
    GumballMachine* mpGumballM;
};
         
class NoQuarterState : public IState
{
public:
    NoQuarterState(GumballMachine* gumballM) { mpGumballM = gumballM; }
    virtual void insertQuarter();
    virtual void ejectQuarter() {cout << "Have not inserted a quarter" << endl;}
    virtual void turnCrank() {cout << "No quarter" << endl;}
    virtual void dispense() {cout << "Pay first" << endl;}
private:
    GumballMachine* mpGumballM;
};
         
class HasQuarterState : public IState
{
public:
    HasQuarterState(GumballMachine* gumballM);
    virtual void insertQuarter() {cout << "Can not insert another quarter" << endl;}
    virtual void ejectQuarter();
    virtual void turnCrank();
    virtual void dispense() {cout << "No gamball dispensed" << endl;};
private:
    GumballMachine* mpGumballM;
    int miRan;
};
         
class WinnerState : public IState
{
public:
    WinnerState(GumballMachine* gumballM) { mpGumballM = gumballM; }
    virtual void insertQuarter() {cout << "Already giving a ball" << endl;};
    virtual void ejectQuarter() {cout << "Already turned the crank" << endl;};
    virtual void turnCrank() {cout << "Turn twice doesn't get another ball" << endl;};
    virtual void dispense();
private:
    GumballMachine* mpGumballM;
};
         
class GumballMachine
{
public:
    GumballMachine(int iCount);
    void insertQuarter();
    void ejectQuarter();
    void turnCrank();
    void dispense();
    void releaseBall();
    int getCount() const;
    void setState(IState* state) { mpState = state; }
    IState* getSoldOutState() { return mpSoldOutState;}
    IState* getNoQuarterState() {return mpNoQuarterState;}
    IState* getHasQuarterState() { return mpHasQuarterState;}
    IState* getSoldState() { return mpSoldState;}
    IState* getWinnerState() { return mpWinnerState;}
private:
    IState* mpState;
    IState* mpSoldOutState;
    IState* mpNoQuarterState;
    IState* mpHasQuarterState;
    IState* mpSoldState;
    IState* mpWinnerState;
    int miCount;
};
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
//***********State**********
void NoQuarterState::insertQuarter()
{
    cout << "Inserted a quarter" << endl;
    mpGumballM->setState(mpGumballM->getHasQuarterState());
}
         
HasQuarterState::HasQuarterState(GumballMachine* gumballM)
{
    mpGumballM = gumballM;
    srand((int)time(0));
    miRan = rand()%MAX;
    cout << "random number" << miRan << endl;
}
                 
void HasQuarterState::ejectQuarter()
{
    cout << "Quarter returned" << endl;
    mpGumballM->setState(mpGumballM->getNoQuarterState());
}
         
void HasQuarterState::turnCrank()
{
    cout << "You turned..." << endl;
    if ( (miRan - 10) == 0 && mpGumballM->getCount() > 1)
        mpGumballM->setState(mpGumballM->getWinnerState());
    else
        mpGumballM->setState(mpGumballM->getSoldState());
}
         
void SoldState::dispense()
{
    mpGumballM->releaseBall();
    if (mpGumballM->getCount() == 0)
    {
        cout << "Out of balls" << endl;
        mpGumballM->setState(mpGumballM->getSoldOutState());
    }
    else
        mpGumballM->setState(mpGumballM->getNoQuarterState());
}
         
void WinnerState::dispense()
{
    cout << "Winner" << endl;
    mpGumballM->releaseBall();
    if (mpGumballM->getCount() == 0)
        mpGumballM->setState(mpGumballM->getSoldOutState());
    else
    {
        mpGumballM->releaseBall();
        if (mpGumballM->getCount() > 0)          
            mpGumballM->setState(mpGumballM->getNoQuarterState());
        else
        {
            cout<<"out of balls" << endl;
            mpGumballM->setState(mpGumballM->getSoldOutState());
        }
    }
}
         
GumballMachine::GumballMachine(int iCount)
{
    mpSoldOutState = new SoldOutState(this);
    mpNoQuarterState = new NoQuarterState(this);
    mpHasQuarterState = new HasQuarterState(this);
    mpSoldState = new SoldState(this);
    mpWinnerState = new WinnerState(this);
    if (iCount>0)
        mpState = mpNoQuarterState;
    miCount = iCount;
}
         
void GumballMachine::insertQuarter()
{
    mpState->insertQuarter();
}
         
void GumballMachine::ejectQuarter()
{
    mpState->ejectQuarter();
}
         
void GumballMachine::turnCrank()
{
    mpState->turnCrank();
    mpState->dispense();
}
         
void GumballMachine::dispense()
{   
}
         
void GumballMachine::releaseBall()
{
    cout<< "A gumball comes..." <<endl;
    if (miCount != 0)
        miCount--;
}
         
int GumballMachine::getCount() const
{
    cout<< "Left gamball number: " << miCount <<endl;
    return miCount;
}
1
2
3
4
5
6
7
//State
GumballMachine* gumballM = new GumballMachine(5);
gumballM->insertQuarter(); gumballM->turnCrank();
gumballM->insertQuarter(); gumballM->ejectQuarter(); gumballM->turnCrank();
gumballM->insertQuarter(); gumballM->turnCrank(); gumballM->ejectQuarter();
gumballM->insertQuarter(); gumballM->insertQuarter(); gumballM->turnCrank();
gumballM->turnCrank(); gumballM->ejectQuarter();

状态模式 - 封装基于状态的行为, 将行为委托到当前状态

策略模式 - 将可以互换的行为封装起来, 使用委托的方法决定使用哪一个行为

模板方法 - 由子类决定如何实现算法中的某些步骤

Summary

>要点 允许一个对象基于内部状态拥有不同的行为; 和程序状态机PSM不同, 状态模式用类代表状态; Context会将行为委托给当前状态对象; 将每个状态封装进一个类,

把以后需要做的改变局部化; 状态和策略模式的意图不同, 策略模式用行为(算法)来配置Context, 状态模式允许Context随着状态改变而改变行为; 状态转换可以由State

类或Context类控制; 使用状态模式会导致类的数目增加; 状态类可以被多个Context实例共享.

---Section 10 End---

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值