组合模式
组合模式在参考链接中已经讲得很好了,这里只简单讲讲就好。
组合模式的意图是表达部分-整体层次结构。
当你需要管理一个组合对象,又要管理这个组合对象的单个对象。这个时候就可以让这个组合对象和单个对象继承同一个基类,以便用基类指针做统一管理。
当基类指针去调用operation方法时,如果这个这个指针指向的是Composite对象,则调用的是Composite对象的operation方法,这个方法中的for循环会挨个遍历各个vector中的指针,如果遍历的指针指向的还是Composite对象,则继续调用Composite对象的operation方法。如果指针指向的单元是Leaf对象,则会调用Leaf对象中的operation方法。
如果不是写成组合模式,一般常用的递归函数会怎么写?首先也是遍历父节点,如果父节点有子节点就去遍历子节点,直到遍历完叶子节点。组合模式比较巧妙的是,在编译的时候,虚函数operation已经根据指针是指向基类还是子类分好了,所以递归函数中省去了判断是否是叶子节点的过程,而是让指针自行去判断。(设计模式经常干的一件事就是:把需用判断的地方巧妙的用继承虚函数来实现)
组合模式+迭代器模式
怎么用迭代器的方式去迭代Composite对象呢?
可以相应写一个CompositeIterator对象。迭代器其实有点像一个托管,对象将自己的链接地址给到迭代器,由迭代器的hasNext判断后面还有没数据,由next返回下一个容器对象。
关键代码
next(): 返回下一个对象,同时把composite对象创建的迭代器加入到iterators容器中。
hasNext(): 判断是否可迭代,如果不可迭代则继续删除此迭代器,继续寻找到下一个可迭代的迭代器。找到则返回true。
templateclass CompositeIterator : public Iterator { public: CompositeIterator(Iterator * iterator){ iterators.push_back(iterator); } T next(){ Iterator * 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 * iterator = iterators[0]; if(!iterator->hasNext()){ iterators.erase(iterators.begin()); // 已经没法迭代了,继续下一个迭代对象 return hasNext(); } else { return true; } } private: vector *> iterators; };
统一vsctor接口代码
这里为了让vector的迭代器也有hasNext()和next()接口,重写了一个newVector对象,其行为类似vector。
templateclass Iterator{ public: virtual bool hasNext(){} virtual T next(){} virtual bool isComposite(){} }; template class newVectorIterator : public Iterator { public: newVectorIterator(vector *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 *p; int position = 0; }; template 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 * createIterator(){ return new newVectorIterator (&mVector); } vector mVector; };
全部代码
#include#include #include using namespace std; template class Iterator{ public: virtual bool hasNext(){} virtual T next(){} virtual bool isComposite(){} }; template class newVectorIterator : public Iterator { public: newVectorIterator(vector *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 *p; int position = 0; }; template 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 * createIterator(){ return new newVectorIterator (&mVector); } vector mVector; }; template class NullIterator : public Iterator { public: T next(){ return nullptr; } bool hasNext(){ return false; } }; template class CompositeIterator : public Iterator { public: CompositeIterator(Iterator * iterator){ iterators.push_back(iterator); } T next(){ Iterator * 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 * iterator = iterators[0]; if(!iterator->hasNext()){ iterators.erase(iterators.begin()); return hasNext(); } else { return true; } } private: vector *> 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 * 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 * createIterator(){ return new NullIterator (); } 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 * createIterator(){ return new CompositeIterator (coms.createIterator()); } private: newVector 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 * iterator = com2->createIterator(); while(iterator->hasNext()){ iterator->next()->operation1(); } } int main(){ doCompositePattern(); return 0; }
参考
C++设计模式——组合模式(composite pattern)_c++ 设计模式组合-CSDN博客
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章