/** * * 复合模式-->在一个解决方案中结合两个或者多个模式,以解决一般或者重复发生的问题 * 模式-->是在某种情境下,针对某种问题的某种解决方案 * 模式类目完整的描述设计模式 * 三次规则:当你的模式在真实世界中的三个方案中成功的运用 * * OO原则 * 封装变化 * 多用组合 少用继承 * 针对接口编程 而非实现 * 为交互对象之间的松耦合设计而努力 * 对扩展开放 对修改关闭 * 依赖抽象 而不是具体实现 * 只和你的朋友交谈 * 好莱坞法则-->别找我 我会找你 * 类应该只有一个改变的理由 * * 模式分类 * 创建型(5个):单例模式(确保类只有一个对象被创建,并提供一个全局的访问点)、原型模式(当创建给定类的实例的过程很复杂或者很昂贵时 * )、工厂方法(由子类决定要创建的类是哪一个)、抽象工厂(创建依赖的对象家族 * ,而又无需指定具体的类)、生成器模式(封装一个产品的构造过程,并允许按步骤构造) * * 结构型(7个):装饰模式(包装一个对象,以提供更多的行为)、代理模式(包装对象,以提供对这个对象的访问 * )、组合模式(用一致的方式处理对象集合和单个对象)、 * 外观模式(简化一群类的接口)、适配器模式(封装对象,提供不同的接口)、蝇量模式(一个实例提供许多虚拟实例)、桥接模式(独立改变实现和抽象) * * 行为型(11个):策略模式(将可变的行为封装起来 * ,使用委托决定使用哪一个)、状态模式(封装了可变的状态,使用委托在行为间切换)、模板方法(由子类决定实现算法中的某个步骤 * )、迭代器模式(在集合之间迭代,而又无需暴露集合的实现 * )、命令模式(封装请求为对象)、观察者模式(让对象能够在状态改变时被通知)、责任链模式(为某个请求创建对象链 * )、解释器模式(为语言创建解释器)、中介者模式(控制对象之间复杂的沟通)、备忘录模式(返回对象之前的状态)、访问者模式(为组合增加新的行为) * * 反模式:告诉你如何采用一个不好的解决方案解决一个问题 * * 复合模式示例: 鸭子模拟器 由抽象工厂模式创建鸭子 由装饰模式为鸭子添加附加行为 由组合模式管理鸭子组合 由迭代模式遍历鸭子和鸭子组合 由观察者模式观察鸭子的行为 * 由适配器模式将鹅转变为鸭子 * * @author Administrator * */
上面即是OO设计原则和23中设计模式 示例演示复合模式代码
下一本设计模式书籍 《敏捷软件开发 原则、模式和实践》
先是 观察者模式中的主题接口
/** * */ package com.undergrowth.compound; /** * 可观察者或者称之为主题 * 注册、移除、通知观察者 * * @author Administrator * */ public interface QuackObservable { public void registerObserver(Observer observer); public void removeObserver(Observer observer); public void notifyObservers(); }
具体的主题
/** * */ package com.undergrowth.compound; import java.util.ArrayList; import java.util.List; /** * 可观察者辅助类 用于管理观察者 移除观察者 通知观察者 * @author Administrator * */ public class ObservableAssist implements QuackObservable { List<Observer> listObservers=new ArrayList<>(); QuackObservable quackObservable; /** * */ public ObservableAssist(QuackObservable quackObservable) { // TODO Auto-generated constructor stub this.quackObservable=quackObservable; } /* (non-Javadoc) * @see com.undergrowth.compound.QuackObservable#registerObserver(java.util.Observer) */ @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub listObservers.add(observer); } /* (non-Javadoc) * @see com.undergrowth.compound.QuackObservable#removeObserver(java.util.Observer) */ @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub if (listObservers.contains(observer)) { listObservers.remove(observer); } } /* (non-Javadoc) * @see com.undergrowth.compound.QuackObservable#notifyObservers() */ @Override public void notifyObservers() { // TODO Auto-generated method stub for (Observer observer : listObservers) { //通知观察者 observer.update(quackObservable); } } }
鸭子的接口
package com.undergrowth.compound; /** * * 复合模式-->在一个解决方案中结合两个或者多个模式,以解决一般或者重复发生的问题 * 模式-->是在某种情境下,针对某种问题的某种解决方案 * 模式类目完整的描述设计模式 * 三次规则:当你的模式在真实世界中的三个方案中成功的运用 * * OO原则 * 封装变化 * 多用组合 少用继承 * 针对接口编程 而非实现 * 为交互对象之间的松耦合设计而努力 * 对扩展开放 对修改关闭 * 依赖抽象 而不是具体实现 * 只和你的朋友交谈 * 好莱坞法则-->别找我 我会找你 * 类应该只有一个改变的理由 * * 模式分类 * 创建型(5个):单例模式(确保类只有一个对象被创建,并提供一个全局的访问点)、原型模式(当创建给定类的实例的过程很复杂或者很昂贵时 * )、工厂方法(由子类决定要创建的类是哪一个)、抽象工厂(创建依赖的对象家族 * ,而又无需指定具体的类)、生成器模式(封装一个产品的构造过程,并允许按步骤构造) * * 结构型(7个):装饰模式(包装一个对象,以提供更多的行为)、代理模式(包装对象,以提供对这个对象的访问 * )、组合模式(用一致的方式处理对象集合和单个对象)、 * 外观模式(简化一群类的接口)、适配器模式(封装对象,提供不同的接口)、蝇量模式(一个实例提供许多虚拟实例)、桥接模式(独立改变实现和抽象) * * 行为型(11个):策略模式(将可变的行为封装起来 * ,使用委托决定使用哪一个)、状态模式(封装了可变的状态,使用委托在行为间切换)、模板方法(由子类决定实现算法中的某个步骤 * )、迭代器模式(在集合之间迭代,而又无需暴露集合的实现 * )、命令模式(封装请求为对象)、观察者模式(让对象能够在状态改变时被通知)、责任链模式(为某个请求创建对象链 * )、解释器模式(为语言创建解释器)、中介者模式(控制对象之间复杂的沟通)、备忘录模式(返回对象之前的状态)、访问者模式(为组合增加新的行为) * * 反模式:告诉你如何采用一个不好的解决方案解决一个问题 * * 复合模式示例: 鸭子模拟器 由抽象工厂模式创建鸭子 由装饰模式为鸭子添加附加行为 由组合模式管理鸭子组合 由迭代模式遍历鸭子和鸭子组合 由观察者模式观察鸭子的行为 * 由适配器模式将鹅转变为鸭子 * * @author Administrator * */ public interface Quackable extends QuackObservable { public void quack(); }
具体的鸭子实现类
北京鸭 将主题的添加、移除、通知观察者的工作交给主题的辅助类进行处理
package com.undergrowth.compound; /** * 北京鸭 * @author Administrator * */ public class BeiJingDuck implements Quackable { //将添加、移除、通知观察者的任务委托给辅助类进行处理 QuackObservable quackObservable; public BeiJingDuck() { this.quackObservable = new ObservableAssist(this); } @Override public void quack() { // TODO Auto-generated method stub System.out.println(BeiJingDuck.class.getName()+" "+"北京鸭,quack"); notifyObservers(); } @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub quackObservable.registerObserver(observer); } @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub quackObservable.registerObserver(observer); } @Override public void notifyObservers() { // TODO Auto-generated method stub quackObservable.notifyObservers(); } }
绿头鸭
package com.undergrowth.compound; /** * 绿头鸭 * * @author Administrator * */ public class MallardDuck implements Quackable { // 将添加、移除、通知观察者的任务委托给辅助类进行处理 QuackObservable quackObservable; public MallardDuck() { this.quackObservable = new ObservableAssist(this); } @Override public void quack() { // TODO Auto-generated method stub System.out.println(MallardDuck.class.getName() + " " + "绿头鸭,quack"); notifyObservers(); } @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub quackObservable.registerObserver(observer); } @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub quackObservable.registerObserver(observer); } @Override public void notifyObservers() { // TODO Auto-generated method stub quackObservable.notifyObservers(); } }
红头鸭
package com.undergrowth.compound; /** * 红头鸭 * @author Administrator * */ public class RedheadDuck implements Quackable { //将添加、移除、通知观察者的任务委托给辅助类进行处理 QuackObservable quackObservable; public RedheadDuck() { this.quackObservable = new ObservableAssist(this); } @Override public void quack() { // TODO Auto-generated method stub System.out.println(RedheadDuck.class.getName()+" "+"红头鸭,quack"); notifyObservers(); } @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub quackObservable.registerObserver(observer); } @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub quackObservable.removeObserver(observer); } @Override public void notifyObservers() { // TODO Auto-generated method stub quackObservable.notifyObservers(); } }
鸭群 组合模式
/** * */ package com.undergrowth.compound; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 一群鸭子 * 组合节点与叶子节点 * 组合节点中可以存放叶子节点,也可存放组合节点,从而构件树形结构 * 组合节点与叶子节点具有不同的行为 这样安全性更好,但是对于客户端而言 透明性就相对降低了 * @author Administrator * */ public class FlockDuck implements Quackable { List<Quackable> flockQuackables=new ArrayList<>(); /** * */ public FlockDuck() { // TODO Auto-generated constructor stub } public void add(Quackable quackable){ flockQuackables.add(quackable); } /* (non-Javadoc) * @see com.undergrowth.compound.Quackable#quack() */ @Override public void quack() { // TODO Auto-generated method stub //递归迭代 内部迭代器 for (Iterator iterator = flockQuackables.iterator(); iterator.hasNext();) { Quackable quackable = (Quackable) iterator.next(); quackable.quack(); } } /** * 向一个组群添加注册时 是向每一个元素添加注册 * * * * */ @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub for (Quackable quackable : flockQuackables) { quackable.registerObserver(observer); } } @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub for (Quackable quackable : flockQuackables) { quackable.removeObserver(observer); } } /** * 委托给每一个叶子节点处理通知事件 */ @Override public void notifyObservers() { // TODO Auto-generated method stub } }
鸭子的装饰类 装饰模式
/** * */ package com.undergrowth.compound; /** * 鸭子装饰器 添加计数行为 * @author Administrator * */ public class QuackCount implements Quackable { private static int count=0; Quackable quackable; /** * */ public QuackCount() { // TODO Auto-generated constructor stub } public QuackCount(Quackable quackable) { // TODO Auto-generated constructor stub this.quackable=quackable; } /* (non-Javadoc) * @see com.undergrowth.compound.Quackable#quack() */ @Override public void quack() { // TODO Auto-generated method stub quackable.quack(); System.out.println("第"+(++count)+"次叫"); } public static int getCount() { return count; } @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub quackable.registerObserver(observer); } @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub quackable.removeObserver(observer); } @Override public void notifyObservers() { // TODO Auto-generated method stub quackable.notifyObservers(); } }
抽象工厂 创建鸭子和鸭群
package com.undergrowth.compound; /** * 抽象工厂 创建鸭子 * @author Administrator * */ public abstract class AbstractDuckFactory { public abstract Quackable createMallardDuck(); public abstract Quackable createRedheadDuck(); public abstract Quackable createBeiJingDuck(); public abstract Quackable createFlockDuck(); }
装饰器鸭子
package com.undergrowth.compound; /** * 使用装饰器创建鸭子 * @author Administrator * */ public class CountingDuckFactory extends AbstractDuckFactory { @Override public Quackable createMallardDuck() { // TODO Auto-generated method stub return new QuackCount(new MallardDuck()); } @Override public Quackable createRedheadDuck() { // TODO Auto-generated method stub return new QuackCount(new RedheadDuck()); } @Override public Quackable createBeiJingDuck() { // TODO Auto-generated method stub return new QuackCount(new BeiJingDuck()); } @Override public Quackable createFlockDuck() { // TODO Auto-generated method stub return null; } }
鸭子工厂
package com.undergrowth.compound; /** * 鸭子工厂 创建不同种类的鸭子 * @author Administrator * */ public class DuckFactory extends AbstractDuckFactory { @Override public Quackable createMallardDuck() { // TODO Auto-generated method stub return new MallardDuck(); } @Override public Quackable createRedheadDuck() { // TODO Auto-generated method stub return new RedheadDuck(); } @Override public Quackable createBeiJingDuck() { // TODO Auto-generated method stub return new BeiJingDuck(); } @Override public Quackable createFlockDuck() { // TODO Auto-generated method stub return new FlockDuck(); } }
鹅的叫声 接口
/** * */ package com.undergrowth.compound; /** * 扎扎叫 * @author Administrator * */ public interface Creak { public void creak(); }
鹅实现类
package com.undergrowth.compound; /** * 鹅 * @author Administrator * */ public class Goose implements Creak { @Override public void creak() { // TODO Auto-generated method stub System.out.println(Goose.class.getName()+" "+"鹅,扎扎叫"); } }
/** * */ package com.undergrowth.compound; /** * 鹅适配器 将鹅转换为鸭子 * @author Administrator * */ public class GooseAdapter implements Quackable { Creak creak; public GooseAdapter(Creak creak) { // TODO Auto-generated constructor stub this.creak=creak; } /* (non-Javadoc) * @see com.undergrowth.compound.Quackable#quack() */ @Override public void quack() { // TODO Auto-generated method stub creak.creak(); } @Override public void registerObserver(Observer observer) { // TODO Auto-generated method stub } @Override public void removeObserver(Observer observer) { // TODO Auto-generated method stub } @Override public void notifyObservers() { // TODO Auto-generated method stub } }
观察者模式的观察者接口
/** * */ package com.undergrowth.compound; /** * 观察者 * @author Administrator * */ public interface Observer { public void update(QuackObservable quackObservable); }
观察者
/** * */ package com.undergrowth.compound; /** * 鸭子医生 观察鸭子的叫行为 * @author Administrator * */ public class DuckDoctor implements Observer { /** * */ public DuckDoctor() { // TODO Auto-generated constructor stub } /* (non-Javadoc) * @see com.undergrowth.compound.Observer#update(com.undergrowth.compound.QuackObservable) */ @Override public void update(QuackObservable quackObservable) { // TODO Auto-generated method stub System.out.println(DuckDoctor.class.getName()+" 观察到的鸭子的对象为:"+quackObservable); } }
测试代码
package com.undergrowth.compound.test; import static org.junit.Assert.*; import org.junit.Test; import com.undergrowth.compound.AbstractDuckFactory; import com.undergrowth.compound.CountingDuckFactory; import com.undergrowth.compound.Creak; import com.undergrowth.compound.DuckDoctor; import com.undergrowth.compound.DuckFactory; import com.undergrowth.compound.FlockDuck; import com.undergrowth.compound.Goose; import com.undergrowth.compound.GooseAdapter; import com.undergrowth.compound.Observer; import com.undergrowth.compound.Quackable; public class DuckTest { @Test public void test() { System.out.println("=====================测试抽象工厂===================="); AbstractDuckFactory duckFactory = new DuckFactory(); // 绿头鸭 Quackable quackable = duckFactory.createMallardDuck(); quack(quackable); // 红头鸭 quackable = duckFactory.createRedheadDuck(); quack(quackable); // 北京鸭 quackable = duckFactory.createBeiJingDuck(); quack(quackable); System.out.println("=====================测试抽象工厂===================="); System.out.println("=====================测试适配器===================="); // 将鹅转换为鸭子 Creak creak = new Goose(); quack(new GooseAdapter(creak)); System.out.println("=====================测试适配器===================="); System.out.println("=====================测试装饰器===================="); // 为鸭子添加叫声的计数行为 duckFactory = new CountingDuckFactory(); // 北京鸭 quackable = duckFactory.createBeiJingDuck(); quack(quackable); // 绿头鸭 quackable = duckFactory.createMallardDuck(); quack(quackable); // 红头鸭 quackable = duckFactory.createRedheadDuck(); quack(quackable); System.out.println("=====================测试装饰器===================="); System.out.println("=====================测试组合模式===================="); duckFactory = new DuckFactory(); //创建鸭子组合 FlockDuck flockQuackable=(FlockDuck) duckFactory.createFlockDuck(); // 绿头鸭 quackable = duckFactory.createMallardDuck(); flockQuackable.add(quackable); // 红头鸭 quackable = duckFactory.createRedheadDuck(); flockQuackable.add(quackable); // 北京鸭 quackable = duckFactory.createBeiJingDuck(); flockQuackable.add(quackable); flockQuackable.quack(); System.out.println("=====================测试组合模式===================="); System.out.println("=====================测试观察者模式===================="); //可观察者 quackable=duckFactory.createMallardDuck(); //观察者 Observer observer=new DuckDoctor(); quackable.registerObserver(observer); quackable.quack(); //群组观察 flockQuackable.registerObserver(observer); flockQuackable.quack(); System.out.println("=====================测试观察者模式===================="); } private void quack(Quackable quackable) { // TODO Auto-generated method stub quackable.quack(); } }
控制台输出
=====================测试抽象工厂==================== com.undergrowth.compound.MallardDuck 绿头鸭,quack com.undergrowth.compound.RedheadDuck 红头鸭,quack com.undergrowth.compound.BeiJingDuck 北京鸭,quack =====================测试抽象工厂==================== =====================测试适配器==================== com.undergrowth.compound.Goose 鹅,扎扎叫 =====================测试适配器==================== =====================测试装饰器==================== com.undergrowth.compound.BeiJingDuck 北京鸭,quack 第1次叫 com.undergrowth.compound.MallardDuck 绿头鸭,quack 第2次叫 com.undergrowth.compound.RedheadDuck 红头鸭,quack 第3次叫 =====================测试装饰器==================== =====================测试组合模式==================== com.undergrowth.compound.MallardDuck 绿头鸭,quack com.undergrowth.compound.RedheadDuck 红头鸭,quack com.undergrowth.compound.BeiJingDuck 北京鸭,quack =====================测试组合模式==================== =====================测试观察者模式==================== com.undergrowth.compound.MallardDuck 绿头鸭,quack com.undergrowth.compound.DuckDoctor 观察到的鸭子的对象为:com.undergrowth.compound.MallardDuck@b524aa com.undergrowth.compound.MallardDuck 绿头鸭,quack com.undergrowth.compound.DuckDoctor 观察到的鸭子的对象为:com.undergrowth.compound.MallardDuck@7a3a30 com.undergrowth.compound.RedheadDuck 红头鸭,quack com.undergrowth.compound.DuckDoctor 观察到的鸭子的对象为:com.undergrowth.compound.RedheadDuck@825cf3 com.undergrowth.compound.BeiJingDuck 北京鸭,quack com.undergrowth.compound.DuckDoctor 观察到的鸭子的对象为:com.undergrowth.compound.BeiJingDuck@a47cc3 =====================测试观察者模式====================
前面设计模式的代码和本文的模式代码 在此有下载 http://download.csdn.net/detail/undergrowth/8306683