结构型模式之迭代器(Iterator)与组合模式(Composite Pattern)C++实现******

目标:让用户遍历你的对象而无法窥视你存储对象的方式。如何创建对象的超集合。


迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。迭代器模式把在元素之间游走的责任交给迭代器,而不是聚合对象。

迭代器类图:



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

组合模式类图:


在开发中,可能要递归构建树状的组合结构,Composite模式则提供了很好的解决方案。

Component想相当于MenuComponent,Leaf相当MenuItem,Composite相当于Menu。


HeadFirst中菜单组合模式的C++实现:

Component.h头文件

#ifndef _COMPONENT_H_
#define _COMPONENT_H_
#include<string>
using namespace std;

class MenuComponent
{
public:
MenuComponent();
virtual ~MenuComponent();
//下面三个方法针对Menu
 virtual void add(MenuComponent *menuCom);
 virtual void remove(MenuComponent *menuCom);
 virtual MenuComponent *getChild(int i);

 //以下方法针对MenuItem
 virtual string getName()=0;
 virtual string getDescription()=0;
 virtual double getPrice()=0;
 virtual bool isVegetarian()=0;
 virtual void print()=0;//同时被Menu和MenuItem实现
};

class Waitress
{
public:
	Waitress(MenuComponent *allMenus);
	~Waitress();
	void printMenu();
protected:
private:
	MenuComponent *allMenus;
};
#endif 

Component.CPP

#include"Component.h"

MenuComponent::MenuComponent()
{

}
MenuComponent::~MenuComponent()
{
 
}
void MenuComponent::add(MenuComponent *menuCom)
{

}
void MenuComponent::remove(MenuComponent *menuCom)
{
	
}
MenuComponent *MenuComponent::getChild(int i)
{
	return 0;
}

Waitress::Waitress(MenuComponent *allMenus)
{
	this->allMenus=allMenus;

}
Waitress::~Waitress()
{

}
void Waitress::printMenu()
{
	allMenus->print();
}

Composite.h

#ifndef _COMPOSITE_H_
#define _COMPOSITE_H_
#include"Component.h"
#include<string>
#include<vector>
#include<iostream>
using namespace std;
class Menu:public MenuComponent
{
public:
    Menu(string name,string description);
    ~Menu();
  void add(MenuComponent *menuCom);
  void remove(MenuComponent *menuCom);
  MenuComponent *getChild(int i);
  string getName();
  string getDescription();

 double getPrice(); //这两个方法对于Menu无意义
 bool isVegetarian();

 void print();


protected:

private:
	string name;
	string description;
    vector<MenuComponent *> menuVec;
};


#endif 

Composite.CPP

#include "Composite.h"
Menu::Menu(string name, string description)
{
	this->name=name;
	this->description=description;
}
Menu::~Menu()
{

}

void Menu::add(MenuComponent *menuCom)
{
	menuVec.push_back(menuCom);
}
void Menu::remove(MenuComponent *menuCom)
{
	vector<MenuComponent *>::const_iterator const_it=menuVec.begin();
	for(;const_it!=menuVec.end();const_it++)
	{
		if((*const_it)==menuCom)
          menuVec.erase(const_it);
		 break;
	}


	 
  // menuVec.erase(&menuCom);
  
}
MenuComponent *  Menu::getChild(int i)
{
	return menuVec[i];
}
string Menu::getName()
{
	return name;
}
string Menu::getDescription()
{
	return description;
}
double Menu::getPrice()
{
	return 0;
}
bool Menu::isVegetarian()
{
	return false;
}
void Menu::print()
{
	cout<<endl<<getName()<<","<<getDescription()<<"---------"<<endl;
	//让菜单不仅打印出本身的信息,也打印出菜单内所有组件的信息:其他菜单,菜单项
	vector<MenuComponent *>::iterator it=menuVec.begin();
	for(;it!=menuVec.end();it++)
	{
		(*it)->print(); //菜单和菜单项都实现了print()方法,相当于一个递归的过程
	}
}


Leaf.h

#ifndef _LEAF_H_
#define _LEAF_H_
#include"Component.h"
#include<string>
#include<iostream>
using namespace std;
class MenuItem:public MenuComponent
{
public:
	MenuItem(string name,string description,bool vegetarian,double price);
	~MenuItem();
	string getName();
	string getDescription();
	double getPrice();
	bool isVegetarian();
	void print();

protected:
private:
	string name;
	string description;
	bool vegetarian;
	double price;

};


#endif

Leaf.CPP

#include "Leaf.h"
MenuItem::MenuItem(string name,string description,bool vegetarian,double price)
{
	this->name=name;
	this->description=description;
	this->vegetarian=vegetarian;
	this->price=price;
}
MenuItem::~MenuItem()
{
 
}
string MenuItem::getName()
{
	return name;
}
string MenuItem::getDescription()
{
	return description;
}
bool MenuItem::isVegetarian()
{
	return vegetarian;
}
double MenuItem::getPrice()
{
	return price;
}

void MenuItem::print()
{
	cout<<" "<<getName();
	if(isVegetarian())
		cout<<" (v)";
	cout<<","<<getPrice()<<"  --"<<getDescription()<<endl;

}

main.CPP

//main.cpp
#include "Component.h"
#include "Composite.h"
#include "Leaf.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
	 //开始创建菜单
	MenuComponent * pancakeHouseMenu=new Menu("PANCANK HOUSE MENU","Breakfast");
    MenuComponent * dinnerMenu=new Menu("DINER MENU","Lunch");
    MenuComponent * cafeMenu=new Menu("CAFE MENU","Dinner");
	MenuComponent * dessertMenu=new Menu("DESSERT MENU","Dessert of course!");


	MenuComponent *allMenus=new Menu("ALL MENUS","All Menus Combined");
	//加入菜单到顶层菜单
	allMenus->add(pancakeHouseMenu);
	allMenus->add(dinnerMenu);
	allMenus->add(cafeMenu);
  //加入菜单项MenuItem
	pancakeHouseMenu->add(new MenuItem("Pancak","pancak with milk",true,4.42));

	dinnerMenu->add(new MenuItem("Pasta0","Spaghetti with Marinara Sauce and a slice of sourdough bread",true,3.89));
	dinnerMenu->add(new MenuItem("Pasta1","Spaghetti with Marinara Sauce and a slice of sourdough bread",false,1.29));
   
   
	Waitress waitress(allMenus);
	waitress.printMenu();
	


	return 0;
}





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值