迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
组合模式 :允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
单一原则:一个类应该只有一个引起变化的原因。
迭代器模式示例代码:
#include <iostream>
#include <iomanip>
//
cout格式控制
#include <
string>
#include <vector>
class MenuItem;
/* 迭代器接口 */
class Iterator
{
public:
virtual bool HasNext() = 0;
virtual void* Next() = 0;
};
/* PancakeMenu 迭代器 */
class PancakeMenuIterator : public Iterator
{
public:
PancakeMenuIterator(std::vector<MenuItem*>* vMenuItem) : _vMenuItem(vMenuItem), _nCurrPos(
0)
{}
virtual
bool HasNext()
{
if (_nCurrPos < _vMenuItem->size())
return
true;
else
return
false;
}
virtual
void* Next()
{
return _vMenuItem->at(_nCurrPos++);
}
private:
std::vector<MenuItem*>* _vMenuItem;
int _nCurrPos;
};
/* DinerMenu 迭代器 */
class DinerMenuIterator : public Iterator
{
public:
DinerMenuIterator(MenuItem **menuItems,
int num) : _menuItems(menuItems), _itemsNum(num), _nCurrPos(
0)
{}
virtual
bool HasNext()
{
if (_nCurrPos < _itemsNum)
return
true;
else
return
false;
}
virtual
void* Next()
{
return _menuItems[_nCurrPos++];
}
private:
MenuItem ** _menuItems;
int _itemsNum;
int _nCurrPos;
};
/*
菜单项
*/
class MenuItem
{
public:
MenuItem(std::
string name, std::
string description,
bool vegetarian,
double price)
: _name(name), _description(description), _vegetarian(vegetarian), _price(price)
{}
std::
string GetName() {
return _name; }
std::
string GetDescription() {
return _description; }
bool IsVegetarian() {
return _vegetarian; }
double GetPrice() {
return _price; }
private:
std::
string _name;
std::
string _description;
bool _vegetarian;
double _price;
};
/*
菜单 Pancake:薄烤饼
*/
class PancakeHouseMenu
{
public:
PancakeHouseMenu()
{
AddItem(
"
K&B Pancake Breakfast
",
"
Pancakes with scrambled eggs and toast
",
true,
2.99);
AddItem(
"
Regular Pancake Breakfast
",
"
Pancakes with fried eggs sausage
",
false,
2.99);
AddItem(
"
Blueberry Pancakes
",
"
Pancakes made with fresh blueberries
",
true,
3.49);
AddItem(
"
Waffles
",
"
Waffles with your choice of blueberries or strawberries
",
true,
3.59);
}
void AddItem(std::
string name, std::
string description,
bool vegetarian,
double price)
{
MenuItem *pItem =
new MenuItem(name, description, vegetarian, price);
_vMenuItem.push_back(pItem);
}
PancakeMenuIterator* GetIterator() { return new PancakeMenuIterator(&_vMenuItem);}
std::vector<MenuItem*>* GetMenus() {
return &_vMenuItem; }
private:
std::vector<MenuItem*> _vMenuItem;
};
/*
菜单 Diner:路边小饭店,餐车式简便餐厅
*/
class DinerMenu
{
public:
DinerMenu()
{
_aMenuItems =
new MenuItem *[MAX_ITEMS];
_num =
0;
AddItem(
"
vegetarian BLT
",
"
(Fakin') Bacon with lettuce & tomato on whole wheat
",
true,
2.99);
AddItem(
"
BLT
",
"
--
",
false,
2.99);
AddItem(
"
Soup of the day
",
"
--
",
false,
3.29);
AddItem(
"
Hotdoy
",
"
--
",
false,
3.05);
}
void AddItem(std::
string name, std::
string description,
bool vegetarian,
double price)
{
if (_num < MAX_ITEMS)
{
MenuItem *pItem =
new MenuItem(name, description, vegetarian, price);
_aMenuItems[_num] = pItem;
_num ++;
}
else
{
std::cout<<
"
Sorry, menu is full. Can't add item to menu.
"<<std::endl;
}
}
MenuItem **GetMenus() {
return _aMenuItems; }
DinerMenuIterator* GetIterator() { return new DinerMenuIterator(_aMenuItems, _num);}
private:
static
const
int MAX_ITEMS;
MenuItem **_aMenuItems;
int _num;
};
const
int DinerMenu::MAX_ITEMS =
10;
/*
服务员,遍历显示菜单
*/
class Waitress
{
public:
Waitress(PancakeHouseMenu *pancakeMenu, DinerMenu *dinerMenu)
:_pancakeMenu(pancakeMenu), _dinerMenu(dinerMenu)
{}
void PrintMenu()
{
DinerMenuIterator *dinerIt = _dinerMenu->GetIterator();
PancakeMenuIterator* pancakeIt = _pancakeMenu->GetIterator();
std::cout<<
"
== Diner menu
"<<std::endl;
PrintMenu(dinerIt);
std::cout<<
"
== Pancake menu
"<<std::endl;
PrintMenu(pancakeIt);
}
void PrintMenu(Iterator *it)
{
#define COUT_STR_FORMAT(width) std::setw(width)<<std::setiosflags(std::ios::left)
MenuItem* item = NULL;
std::cout<<COUT_STR_FORMAT(
20)<<
"
-name-
"<<
"
"<<COUT_STR_FORMAT(
20)<<
"
-Description-
"<<std::endl;
while(it->HasNext())
{
item = (MenuItem *)it->Next();
std::cout<<COUT_STR_FORMAT(
20)<<item->GetName().c_str()<<
"
"<<COUT_STR_FORMAT(
20)<<item->GetDescription().c_str()<<std::endl;
}
}
private:
PancakeHouseMenu *_pancakeMenu;
DinerMenu *_dinerMenu;
};
int main()
{
std::cout<<
"
Iterator patten.
"<<std::endl<<std::endl;
PancakeHouseMenu *pancakeMenu =
new PancakeHouseMenu();
DinerMenu *dinerMenu =
new DinerMenu();
Waitress waitess(pancakeMenu, dinerMenu);
waitess.PrintMenu();
return
0;
}
组合模式示例代码:
#include <iostream>
#include <iomanip>
//
cout格式控制
#include <
string>
#include <vector>
/* 菜单组合接口 */
class MenuComponent
{
public:
/*
组合的3个基本方法
*/
virtual
void Add(MenuComponent *menu) {}
virtual
void Remove(MenuComponent *menu) {}
virtual MenuComponent *GetChild(
int i) {
return NULL; }
/*
菜单项方法
*/
virtual std::
string GetName() {
return
""; }
virtual std::
string GetDescription() {
return
""; }
virtual
bool IsVegetarian() {
return
false; }
virtual
double GetPrice() {
return
0; }
/* 组合接口的操作,菜单和菜单项 同时支持 */
virtual void Print() {}
};
#define COUT_STR_FORMAT(width) std::setw(width)<<std::setiosflags(std::ios::left)
/*
菜单项
*/
class MenuItem :
public MenuComponent
{
public:
MenuItem(std::
string name, std::
string description,
bool vegetarian,
double price)
: _name(name), _description(description), _vegetarian(vegetarian), _price(price)
{}
std::
string GetName() {
return _name; }
std::
string GetDescription() {
return _description; }
bool IsVegetarian() {
return _vegetarian; }
double GetPrice() {
return _price; }
/* 组合接口的操作,菜单和菜单项 同时支持 */
void Print()
{
std::cout<<COUT_STR_FORMAT(20)<<_name.c_str()<<" "<<COUT_STR_FORMAT(20)<<_description.c_str()<<std::endl;
}
private:
std::
string _name;
std::
string _description;
bool _vegetarian;
double _price;
};
class Menu :
public MenuComponent
{
public:
Menu(std::
string name, std::
string description) : _name(name), _description(description)
{}
/*
组合的3个基本方法
*/
void Add(MenuComponent *menu) { _vMenuItem.push_back(menu); }
void Remove(MenuComponent *menu)
{
for(std::vector<MenuComponent*>::iterator it=_vMenuItem.begin(); it!=_vMenuItem.end(); )
{
if(*it == menu)
{
it = _vMenuItem.erase(it);
//
_vMenuItem.erase(it);
}
else
{
++it;
}
}
}
MenuComponent *GetChild(
int i) {
return _vMenuItem.at(i); }
std::
string GetName() {
return _name; }
std::
string GetDescription() {
return _description; }
/* 组合接口的操作,菜单和菜单项 同时支持 */
void Print()
{
std::cout<<"menu:"<<_name.c_str()<<std::endl;
std::vector<MenuComponent*>::iterator it = _vMenuItem.begin();
while (it != _vMenuItem.end())
{
(*it)->Print();
++ it;
}
}
private:
std::
string _name;
std::
string _description;
std::vector<MenuComponent*> _vMenuItem;
};
/*
服务员,显示菜单
*/
class Waitress
{
public:
Waitress()
{
Menu *dinerMenu =
new Menu(
"
Diner menu
",
"");
dinerMenu->Add(
new MenuItem(
"
vegetarian BLT
",
"
(Fakin') Bacon with lettuce & tomato on whole wheat
",
true,
2.99));
dinerMenu->Add(
new MenuItem(
"
BLT
",
"
--
",
false,
2.99));
dinerMenu->Add(
new MenuItem(
"
Soup of the day
",
"
--
",
false,
3.29));
dinerMenu->Add(
new MenuItem(
"
Hotdoy
",
"
--
",
false,
3.05));
Menu *pancakeMenu =
new Menu(
"
Pancake menu
",
"");
pancakeMenu->Add(
new MenuItem(
"
K&B Pancake Breakfast
",
"
Pancakes with scrambled eggs and toast
",
true,
2.99));
pancakeMenu->Add(
new MenuItem(
"
Regular Pancake Breakfast
",
"
Pancakes with fried eggs sausage
",
false,
2.99));
pancakeMenu->Add(
new MenuItem(
"
Blueberry Pancakes
",
"
Pancakes made with fresh blueberries
",
true,
3.49));
pancakeMenu->Add(
new MenuItem(
"
Waffles
",
"
Waffles with your choice of blueberries or strawberries
",
true,
3.59));
_allMenus =
new Menu(
"
All Menu
",
"");
_allMenus->Add(dinerMenu);
_allMenus->Add(pancakeMenu);
}
void PrintMenu()
{
_allMenus->Print();
}
private:
Menu *_allMenus;
};
int main()
{
std::cout<<
"
Composite patten.
"<<std::endl<<std::endl;
Waitress waitess;
waitess.PrintMenu();
return
0;
}