Head First 设计模式 --9 迭代器模式 组合模式
迭代器模式:提供一种方法书序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
用到的设计原则:
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 ),组合模式主要是用在树形结构中。
一般情况下,组合模式和迭代器模式搭配使用(获取所有子节点的地方)。
Head First 设计模式 --9 迭代器模式 组合模式的更多相关文章
- 《Head First 设计模式》之迭代器与组合模式——遍历合并的菜单
迭代器与组合模式(Iterator & Composite) 迭代器:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 组合:允许你将对象组成树形结构来表现“整体.部分” ...
- 设计模式(七)组合模式Composite(结构型)
设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...
- Java设计模式(8)组合模式(Composite模式)
Composite定义:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Composite就应该想到树 ...
- 【HeadFirst设计模式】9.迭代器与组合模式
迭代器: 定义: 提供一种方法,顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示.(不让你知道我内部是如何聚合的) 把游走的任务放在迭代器上,而不是聚合上.这样简化了聚合的接口和实现,也让责任 ...
- 《Head First 设计模式》学习笔记——迭代模式 + 组合模式
迭代模式设置共生死亡,一般来说.我们只是想实现一个集,我们需要的同时提供这个集合的迭代器,喜欢java中间Collection.List.Set.Map等,这些集合都有自己的迭代器.假如我们要实现一个 ...
- 设计模式(十)组合模式(Composite Pattern)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- js设计模式(六)---组合模式
组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构.除了用来表示树形结构之外,组合模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性.基本图例 1.组合模式 ...
- 设计模式08: Composite 组合模式(结构型模式)
Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...
- 设计模式-(11)组合模式 (swift版)
一,概念 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...
随机推荐
- C++笔记----构造函数与析构函数(二)
构造函数是一种特殊的成员函数.在创建对象的时候自动调用,对对象的数据成员进行初始化. (1)栈区中创建的对象,在生存期结束的时候会自动调用析构函数. (2) 在堆上创建的对象,要由程序员显示调用del ...
- 关于ios8模拟器不能输入中文问题以及软键盘不弹出问题
在Xcode菜单栏中 Product->scheme->Edit Scheme->Options->Application Region改为中国,就可以输入中文了, 如果软 ...
- 《奥威Power-BI智能分析报表制作方法》精彩回顾
年的最后一个月,一年又快过去.工作和学习都不能耽误,本周三奥威公开课又如约与大家见面咯!不知老师教的图文报表在课后你们都有练习吗?趁热打铁,我们现在再次来温习一下吧. 本期分享的内容:<奥威Po ...
- 对于字符串拼接,string.format、stringbuilder、+=
sring拼接经常会用到,拼接时候使用的方法,每个人的又不一样,有的是不知道哪个效率高,也有一些是为了方便不差那么一点时间! 今天百度查了查他们的区别! += 是效率最低的一个,尽量避免使用,当然,不 ...
- ubuntu 16.04 忘记root密码的处理方法
1.开机按ESC,出现如下界面 2.按回车键进入如下界面,然后选中有recovery mode的选项 3.按e进入如下界面,并找到图中红色框的recovery nomodeset,并在这一行的后面输入 ...
- 关于HTML中标签<a>使用js的注意事项
以下两点都不可取: 1.<a href="#" onClick="popUp('http://www.baidu.com');return false;" ...
- AndroidStudio第一个项目HelloWorld
实验内容 在Android Studio中创建项目 创建并启动Android模拟器 项目的编译和运行 实验要求 在安装好的AndroidStudio上建立第一个工程 创建并启动Android模拟器 编 ...
- excel转换日期格式,将yyyymmdd类型日期转换成yyyy-mm-dd等日期类型方法
源数据日期格式:例如: 20160420 20160422 目标日期格式类型: 2016-4-20 2016-4-22 或 2016/04/20 2016/04/22 方法: 一.选中相应数据的单元格 ...
- QQ 图片
http://wpa.qq.com/pa?p=2:QQ号码:45 查看QQ是否在线,或者图片,在这里,其他的另行百度. <!-- tencent://message/?uin=763999883 ...
- 如何保存CONSOLE LOG
很早以前就想过问题,但因为我们一直有自动化程序去做,所以没仔细研究. 今天学习了一下,其实很简单,在sdsf.da 里面搜索master会看到下面这样一个TASK *MASTER* STC0000 ...