迭代器模式:提供一种方法书序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
用到的设计原则:
1、封装变化
2、多用组合,少用继承|
3、针对接口编程,不针对实现编程
4、松耦合
5、对扩展开放,对修改关闭
6、依赖抽象,不依赖具体
7、只和朋友交谈
8、别找我,我会找你
9、类应该只有一个改变的理由
迭代器模式非常简单,直接看代码(代码的意思,PancakeHouseMenu和DinerMenu两种菜单,一个用了list一个用了数组,分别对应两种类型的Iterator方便Waitress操作菜单)
class Waitress { Menu pancakeHouseMenu; Menu dinerMenu; public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) { this.pancakeHouseMenu = pancakeHouseMenu; this.dinerMenu = dinerMenu; } public void printMenu() { Iterator<MenuItem> pancakeIterator = pancakeHouseMenu.createIterator(); Iterator<MenuItem> dinerIterator = dinerMenu.createIterator(); printMenu(pancakeIterator); printMenu(dinerIterator); } private void printMenu(Iterator<MenuItem> iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem) iterator.next(); System.out.println(menuItem.getName()); System.out.println(menuItem.getPrice()); } } } class MenuItem { String name; double price; public MenuItem(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } } interface Menu { public Iterator<MenuItem> createIterator(); } class DinerMenuIterator implements Iterator<MenuItem> { MenuItem[] items; int position; public DinerMenuIterator(MenuItem[] items) { this.items = items; } @Override public boolean hasNext() { if (position >= items.length || items[position] == null) { return false; } else { return true; } } @Override public MenuItem next() { MenuItem menuItem = items[position]; position = position + 1; return menuItem; }
public void remove() {
if (position <= 0) {
throw new IllegalStateException();
}
if (items[position - 1] != null) {
for (int i = position - 1; i < (items.length - 1); i++) {
items[i] = items[i + 1];
}
items[items.length - 1] = null;
}
}
} class DinerMenu implements Menu { static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu() { menuItems = new MenuItem[MAX_ITEMS]; addItem("diner breakfase", 1.00); } public void addItem(String name, double price) { MenuItem menuItem = new MenuItem(name, price); if (numberOfItems >= MAX_ITEMS) { System.out.println("menu is full"); } else { menuItems[numberOfItems] = menuItem; numberOfItems = numberOfItems + 1; } } public Iterator<MenuItem> createIterator() { return new DinerMenuIterator(menuItems); } } class PancakeHouseIterator implements Iterator<MenuItem> { ArrayList<MenuItem> items; int position; public PancakeHouseIterator(ArrayList<MenuItem> items) { this.items = items; } @Override public boolean hasNext() { if (position >= items.size() || items.get(position) == null) { return false; } else { return true; } } @Override public MenuItem next() { MenuItem menuItem = items.get(position); position = position + 1; return menuItem; }
public void remove() {
if (position <= 0) {
throw new IllegalStateException();
}
items.remove(position);
}
} class PancakeHouseMenu implements Menu { ArrayList<MenuItem> menuItems; public PancakeHouseMenu() { menuItems = new ArrayList<>(); addItem("pancake house breakfase", 1.00); } public void addItem(String name, double price) { MenuItem menuItem = new MenuItem(name, price); menuItems.add(menuItem); } public Iterator<MenuItem> createIterator() { return new PancakeHouseIterator(menuItems); } } public class Test { public static void main(String[] args) { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); DinerMenu dinerMenu = new DinerMenu(); Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); waitress.printMenu(); } }
类图:
虽然代码有点多,但是还是很好理解。代码多只是因为为了用一个真实点的例子,类多了点。
迭代器模式的类图:
设计原则【单一权责:一个类应该只有一个引起变化的原因】
组合模式:允许你将对向组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
组合模式可以理解为迭代器的扩展,如果菜单中还有子菜单,那么迭代器模式就无法解决了。这是就可以考虑用组合模式。
class TreeNode { private String name; private TreeNode parent; private Vector<TreeNode> children = new Vector<TreeNode>(); public TreeNode(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public TreeNode getParent() { return parent; } public void setParent(TreeNode parent) { this.parent = parent; } // 添加孩子节点 public void add(TreeNode node) { children.add(node); } // 删除孩子节点 public void remove(TreeNode node) { children.remove(node); } // 取得孩子节点 public Enumeration<TreeNode> getChildren() { return children.elements(); } } class Tree { TreeNode root = null; public Tree(String name) { root = new TreeNode(name); } } public class CompositeTest { public static void main(String[] args) { Tree tree = new Tree("A"); TreeNode nodeB = new TreeNode("B"); TreeNode nodeC = new TreeNode("C"); TreeNode nodeD = new TreeNode("D"); nodeB.add(nodeC); nodeB.add(nodeD); tree.root.add(nodeB); tree.root.getChildren(); } }
这个模式没用书里的例子( http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html ),组合模式主要是用在树形结构中。
一般情况下,组合模式和迭代器模式搭配使用(获取所有子节点的地方)。