程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 設計模式C++實現——迭代器模式

設計模式C++實現——迭代器模式

編輯:C++入門知識

模式定義

迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。

迭代器模式讓我們能游走於聚合內的每一個元素,而又不暴露其內部的表示。把游走的任務放在迭代器上,而不是聚合上。這樣簡化了聚合的接口和實現,也讓責任各得其所。

模式結構:

\

<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+ICAgICAgICBJdGVyYXRvcqO6tfy0+sb3tqjS5bfDzsq6zbHpwPrUqsvYtcS907/aPC9wPgo8cD4gICAgICAgIENvbmNyZXRlSXRlcmF0b3I6vt/M5bX8tPrG98q1z9a1/LT6xve907/ao7u21LjDvtu6z7HpwPrKsbj619m1scewzrvWwzwvcD4KPHA+ICAgICAgICBBZ2dyZWdhdGU6vtu6z7ao0uW0tL2oz+DTprXEtfy0+sb3ttTP873Tv9o8L3A+CjxwPiAgICAgICAgQ29uY3JldGVBZ2dyZWdhdGU6vt/M5b7bus/Ktc/WtLS9qM/g06a1/LT6xve1xL3Tv9qjrLjDstnX97e1u9hDb25jcmV0ZUl0ZXJhdG9ytcTSu7j2ysq1sbXEyrXA/aGjPC9wPgo8aDE+vtnA/aO6PC9oMT4KPHA+ICAgICAgICC85bH9zt26zc7nss216rrPsqK689Do0qq2qNbG0ru33dDCtcSyzbWlo6y1q9PJ09q85bH9zt21xNStssu1pcrH08PBtLHtyrXP1qOstvjO57LNtePUrbLLtaXKx9PDyv3X6cq1z9Yoy/vDx7XEtqjS5cjnz8LL+cq+KaOsy/nS1LTy06HQwrLNtaW1xMqxuvLQ6NKqt9ax8NGtu7ex6cD61K2yzbWl1tC1xLLLtaXP7qGjPC9wPgo8cCBhbGlnbj0="left">

//菜單項類
class MenuItem
{
public:
	MenuItem(){}
	MenuItem(string na, string descrip, double pric)
	{
		name = na;
		description = descrip;
		price = pric;
	}

	string getName()
	{
		return name;
	}

	string getDescription()
	{
		return description;
	}
	
	double getPrice()
	{
		return price;
	}
private:
	string name;
	string description;
	double price;
};
//煎餅屋餐單類
class PancakeHouseMenu
{
public:
	PancakeHouseMenu()
	{
		addItem("K&B'S Breakfase","pacakes with eggs",2.99);
		addItem("Buleberry Breakfase","pacakes with buleberries",3.99);
	}

	void addItem(string na, string descrip, double ric)
	{
		MenuItem menuItem(na,descrip,ric);
		menuItems.push_back(menuItem);
	}
	list getMenuItems()
	{
		return menuItems;
	}
private:
	list menuItems;
};
//午餐點餐單類
class DinerMenu
{
public:
	DinerMenu()
	{
		addItem("Vegetarian BLT", "Bacon with lettuce", 2.99);
		addItem("BLT", "Bacon with tomato", 3.99);
	}
	void addItem(string na, string descrip, double ric)
	{
		MenuItem menuItem(na,descrip,ric);
		menuItems.push_back(menuItem);
	}
	vector getMenuItems()
	{
		return menuItems;
	}
private:
	vector menuItems;
};
//必須調用pancakeHouseMenu.getMenuItems()和//dinerMenu.getMenuItems()來取得他們的餐單
PancakeHouseMenu pancakeHouseMenu;
list breakfastItems = pancakeHouseMenu.getMenuItems();
DinerMenu dinerMenu;
vector lunchItem = dinerMenu.getMenuItems();

	list::iterator iter = breakfastItems.begin();
	//打印新餐單的時候需要分別循環遍歷原餐單中的菜單項
	for(; iter != breakfastItems.end(); ++iter)
	{
		MenuItem menuItem = *iter;
		cout << menuItem.getName() << "	"<< menuItem.getPrice()<<"	" 
			<< menuItem.getDescription() << endl;
	}

	for(unsigned int i=0; i

如果還有第三家餐廳加入,我們還需要第三個循環,意味著要寫很多重復代碼。解決方法利用迭代器模式。

UML設計:

\

編程實現及執行結果:

#include 
#include 
#include 
#include 

using namespace std;

//菜單項類
class MenuItem
{
public:
	MenuItem(){}
	MenuItem(string na, string descrip, double pric)
	{
		name = na;
		description = descrip;
		price = pric;
	}

	string getName()
	{
		return name;
	}

	string getDescription()
	{
		return description;
	}
	
	double getPrice()
	{
		return price;
	}
private:
	string name;
	string description;
	double price;
};
//迭代器基類
class Iterator
{
public:
	//是否有下一個一個菜單
	virtual bool hasNext(){throw std::exception("ERROR");};
	//取下一個菜單
	virtual MenuItem next(){throw std::exception("ERROR");};
};
//煎餅屋餐單迭代器
class PancakeHouseMenuIterator : public Iterator
{
public:
	PancakeHouseMenuIterator(list item)
	{
		items = item;
		iter = items.begin();
	}
	MenuItem next()
	{
		MenuItem menuItem = *iter;
		++iter;
		return menuItem;
	}

	bool hasNext()
	{
		if(iter == items.end())
		{
			return false;
		}
		else
		{
			return true;
		}
	}
private:
	list items;
	list::const_iterator iter;
};
//午餐店餐單迭代器
class DinerMenuIterator : public Iterator
{
public:
	DinerMenuIterator(vector item):position(0)
	{
		items = item;
	}
	MenuItem next()
	{
		MenuItem menuItem = items[position];
		position = position + 1;
		return menuItem;
	}

	bool hasNext()
	{
		if(position >= items.size())
		{
			return false;
		}
		else
		{
			return true;
		}
	}
private:
	vector items;
	unsigned int position;
};

//餐單基類
class Menu
{
public:
	//創建迭代器
	virtual Iterator* createIterator(){throw std::exception("ERROR");}
};



//煎餅屋餐單類
class PancakeHouseMenu : public Menu
{
public:
	PancakeHouseMenu()
	{
		addItem("K&B'S Breakfase","pacakes with eggs",2.99);
		addItem("Buleberry Breakfase","pacakes with buleberries",3.99);
	}
	//增加菜單
	void addItem(string na, string descrip, double ric)
	{
		MenuItem menuItem(na,descrip,ric);
		menuItems.push_back(menuItem);
	}
	//創建PancakeHouseMenuIterator迭代器
	Iterator* createIterator()
	{
		return new PancakeHouseMenuIterator(menuItems);
	}
private:
	list menuItems;
};

//午餐點餐單類
class DinerMenu : public Menu
{
public:
	DinerMenu()
	{
		addItem("Vegetarian BLT", "Bacon with lettuce", 2.99);
		addItem("BLT", "Bacon with tomato", 3.99);
	}
	void addItem(string na, string descrip, double ric)
	{
		MenuItem menuItem(na,descrip,ric);
		menuItems.push_back(menuItem);
	}
	Iterator* createIterator()
	{
		return new DinerMenuIterator(menuItems);
	}
private:
	vector menuItems;
};

//服務生類
class Waitress
{
public:
	Waitress(Menu* p_PancakeHouseMenu, Menu* p_DinerMenu)
	{
		pPancakeHouseMenu = p_PancakeHouseMenu;
		pDinerMenu = p_DinerMenu;
	}
	//打印菜單
	void printMenu()
	{
		Iterator* pPancakeHouseIterator = pPancakeHouseMenu->createIterator();
		Iterator* pDinerIterator = pDinerMenu->createIterator();

		cout << "Menu"<< endl <<"----"<hasNext())
		{
			MenuItem menuItem = (MenuItem)iter->next();
			cout << menuItem.getName() << "	"<< menuItem.getPrice()<<"	" 
			<< menuItem.getDescription() << endl;
		}
	}
private:
	Menu* pPancakeHouseMenu;
	Menu* pDinerMenu;
};
//客戶代碼
int main()
{
	Menu* pPancakeHouseMenu = new PancakeHouseMenu();
	Menu* pDinerMenu = new DinerMenu();

	Waitress waitress(pPancakeHouseMenu,pDinerMenu);
	waitress.printMenu();
	return 0;
}

執行結果:

Menu

----

BREAKFAST

K&B'SBreakfase 2.99 pacakes with eggs

BuleberryBreakfase 3.99 pacakes with buleberries

LUNCH

VegetarianBLT 2.99 Bacon with lettuce

BLT 3.99 Bacon with tomato

請按任意鍵繼續. . .

設計原則的應用:

設計原則:一個類應該只有一個引起變化的原因。這個原則告訴我們盡量讓一個類保持單一責任。如果一個類具有兩個以上改變的原因,那麼這會使將來該類的變化率上升。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved