《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 items = new ArrayList();

	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 menus = new ArrayList();

	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--

你可能感兴趣的:(设计模式,数据结构,软件测试,框架)