Java设计模式研究
来源:互联网 发布:mac废纸篓清空还原 编辑:程序博客网 时间:2024/06/08 07:20
库与框架无法帮助我们将应用组织成容易了解、容易维护、具有弹性的架构,所以需要设计模式。
模式不是发明,而是发现。模式不是代码,而是方案。
以下模式被认为是历经验证的OO设计经验。
1. 观察者模式
1) 类图
2) 定义
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它所有依赖者都会收到通知并自动更新。
3)设计原则
为了交互对象之间的松耦合设计而努力。
4)实现原理
Subject主题类是事件的主导者,通过registerObserver()注册上有需求的观察者,
通过NotifyObserver()实时更新自己状态并告知已经注册的各位观察者。
observer.update(); 由每位观察者自行处理更新的数据。
观察者构造函数里指定主题,并调用该主题的registerObserver()方法实现绑定。
public class WeatherData implements Subject {private ArrayList observers;public WeatherData() {observers = new ArrayList();}public void registerObserver(Observer o) {observers.add(0);}public void removeObserver(Observer o) {int i = observers.indexOf(o);if (i >= 0) {observers.remove(i);}}public void notifyObserver() {for (int i = 0; i < observers.size(); i++) {Observer observer = (Observer)observers.get(i);observer.update(temperature, humidity, pressure);}}}
public class CurrentCondition {private Subject weatherData;public CurrentCondition (Subject weatherData) {this.weatherData = weatherData;weatherData.registerObserver(this);}public void update(float t, float h, float p) {display(t, h, p);}}
5)点评
如果让观察者去“拉”主题的数据,这样主题会门户大开,被大肆挖掘数据,不够安全。
所以更常用的设计是主题主动“推”送数据给观察者,主题不关心观察者的具体情况,实现松耦合。
6)应用场景
一对多的关系,多个对象实时监听一个对象的状态。
系统级更常见,比如建立一个对象,监听按键,传感器数据等。
2. 策略模式
1) 类图
2) 定义
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
3)设计原则
针对接口编程,而不是针对实现编程。多用组合,少用继承。
把系统中会变化的部分抽离出来封装。
4)实现原理
在这个类中加一个接口,把行为委托给这个接口处理,
在这个接口下有各种不同的策略实现它的行为,
客户只要通过set和get动态地设置变量就可以在运行时引用正确的策略。
public abstract class Duck {FlyBehavior flyBehavior;public Duck () {}public void setFlyBehavior(FlyBehavior fb) {flyBehavior = fb;}public FlyBehavior getFlyBehavior() {return flyBehavior;} public void performFly () {flyBehavior.fly(); }}public class FlyWithWings implements FlyBehavior {public void fly() {... ...}}
5)点评
策略模式使用委托模型,增加了对象数量,使代码较复杂,但使用对象组合,所以更具有弹性。
6)应用场景
3. 状态模式
1) 类图
基本同策略模式,唯一区别在于委托的状态是一个抽象类而不是接口。
2) 定义
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
3)点评
将一群行为封装在状态对象中,context的行为随时可委托到那些状态对象中的一个,
状态是用在Context中来代表它的内部状态以及行为的,客户不会直接改变context的状态,改变状态是方案中事先定义好的。
4)应用场景
适用于同一行为在不同条件下产生不同表现的场景,把条件看成状态,或者策略。4. 装饰者模式
1) 类图
2) 定义
动态地将责任附加到对象身上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
3)设计原则
类应该对扩展开放,对修改关闭。
4)实现原理
public class Mocha extends CondimentDecorator {Beverage beverage;public Mocha(Beverage beverage) {this.beverage = beverage;}public double cost(){return .20 + beverage.cost();}}
5)点评
装饰者与被装饰者必须是同一类型,用继承达到类型匹配。
装饰者模式的设计中加入了大量的小类,会让程序变得复杂难懂。
6)应用场景
对象须要添加一个新功能,新功能具有弹性,易于修改更新替代或叠加,同时不会改变原有对象。
典型例子比如JAVA I/O里的读写功能。
5. 适配器模式
1) 类图
2) 定义
将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
3)实现原理
客户通过目标接口调用适配器的方法对适配器发出请求。
适配器把请求转换成被适配者的接口。
客户接收到调用的结果,但并未察觉适配器在中间的作用。
public class EnumerationIterator implements Iterator{Enumeration enum;public EnumerationIterator(Enumeration enum) {this.enum = enum;}public boolean hasNext() {return enum.hasMoreElements();}public Object next() {return enum.nextElement();}public void remove() {throw new UnsupportedOperationException();}}
4)点评
如果不用适配器,客户就必须改写代码来调用新的接口。
适配器允许客户使用新的库和子集合而无须改变代码,由适配器负责转换。
5)应用场景
有新的客户需求,不想改变客户代码,又想保留原有系统接口,那么考虑用适配器模式作中间层转换。6. 外观模式
1) 类图
2)定义
提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
3)设计原则
“最少知识”原则:只和你的密友谈话。
就任何对象而言,在该对象的方法内,我们只应该调用属于以下范围的方法:
- 该对象本身
- 被当做方法的参数而传递进来的对象
- 此方法所创建或实例化的任何对象
- 对象的任何组件
5)应用场景
某对象具备复杂的功能,客户希望使用简单的高层接口。
典型的例子如家庭影院系统。
7. 工厂方法模式
1) 类图
2) 定义
定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到子类。
3)设计原则
依赖倒置原则:要依赖抽象,不要依赖具体类。
不能让高层组件依赖低层组件,而且两者都应该依赖于抽象。
遵循倒置原则应注意:
- 变量不可以持有具体类的引用
- 不要让类派生自具体类
- 不要覆盖基类中已实现的方法
4)实现原理
首先声明一个工厂方法factroyMethod(),工厂方法将客户和实际创建具体产品的代码分隔开来。
子类工厂继承抽象工厂,子类工厂的工厂方法具体实现低层组件-产品。
public abstract class PizzaStore {public Pizza orderPizza(String type) {Pizza pizza;pizza = createPizza(type);pizza.prepare();pizza.bake();pizza.cut();pizza.box;return pizza;}abstract Pizza createPizza(String type);}public class NYPizzaStore extends PizzaStore {Pizza createPizza(String item) {if (item.equals("cheese")) {return new NYStyleCheesePizza();} else if (item.equals("veggie")) {return new NYStyleVeggiePizza();} else if (item.equals("clam")) {return new NYStyleClamPizza();} else if (item.equals("pepperoni")) {return new NYStylePepperoniPizza();} else return null;}}客户只要实例化具体的子类工厂,让子类工厂生产产品。
public static void main () {PizzaStore nyStore = new NYPizzaStore();Pizza pizza = nyStore.orderPizza("cheese");}
5)点评
工厂方法让子类决定要实例化的类是哪一个,选择使用哪个子类就决定了实际创建哪个产品。
将创建对象的代码集中在一个对象或方法中,可以避免代码的重复,且方便维护。
客户在实例化对象时,只会依赖于接口,而不是具体类。
除了工厂方法模式,还有抽象工厂模式,有利于创建对象的家族。
8. 单件模式
1) 定义
确保一个类只有一个实例,并提供一个全局访问点。
2)实现原理
public class Singleton {private static Singleton uniqueInstance;private Singleton() {}public static Singleton getInstance() {if (uniqueInstance == null)uniqueInstance = new Singleton();return uniqueInstance;}}
3)应用场景
独一无二的资源,比如线程池,缓存,对话框,偏好,日志,设备驱动等。
这些对象可能非常耗资源,而且初始化后程序一直没有使用它。
9. 命令模式
1) 类图
2) 定义
3)实现原理
关键要理清客户,发起者Invoker,接收者Receiver三者的关系以及命令对象Command与具体动作receiver.Action()之间的关系。
- 客户提出请求 - 客户创建一个具体命令对象,这个命令对象暴露execute()接口
- 发起者封装请求 - 发起者由setCommand()持有用户提出的具体命令,并在某个时刻调用命令对象的execute(),实施动作
- 接收者实现请求 - 具体命令对象定义了动作receiver.Action()和接收者之间的绑定关系
调用者只要调用execute()就可以发出请求,由具体命令调用接收者的一个或多个动作。
public interface Command {public void execute();}public class LightOnCommand implements Command { //具体命令Light light;public LightOnCommand(Light light) {this.light = light;}public void execute() {light.on(); // 具体动作}}public class SimpleRemoteControl { //调用者Command slot;public SimpleRemoteControl () {}public void setCommand(Command command) { //调用者持有用户的具体命令slot = command;}public void buttonWasPressed() { //实施动作的时刻slot.execute();}}public class RemoteControlTest {public static void main() {SimpleRemoteControl remote = new SimpleRemoteControl(); Light light = new Light();LightOnCommand lightOn = new LightOnCommand(light); //用户创建具体命令remote.setCommand(lightOn);remote.buttonWasPressed();}}
4)点评
一旦有新的动作加入,发起者并不需要改变。
5)应用场景
典型例子:多功能on/off按钮,记录状态可撤销动作,使用宏命令的party模式
更多应用:队列请求,日志请求
10. 模板方法模式
1) 类图
2) 定义
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
3)设计原则
好莱坞原则:别调用我们,我们会调用你。
4)点评
当子类必须提供算法中的某个方法或步骤的实现时,就使用抽象方法。
如果算法的这个部分是可选的,就用钩子,要不要挂钩由子类决定。
模板方法模式是最常用的模式。
- Java设计模式研究
- JAVA设计模式的研究
- Java设计模式之外观模式研究
- Java设计模式之外观模式研究
- Java设计模式研究之Flyweight模式
- Java设计模式研究之Flyweight模式
- Java设计模式研究之Flyweight模式
- Java设计模式研究之策略模式
- Java研究之学习设计模式-简单工厂模式详解
- Java研究之学习设计模式-抽象工厂模式详解
- Java研究之学习设计模式-多例模式详解
- 设计模式研究
- 设计模式研究--Proxy Model
- [记录] UI设计模式研究
- java学习之路---设计模式----工厂代理模式的进一步研究
- .NET设计模式研究之装饰模式
- javascript设计模式研究学习-设计模式类别
- 设计模式_记设计模式研究的开始(0)
- MySQL update 语句的正确用法
- ios7中让程序使用统一的status bar风格
- 什么是DLL,如何调用DLL
- 优秀Web开发者必须知道的10件事 新浪微博
- eclispe 窗口背景颜色、字体等设置整理
- Java设计模式研究
- IBM SOA 标准
- web请求---小结
- js中遍历Map对象
- 迟来的革命-贵港的新互联网生活
- Android Call requires API level 11 (current min is 8)的解决方案
- 蛋疼啊
- iPhone开发经典语录
- 一致性哈希算法的简单实现和在redis集群的应用