1.迭代器(Iterator)模式部分
----Sharpen Your Pencil解答----
A、C、D、E
------------
*当我们说“集合(Collection)”的时候,我们指的是一群对象。其存储方式可以是各式各样的数据结构,例如:列表、数组、散列表,无论用什么方式存储,一律可以视为集合。有时候也被称为聚合(aggregate)。
----习题解答----
public class PancakeHouseIterator implements Iterator {
private List items;
private int position = 0;
public PancakeHouseIterator(List items) {
this.items = items;
}
public Object next() {
position += 1;
return items.get(position);
}
public boolean hasNext() {
if(position >= items.size()){
return false;
} else {
return true;
}
}
}
public class PancakeHouseMenu {
ArrayList menuItems;
// 这里是构造器
// 这里是addItem()方法
// 删除此方法
//public ArrayList getMenuItems() {
// return menuItems;
//}
// 新增的方法
public Iterator createIterator() {
return new PancakeHouseIterator(menuItems);
}
// 其他方法
}
------------
*在实现java.util.Iterator接口时,如果不需要remove()方法,可以跑出java.lang.UnsupportedOperationException异常。
迭代器模式:提供一种顺序访问集合对象中各个元素的方法,而又不暴露其内部的表示(也就是数据结构)。
*迭代器(Iterator)模式把元素之间游走的任务交给了迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也让它专注于管理对象,而不必理会遍历的事情。
----Brain Power解答----
工厂方法(Factory Method)模式
------------
*类的每个责任都有一个潜在的改变区域,多一个责任就意味着多一个改变的区域。要尽量让每个类保持单一责任。
软件设计原则:一个类应该只有一个引起变化的原因。
*既要让每个类都保持单一的责任,也要保证一个责任只指派给一个类。
*内聚(Cohesion)用来度量一个类或模块紧密地达到单一目的或责任的程度。
*当一个类或模块被设计成只支持一组相关功能时,我们说它具有高内聚;反之,当被设计成支持一组不相关的功能时,我们说它具有低内聚。
----Brain Power解答----
具有多重责任的类:Game、Person、DeckOfCards、ShoppingCart、Iterator
------------
----Brain Power 2解答----
低内聚类:Game
高内聚类:GameSession、PlayerActions、Player
------------
----Sharpen Your Pencil解答---
1、定义一个迭代器类,实现咖啡厅菜单的遍历
2、删除CafeMenu类的getItems()方法
3、让CafeMenu类继承Menu接口并实现createIterator()方法
------------
*框架(framework)指一群类和接口。
*在Java 5中新增了一种“for/in”语句支持对集合类的遍历。形式如下:
for(Object obj:collection) {
obj.methodName();
...
}
----代码贴解答----
import java.util.Iterator;
import java.util.Calendar;
public class AlternatingDinerMenuIterator implements Iterator {
MenuItem[] items;
int position;
public AlternatingDinerMenuIterator(MenuItem[] items) {
this.items = items;
Calendar rightNow = Calendar.getInstance();
position = rightNow.get(Calendar.DAY_OF_WEEK) % 2;
}
public boolean hasNext() {
if (position >= items.length || items[position] == null) {
return false;
} else {
return true;
}
}
public Object next() {
MenuItem menuItem = items[position];
position = position + 2;
return menuItem;
}
public void remove() {
throw new UnsupportedOperationException("Alternating Diner Menu Iterator does not support remove()");
}
}
------------
----Brain Power解答----
修改女招待类如下:
public class Waitress {
MenuItem[] menus;
public Waitress(MenuItem[] menus) {
this.menus = menus;
}
public void printMenu() {
for(MenuItem menu: menus) {
printMenu(menu.createIterator());
}
}
private void printMenu(Iterator items) {
while(items.hasNext()) {
MenuItem item = (MenuItem)items.next();
...
}
}
}
------------
2.组合(Composite)模式部分
组合模式:将对象组合成树状结构来表现“整体/部分”的层级结构,让客户以一致的方式来处理个别对象以及对象组合。
*在树状结构中,带有子元素的元素成为节点(Node);没有子元素的元素成为叶节点(Leaf)。
*组合(Composite)模式牺牲了单一责任设计原则,换取了透明性(Transprency)。
----Brain Power解答----
从上到下,从左到右一次遍历树结构的所有节点。
------------
*空迭代器(Iterator)是空对象(null object)“设计模式”的又一个例子,之前的例子是“空命令(NullCommand)”。
----空迭代器实例----
public class NullIterator implements Iterator {
public boolean hasNext() {
return false;
}
public Object next() {
return null;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
------------
*“空对象设计模式”带来的好处是客户不用处理null,因此不必担心系统会跑出NullPointerException。
*当多个对象彼此之间有“整体/部分”的关系,并且你想用一致的方式处理这些对象时(就是让它们看起来一样,有共同的方法可以调用),就需要用组合(Composite)模式。
*包含其它组件的组件被称为组合对象,没有包含其它组件的组件被称为叶节点对象。
*组合通常是树形结构,也就是一种层次结构,根就是顶层的组合,往下是它的孩子,最末端是叶节点。
*为了更方便操作,比如把一个子节点从它的父节点删除,可以让子节点保存到父节点的一个引用。
*在组合中加入缓存可以提高遍历的性能。
----连连看解答----
策略->封装可互换的行为,并用委托决定使用哪一个
适配器->改变一个或多个类的接口
迭代器->提供一个方式来遍历组合,而无需暴露组合的实现
外观->简化一群类的接口
组合->客户可以将对象的组合以及个别对象一视同仁
观察者->当某个状态改变时,允许一群对象能被通知到
------------
3.迭代器(Iterator)模式与组合(Compsite)模式小结
*迭代器允许访问聚合的元素,而不需要暴露它内部的结构。
*迭代器将遍历聚合的工作封装进一个对象里。
*当使用迭代器时,我们依赖聚合提供遍历。
*迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
*我们应该努力让一个类只分配一个责任。
*组合模式提供一个结构,可同时包容个别对象和组合对象。
*组合对象允许客户对个别对象和组合对象一视同仁。
*组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点。
*在实现组合模式时,有许多设计上的折中;要根据需要平衡透明性和安全性。
4.迭代器(Iterator)模式实例
//迭代器接口
public interface Iterator {
public boolean hasNext();
public Object next();
}
//数组迭代器
public class ArrayIterator implements Iterator {
private Object[] objects;
private int position = 0;// 当前位置
public ArrayIterator(Object[] objects) {
this.objects = objects;
}
public boolean hasNext() {
return position < objects.length - 1;
}
public Object next() {
Object retObj = objects[position];
position += 1;
return retObj;
}
}
// List迭代器
public class ListIterator implements Iterator {
private java.util.Iterator iter;
public ListIterator(List list) {
this.iter = list.iterator();
}
public boolean hasNext() {
return iter.hasNext();
}
public Object next() {
return iter.next();
}
}
5.组合(Composite)模式实例
基于以上代码实现:
// 菜单接口
public interface IMenu {
// 取得名称
public String getName();
// 显示
public void display();
// 添加菜单
public void addItem(IMenu menu);
// 取得所有子菜单
public Iterator getChildren();
}
// 菜单
public class Menu implements IMenu {
private List<IMenu> items = new ArrayList<IMenu>();
private String name;
public Menu(String name) {
this.name = name;
}
public void addItem(IMenu menu) {
items.add(menu);
}
public void display() {
System.out.println(this.name + ":Menu");
Iterator children = this.getChildren();
while (children.hasNext()) {
IMenu menu = (IMenu) children.next();
menu.display();
}
}
public Iterator getChildren() {
return new ListIterator(items);
}
public String getName() {
return this.name;
}
}
// 菜单项
public class MenuItem implements IMenu {
private String name;
public MenuItem(String name) {
this.name = name;
}
public void display() {
System.out.println(this.name + ":MenuItem");
}
public String getName() {
return this.name;
}
public void addItem(IMenu menu) {
throw new UnsupportedOperationException();
}
public Iterator getChildren() {
return new NullIterator();
}
}
// 菜单条
public class MenuBar {
private List<IMenu> menus = new ArrayList<IMenu>();
public void addMenu(IMenu menu) {
this.menus.add(menu);
}
public void display() {
System.out.println(":MenuBar");
Iterator items = new ListIterator(menus);
while (items.hasNext()) {
IMenu menu = (IMenu) items.next();
menu.display();
}
}
}
// 空迭代器
public class NullIterator implements Iterator {
public boolean hasNext() {
return false;
}
public Object next() {
return null;
}
}
// 测试程序
public class TestMenuBar {
public static void main(String[] args) {
IMenu menu1 = new Menu("File");
IMenu item1 = new MenuItem(" New");
IMenu item2 = new MenuItem(" Open");
IMenu item3 = new MenuItem(" Exit");
menu1.addItem(item1);
menu1.addItem(item2);
menu1.addItem(item3);
IMenu menu2 = new Menu("Edit");
IMenu item4 = new MenuItem(" Cut");
IMenu menu3 = new Menu(" Find");
IMenu item5 = new MenuItem(" Find Next");
IMenu item6 = new MenuItem(" Find Previous");
IMenu item7 = new MenuItem(" Replace");
IMenu item8 = new MenuItem(" Copy");
menu2.addItem(item4);
menu2.addItem(menu3);
menu2.addItem(item8);
menu3.addItem(item5);
menu3.addItem(item6);
menu3.addItem(item7);
MenuBar bar = new MenuBar();
bar.addMenu(menu1);
bar.addMenu(menu2);
bar.display();
}
}
测试结果:
引用
:MenuBar
File:Menu
New:MenuItem
Open:MenuItem
Exit:MenuItem
Edit:Menu
Cut:MenuItem
Find:Menu
Find Next:MenuItem
Find Previous:MenuItem
Replace:MenuItem
Copy:MenuItem
--END--