《Head First设计模式》阅读笔记.第九章

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();
}
}


测试结果:
[quote]: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
[/quote]

--END--
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值