C++设计模式--迭代器模式组合模式解析(head first 设计模式C++实现)

迭代器模式与组合模式

  1. 迭代器模式:提供一种方法顺序访问一个聚会对象中的各个元素,而不是暴露其内部的表示
  2. 迭代器模式用来封装变化,迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露其内部的表示。把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。
  3. 迭代器模式体现的设计原则:单一责任:一个类应该只有一个引起变化的原因(类中管理数组是一个功能 遍历数组是另外一个功能两者分开)
  4. 组合模式:允许你将对象组合成树形结构来表现整体/部分层次结构,组合能让客户以一致的方式处理个别对象以及对象组合。
  5. 迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
  6. 迭代器将遍历聚合的工作封装进一个对象中。
  7. 组合模式提供一个结构,可同时包容个别对象和组合对象。

例子

在这里插入图片描述


迭代器模式示例
class Menus{
    public:
    virtual void* createIterator()=0;
};


class MenuItem{

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

    public:
        MenuItem(){}
        MenuItem(string m_name,string m_description,bool m_vegetarian,double m_price):
        name(m_name),description(m_description),vegetarian(m_vegetarian),price(m_price){} 

        string getName(){
            return name;
        }

        string getDescription(){
            return description;
        }

        double getPrice(){
            return price;
        }
        
        bool isVegetarian(){
            return vegetarian;
        }
};

class m_iterator{
    public:
        virtual bool hasNext()=0; 
        virtual MenuItem* next()=0; 
};

class DinerMenuIterator:public m_iterator{
    public:
        DinerMenuIterator(MenuItem** m_menuItems,int m_size):menuItems(m_menuItems),length(m_size){
        }
        ~DinerMenuIterator(){
            if(menuItems){
                delete menuItems;
                menuItems=nullptr;
            }
        }

        virtual bool hasNext(){
            
            if(length==0||position>=length){
                return false;
            }
            return true;
        }

        virtual MenuItem* next(){
            if(position<length)
                return menuItems[position++]; 
        }


    private:
        int length=0;
        int position=0; 
        MenuItem** menuItems;  
};


class PancakeMenuIterator:public m_iterator{
    public:
        PancakeMenuIterator(list<MenuItem>& m_menuItems):menuItems(m_menuItems){
            start=menuItems.begin();
        }

        virtual bool hasNext(){

            if(start==menuItems.end()){
                return false;
            }
            return true;
        }

        virtual MenuItem* next(){
            if(start!=menuItems.end()){
                MenuItem* temp = &(*start);                    
                ++start;
                return temp;
            }
        }


    private:
        list<MenuItem> menuItems;
        list<MenuItem>::iterator start;   

};


class DinerMenu:public Menus{
private:
    static int MAX_ITEMS;
    int numberOfItems =-1;
    MenuItem** menuIems=nullptr;

public:
    DinerMenu(){
        menuIems = new MenuItem*[MAX_ITEMS];
        addItem("Vegetarian BLT","Bacon with lettuce",true,2.99);
        addItem("Soup of the day","Soup of the day , with a side of potato salad",false,3.99);

    }

    void addItem(string name,string description,bool vegetarian,double price){
        if(numberOfItems<MAX_ITEMS){
            menuIems[++numberOfItems]=new MenuItem(name,description,vegetarian,price);
        }
    }

    int getSize(){
        return numberOfItems;
    } 

    MenuItem** getMenuItems(){
        return menuIems;
    }
    ~DinerMenu(){
        if(menuIems){
            delete [] menuIems;
            menuIems=nullptr;
        }
    }


    virtual void* createIterator(){

        return new DinerMenuIterator(menuIems,numberOfItems+1);
    } 


};

int DinerMenu::MAX_ITEMS = 6;

class PancakeHouseMenu:public Menus{

    private:
        list<MenuItem> menuItems;
    public:
      
        PancakeHouseMenu(){
           addItem("Pancake Breakfast","Pancakes with scrambled eggs",true,4.99);
           addItem("Regular Breakfast","Pancakes made with fresh blueberries",true,5.99);
        }

    void addItem(string name,string description,bool vegetarian,double price){
        menuItems.push_back(MenuItem(name,description,vegetarian,price));
    }

    list<MenuItem> getMenuItems(){
        return menuItems;
    }
    virtual void* createIterator(){
        
        return new PancakeMenuIterator(menuItems);
    } 
};



int main(){

vector<Menus*> menus; //总的菜单容器

DinerMenu* dinnermenu = new DinerMenu;
menus.push_back(dinnermenu); //加入菜单
PancakeHouseMenu* pancakemenu = new PancakeHouseMenu;
menus.push_back(pancakemenu);

for(int i=0;i<menus.size();++i){  //遍历每个菜单的菜

    m_iterator* pointer=(m_iterator*)menus[i]->createIterator();
        
    while(pointer->hasNext()){
        MenuItem* menuitem = pointer->next();
        cout<<menuitem->getName()<<" "<<menuitem->getPrice()<<endl;
    } 
         
    cout<<endl<<endl; 

}


system("pause");
return 0;

}

例子

在这里插入图片描述


组合模式示例
class MenuComponent{
    public:
        virtual ~MenuComponent(){};

        virtual void add(MenuComponent* menuComponent)=0;
        virtual void remove(MenuComponent* menuComponent)=0;
        virtual void* getChild(int i)=0;

        virtual string getName()=0; 
        virtual string getDescription()=0;

        virtual double  getPrice()=0;
        virtual bool isVegetarian()=0;

        virtual void print()=0;
};


class MenuItem:public MenuComponent{
    private:
        string name;
        string description;
        double price;
        bool vegetarian; 
    public:
        MenuItem(string m_name,string m_description,double m_price,bool m_vegetarian)
            :name(m_name),description(m_description),price(m_price),vegetarian(m_vegetarian){}
        
        virtual void add(MenuComponent* menuComponent){return;};
        virtual void remove(MenuComponent* menuComponent){return;};
        virtual void* getChild(int i){return nullptr;};

        virtual string getName(){
            return name;
        }; 
        virtual string getDescription(){
            return description;
        };

        virtual double  getPrice(){
            return price;
        }
        virtual bool isVegetarian(){
            return vegetarian;
        }

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

};
class Menu:public MenuComponent{
    private:
        vector<MenuComponent*> menuComponents;
        string name;
        string description;

    public:
        Menu(string m_name,string m_description)
            :name(m_name),description(m_description){};

        virtual void add(MenuComponent* menuComponent){
            if(menuComponent){
                menuComponents.push_back(menuComponent);
            }
        };
        virtual void remove(MenuComponent* menuComponent){
            for(int i=0;i<menuComponents.size();++i){
                if(menuComponents[i]==menuComponent){
                    menuComponents.erase(menuComponents.begin()+i);
                    break;
                }
            } 
        };
        virtual void* getChild(int i){
            if(i<menuComponents.size()){
                return menuComponents[i];
            }
        };

        virtual string getName(){
            return name;
        }; 
        virtual string getDescription(){
            return description;
        };

        virtual double  getPrice(){
            return 0;
        };
        virtual bool isVegetarian(){
            return false;
        };

        virtual void print(){
            cout<<"\n"<<getName();
            cout<<","<<getDescription()<<endl;
            cout<<"--------------"<<endl;
            for(int i=0;i<menuComponents.size();++i){
                menuComponents[i]->print();
            } 
        };
};

int main(){

    MenuComponent* pancakeHouseMenu=new Menu("PANCAKE HOUSE MENU","Breakfast");
    MenuComponent* dinerMenu=new Menu("DINER","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(dinerMenu);
    allMenus->add(cafeMenu);

    dinerMenu->add(new MenuItem("Pasta","Spaghetti with Marinara Sauce",2.99,true));
    dinerMenu->add(dessertMenu);

    dessertMenu->add(new MenuItem("Apple Pie","Apple pie with a flakey crust",1.99,true));

    allMenus->print();


    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值