(十)Head first design patterns组合模式(c++)

这篇具有很好参考价值的文章主要介绍了(十)Head first design patterns组合模式(c++)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

组合模式

组合模式在参考链接中已经讲得很好了,这里只简单讲讲就好。

组合模式的意图是表达部分-整体层次结构。

当你需要管理一个组合对象,又要管理这个组合对象的单个对象。这个时候就可以让这个组合对象和单个对象继承同一个基类,以便用基类指针做统一管理。

当基类指针去调用operation方法时,如果这个这个指针指向的是Composite对象,则调用的是Composite对象的operation方法,这个方法中的for循环会挨个遍历各个vector中的指针,如果遍历的指针指向的还是Composite对象,则继续调用Composite对象的operation方法。如果指针指向的单元是Leaf对象,则会调用Leaf对象中的operation方法。

如果不是写成组合模式,一般常用的递归函数会怎么写?首先也是遍历父节点,如果父节点有子节点就去遍历子节点,直到遍历完叶子节点。组合模式比较巧妙的是,在编译的时候,虚函数operation已经根据指针是指向基类还是子类分好了,所以递归函数中省去了判断是否是叶子节点的过程,而是让指针自行去判断。(设计模式经常干的一件事就是:把需用判断的地方巧妙的用继承虚函数来实现)

(十)Head first design patterns组合模式(c++),设计模式cpp,设计模式

组合模式+迭代器模式

怎么用迭代器的方式去迭代Composite对象呢?

可以相应写一个CompositeIterator对象。迭代器其实有点像一个托管,对象将自己的链接地址给到迭代器,由迭代器的hasNext判断后面还有没数据,由next返回下一个容器对象。

关键代码

next(): 返回下一个对象,同时把composite对象创建的迭代器加入到iterators容器中。

hasNext(): 判断是否可迭代,如果不可迭代则继续删除此迭代器,继续寻找到下一个可迭代的迭代器。找到则返回true。

template<class T>
class CompositeIterator : public Iterator<T>{
public:
    CompositeIterator(Iterator<T>* iterator){ iterators.push_back(iterator); }
    T next(){
        Iterator<T>* iterator = iterators[0];
        T item = iterator->next();
        iterator = item->createIterator();
        if(iterator->hasNext()){ // 这里leaf的迭代器hasNext返回的是false,故而不会添加进去
            iterators.push_back(iterator);
        } 
        return item;
    }
    bool hasNext(){
        if(iterators.size()==0) return false;
        Iterator<T>* iterator = iterators[0];
        if(!iterator->hasNext()){ 
            iterators.erase(iterators.begin()); // 已经没法迭代了,继续下一个迭代对象
            return hasNext();
        } else {
            return true;
        }
    }
private:
    vector<Iterator<T>*> iterators;
};

统一vsctor接口代码

这里为了让vector的迭代器也有hasNext()和next()接口,重写了一个newVector对象,其行为类似vector。

template<class T>
class Iterator{
public:
    virtual bool hasNext(){}
    virtual T next(){}
    virtual bool isComposite(){}
};
template<class T>
class newVectorIterator : public Iterator<T>{
public:
    newVectorIterator(vector<T> *p):p(p){}
    T next(){
        T t = p->at(position);
        position++;
        return t;
    }
    bool hasNext(){
        if(position >= p->size()) 
            return false;
        else
            return true;
    }
    vector<T> *p;
    int position = 0;
};
template<class T>
class newVector{
public:
    void push_back(T item){
        mVector.push_back(item);
    }
    T operator[](int index){
        return mVector[index];
    }
    int size(){
        return mVector.size();
    }
    Iterator<T>* createIterator(){
        return new newVectorIterator<T>(&mVector);
    }
    vector<T> mVector;
};

全部代码

#include<iostream>
#include<string>
#include<vector>
using namespace std;

template<class T>
class Iterator{
public:
    virtual bool hasNext(){}
    virtual T next(){}
    virtual bool isComposite(){}
};
template<class T>
class newVectorIterator : public Iterator<T>{
public:
    newVectorIterator(vector<T> *p):p(p){}
    T next(){
        T t = p->at(position);
        position++;
        return t;
    }
    bool hasNext(){
        if(position >= p->size()) 
            return false;
        else
            return true;
    }
    vector<T> *p;
    int position = 0;
};
template<class T>
class newVector{
public:
    void push_back(T item){
        mVector.push_back(item);
    }
    T operator[](int index){
        return mVector[index];
    }
    int size(){
        return mVector.size();
    }
    Iterator<T>* createIterator(){
        return new newVectorIterator<T>(&mVector);
    }
    vector<T> mVector;
};

template<class T>
class NullIterator : public Iterator<T>{
public:
    T next(){ return nullptr; }
    bool hasNext(){ return false; }
};
template<class T>
class CompositeIterator : public Iterator<T>{
public:
    CompositeIterator(Iterator<T>* iterator){ iterators.push_back(iterator); }
    T next(){
        Iterator<T>* iterator = iterators[0];
        T item = iterator->next();
        iterator = item->createIterator();
        if(iterator->hasNext()){
            iterators.push_back(iterator);
        } 
        return item;
    }
    bool hasNext(){
        if(iterators.size()==0) return false;
        Iterator<T>* iterator = iterators[0];
        if(!iterator->hasNext()){
            iterators.erase(iterators.begin());
            return hasNext();
        } else {
            return true;
        }
    }
private:
    vector<Iterator<T>*> iterators;
};
class Compoment{
public:
    virtual ~Compoment(){ std::cout << "~Compoment()" << endl; }
    virtual void operation() = 0;
    virtual void operation1() = 0;
    virtual void add(Compoment *com){}
    virtual void remove(Compoment *com){}
    virtual Compoment* findChild(int index){ return nullptr; }
    virtual Iterator<Compoment*>* createIterator(){}
};
class Leaf : public Compoment{
public:
    Leaf(int num) : num(num) {}
    ~Leaf(){ std::cout << "~Leaf()" << num << endl;}
    virtual void operation() { cout << "Leaf::operation()" << num << endl; }
    void operation1(){ std::cout << "Leaf::operation1()" << num << std::endl; }
    Iterator<Compoment*>* createIterator(){
        return new NullIterator<Compoment*>();
    }
private:
    int num;
};
class Composite : public Compoment{
public:
    Composite(){}
    ~Composite(){
        std::cout << "~Composite()" << std::endl;
    }
    void operation(){
        std::cout << "Composite::operation()" << std::endl;
        for(int i = 0; i < coms.size(); i ++ ){
            coms[i]->operation();
        }
    }
    void operation1(){
        std::cout << "Composite::operation1()" << std::endl;
    }
    bool isComposite(){ return true; }
    void add(Compoment *com){ coms.push_back(com); }
    Compoment* findChild(int index){
        if(index < 0 || index >= coms.size()){
            return nullptr;
        }
        return coms[index];
    }
    Iterator<Compoment*>* createIterator(){
        return new CompositeIterator<Compoment*>(coms.createIterator());
    }
private:
    newVector<Compoment*> coms;
};

void doCompositePattern(){
    std::cout << "-----------com1->operation()-----------" << std::endl;
    Compoment *com1 = new Composite();
    com1->add(new Leaf(1));
    com1->add(new Leaf(2));
    com1->add(new Leaf(3));
    com1->operation();
    std::cout << "-----------com2->operation()-----------" << std::endl;
    Compoment *com2 = new Composite();
    com2->add(new Leaf(4));
    com2->add(com1);
    com2->add(com1);
    com1->add(new Leaf(11));
    com2->operation();

    std::cout << "\n-----------iterator-----------" << std::endl;
    Iterator<Compoment*>* iterator = com2->createIterator();
    while(iterator->hasNext()){
        iterator->next()->operation1();
    }
}

int main(){
    doCompositePattern();
    return 0;
}

 参考

​​​​​​​​​​​​​​C++设计模式——组合模式(composite pattern)_c++ 设计模式组合-CSDN博客文章来源地址https://www.toymoban.com/news/detail-817478.html

到了这里,关于(十)Head first design patterns组合模式(c++)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【设计模式】Head First 设计模式——策略模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 将行为想象为一族算法,定义算法族,分别封装起来,让他们之间可以互相替换,使得算

    2024年02月11日
    浏览(41)
  • 【设计模式】Head First 设计模式——抽象工厂模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具

    2024年02月10日
    浏览(43)
  • 【设计模式】Head First 设计模式——构建器模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 ​ 将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同

    2024年02月09日
    浏览(40)
  • 【设计模式】Head First 设计模式——装饰者模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    2024年02月10日
    浏览(44)
  • 【设计模式】Head First 设计模式——工厂方法模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使得一个类的实

    2024年02月10日
    浏览(50)
  • 【设计模式】Head First 设计模式——观察者模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 主题对象(出版者)管理某些数据,当主题内的数据改变,就会通知观察者(订阅者)。

    2024年02月10日
    浏览(42)
  • 【Head First 设计模式】-- 观察者模式

    客户有一个WeatherData对象,负责追踪温度、湿度和气压等数据。现在客户给我们提了个需求,让我们利用WeatherData对象取得数据,并更新三个布告板:目前状况、气象统计和天气预报。 WeatherData对象提供了4个接口: getTemperature():获取温度 getHumidity():获取湿度 getPressure():获

    2024年02月05日
    浏览(46)
  • 【设计模式】Bridge Design pattern 桥接模式

    多个维度的变化引起的继承组合指数级增长 例子 一个物体有不同形状和不同颜色,如何用类来表示它们,这里包含了两个变化维度,一个是物体的形状,一个是颜色 继承的方式 如果使用继承的方式,此时要增加一个形状就要多两个类,或者增加一个颜色也要多两个类,这个

    2023年04月08日
    浏览(43)
  • 设计模式--组合模式(Composite Pattern)

    组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构,并且能像使用独立对象一样使用它们。 组合模式主要包含以下几个角色: Component:这是组合中对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管

    2024年02月22日
    浏览(44)
  • 设计模式-组合模式(Composite Pattern)

    组合模式是一种结构型设计模式,它允许将对象组合成树状的层次结构,用来表示“整体-部分”的关系。 原理图 抽象角色(Component) :这是组合模式的核心,它定义了树叶和树枝构件的公共接口,并可能提供一些默认行为。在透明式的组合模式中,它还声明了访问和管理子

    2024年04月12日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包