初学设计模式(7)迭代模式和组合模式
2013-03-05 13:53
141 查看
家里蹲了将近一个多月,终于找到一份新的工作,开始了另一端修行。
这段时间里,通读了大半head first设计模式,如今已经看到了代理模式。看着自己知识的日积月累,心里也是各种欢喜,坚定了要一读到底的决心。(虽然实用与否依然需要项目的磨练)
今天将之前没写的几个模式补上。首先来讲讲,跌到模式和组合模式。
心法(8):迭代模式。
说起这个迭代模式,其实跟我们平时用到的for循环很类似,应该说,是把for循环给抽象化,忽略实际的遍历过程,在client code端直接通过moveNext和hasNext来实现遍历整个数据结构。这里说是数据结构,其实在代码中就是表现成类实例的结构。
心法(9):组合模式。
当我们需要把几个相关的类组合成一个树状结构时,便可以通过组合模式,将那些类的实例,通过统一的接口进行组织,
由于组合模式从某种程度上依赖于迭代模式的实现,因此,我将两者代码合并在一起。
以下是代码:
Component(这就是需要组织成树状结构的类)
虚基类,用于concrete class继承,其中每个方法都定义一个默认的实现----抛出一个不支持的实现
两个concrete class
Menu,compose了一个MenuComponent的集合,说明menu可以充当一个容器。
MenuItem:这只是一个MenuComponent最基础的单元,可以作为menu的子项。
Iterator:
CompositeIterator:用于遍历树状结构的实例集合
NullIterator:由于MenuItem是最基础的子项,因此对他迭代是无意义的,因此创建此类,并相应的返回false和null。
Waitress:用于遍历整个对象集合的client code。
Main函数:
如图中所示,这就是我们创建的menu结构图,当我们需要对这个整个结构进行遍历的时候,就需要用到composite iterator类。使用递归的实现,进行遍历。
(PS:但是这里的递归实现是有问题的,当运行main函数的时候,会发现item被显示了5次,ccc被显示了2次,而我们的本意则是每个子项只显示一次。因此这里一的算法肯定错了,我已经在论坛里面挂了贴----------(请猛戳这里!!
) 希望能得到大牛前辈们的指点,算法确实基础不是很好,决定设计模式结束之后开始重新复习数据结构和算法)
这里贴下结构截图,结果显示不是正确,但至少这个模式是对的。
这里要提一个设计模式,就是A class should have only one reason to change. 其实也就是one class,one responsibility。 对于以上的设计,每个menu除了负责本身menu的getter和setter之外就是createIterator方法,这个方法本就是menu的职责之内,而menu并不负责对整个树状结构的遍历,其实现是交给了composite
iterator,即composite iterator仅仅只是用来遍历树状结构的对象集,但他并不知道他处理的是menu还是menuitem,只是一个menucomponent。(depend on abstraction,not concrete class)
对于组合模式和迭代模式的学习就暂且到这。今后将利用项目中的实际操作经验,来完善对这两个模式的理解。
这段时间里,通读了大半head first设计模式,如今已经看到了代理模式。看着自己知识的日积月累,心里也是各种欢喜,坚定了要一读到底的决心。(虽然实用与否依然需要项目的磨练)
今天将之前没写的几个模式补上。首先来讲讲,跌到模式和组合模式。
心法(8):迭代模式。
说起这个迭代模式,其实跟我们平时用到的for循环很类似,应该说,是把for循环给抽象化,忽略实际的遍历过程,在client code端直接通过moveNext和hasNext来实现遍历整个数据结构。这里说是数据结构,其实在代码中就是表现成类实例的结构。
心法(9):组合模式。
当我们需要把几个相关的类组合成一个树状结构时,便可以通过组合模式,将那些类的实例,通过统一的接口进行组织,
由于组合模式从某种程度上依赖于迭代模式的实现,因此,我将两者代码合并在一起。
以下是代码:
Component(这就是需要组织成树状结构的类)
虚基类,用于concrete class继承,其中每个方法都定义一个默认的实现----抛出一个不支持的实现
public abstract class MenuComponent { public String getDescription(){ throw new UnsupportedOperationException(); } public String getName(){ throw new UnsupportedOperationException(); } public void add(MenuComponent mc){ throw new UnsupportedOperationException(); } public void remove(MenuComponent mc){ throw new UnsupportedOperationException(); } public MenuComponent getChild(int index){ throw new UnsupportedOperationException(); } public Iterator<MenuComponent> createIterator(){ throw new UnsupportedOperationException(); } }
两个concrete class
Menu,compose了一个MenuComponent的集合,说明menu可以充当一个容器。
public class Menu extends MenuComponent{ ArrayList<MenuComponent> items=new ArrayList<>(); String description; String name; public Menu(String des,String name){ this.description=des; this.name=name; } public String getDescription(){ return this.description; } public String getName(){ return this.name; } public void add(MenuComponent mc){ items.add(mc); } public void remove(MenuComponent mc){ if(items.contains(mc)){ items.remove(mc); } } public MenuComponent getChild(int index){ return items.get(index); } public Iterator<MenuComponent> createIterator(){ return new CompositeIterator(items.iterator()); } }
MenuItem:这只是一个MenuComponent最基础的单元,可以作为menu的子项。
public class MenuItem extends MenuComponent { String name; String description; public MenuItem(String name,String des){ this.name=name; this.description=des; } public String getDescription(){ return this.description; } public String getName(){ return this.name; } public Iterator<MenuComponent> createIterator(){ return new NullIterator(); } }
Iterator:
CompositeIterator:用于遍历树状结构的实例集合
public class CompositeIterator implements Iterator<MenuComponent> { Stack<Iterator<MenuComponent>> itemStack=new Stack<>(); public CompositeIterator(Iterator<MenuComponent> iterator) { // TODO Auto-generated constructor stub itemStack.add(iterator); } @Override public boolean hasNext() { // TODO Auto-generated method stub if(itemStack.size()==0){ return false; }else{ Iterator<MenuComponent> iter=itemStack.peek(); if(!iter.hasNext()){ itemStack.pop(); return hasNext(); }else{ return true; } } } @Override public MenuComponent next() { // TODO Auto-generated method stub if(hasNext()){ Iterator<MenuComponent> iter=itemStack.peek(); MenuComponent mc=iter.next(); if(mc instanceof Menu){ itemStack.add(mc.createIterator()); } return mc; }else{ return null; } } @Override public void remove() { // TODO Auto-generated method stub throw new UnsupportedOperation(); } }
NullIterator:由于MenuItem是最基础的子项,因此对他迭代是无意义的,因此创建此类,并相应的返回false和null。
public class NullIterator implements Iterator<MenuComponent> { @Override public boolean hasNext() { // TODO Auto-generated method stub return false; } @Override public MenuComponent next() { // TODO Auto-generated method stub return null; } @Override public void remove() { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } }
Waitress:用于遍历整个对象集合的client code。
public class Waitress { MenuComponent menus; public Waitress(MenuComponent mc){ this.menus=mc; } public void printAll(){ Iterator<MenuComponent> iter=menus.createIterator(); while(iter.hasNext()){ MenuComponent mc=iter.next(); System.out.println(mc.getName()+" "+mc.getDescription()); } } }
Main函数:
public static void main(String[] args) { // TODO Auto-generated method stub Menu m1 = new Menu("aaa", "a"); Menu m2 = new Menu("bbb", "b"); Menu m3 = new Menu("ccc", "c"); Menu all=new Menu("all", "all"); all.add(m1); m1.add(m2); m2.add(m3); m3.add(new MenuItem("item", "item")); Waitress w=new Waitress(all); w.printAll(); }
如图中所示,这就是我们创建的menu结构图,当我们需要对这个整个结构进行遍历的时候,就需要用到composite iterator类。使用递归的实现,进行遍历。
(PS:但是这里的递归实现是有问题的,当运行main函数的时候,会发现item被显示了5次,ccc被显示了2次,而我们的本意则是每个子项只显示一次。因此这里一的算法肯定错了,我已经在论坛里面挂了贴----------(请猛戳这里!!
) 希望能得到大牛前辈们的指点,算法确实基础不是很好,决定设计模式结束之后开始重新复习数据结构和算法)
这里贴下结构截图,结果显示不是正确,但至少这个模式是对的。
a aaa b bbb c ccc item item item item c ccc item item item item item item
这里要提一个设计模式,就是A class should have only one reason to change. 其实也就是one class,one responsibility。 对于以上的设计,每个menu除了负责本身menu的getter和setter之外就是createIterator方法,这个方法本就是menu的职责之内,而menu并不负责对整个树状结构的遍历,其实现是交给了composite
iterator,即composite iterator仅仅只是用来遍历树状结构的对象集,但他并不知道他处理的是menu还是menuitem,只是一个menucomponent。(depend on abstraction,not concrete class)
对于组合模式和迭代模式的学习就暂且到这。今后将利用项目中的实际操作经验,来完善对这两个模式的理解。
相关文章推荐
- 设计模式学习(七)----迭代和组合
- Android设计模式初学:组合模式
- 【初学设计模式】Composite (组合)
- [设计模式]组合模式
- 设计模式初学结束
- C++设计模式之组合模式
- 设计模式之第22章-组合模式(Java实现)
- Java设计模式----组合模式(Composit )
- 设计模式Before-after之组合模式
- 【初学设计模式】Facade (外观)
- 组合模式--设计模式解析与实战(关爱名 何红辉)笔记
- 设计模式-组合模式(Component)
- Java设计模式——组合模式(Composite Pattern)
- 设计模式之Composite(组合)
- 窥视设计模式之组合模式(composite)
- 设计模式之组合模式
- JAVA设计模式十七:--Composite(组合模式)
- 设计模式笔记九:组合模式
- 设计模式C++描述----11.组合(Composite)模式
- 设计模式之组合模式(composite)