单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。例子:Windows的回收站。
1. 最简单的实现
1 public class Singleton{ 2 private static final Singleton singleton = new Singleton(); 3 4 public static Singleton getInstance(){ 5 return singleton; 6 } 7 8 private Singleton(){ 9 10 } 11 }
2. 线程安全版本
public class SingletonClass{ private static SingletonClass instance = null; public static SingletonClass getInstance(){ if(instance == null){ synchronized(SingletonClass.class){ if(instance == null){ instance = new SingletonClass(); } } } return instance; } private SingletonClass(){ } }
观察者模式
观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
它将观察者和被观察者的对象分离开。提高了应用程序的可维护性和重用性。
实现观察者模式有很多形式,一种是“注册---通知---撤销注册”的形式。
观察者Observer:所有潜在的观察者必须实现观察者接口,这个接口只有update方法,当主题改变时,它被调用。
具体观察者ConcreteObserver: 具体观察者可以是任何实现了Observer接口的类。观察者必须注册具体主题,一边接收更新。
可观察者Subject: 主题接口,即可观察者Observable,对象使用此接口注册为观察者,或者把自己从观察者中删除,每个主题可以有多个观察者。
具体可观察者ConcreteSubject: 一个具体主题实现了主题接口,除了注册和撤销之外,具体主题还实现了notifyObservers()方法,这个方法用来在主题状态改变时更新所有观察者。具体主题也可能有设置和获取状态的方法。
观察者模式的应用场景:
1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
观察者模式的优点:
1、 Subject和Observer之间是松偶合的,分别可以各自独立改变。
2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
观察者模式的缺陷:
1、 松偶合导致代码关系不明显,有时可能难以理解。(废话)
2、 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)
1 public interface Observer 2 { 3 public void update(float temprature); 4 } 5 6 public class ConcreteObserver implements Observer 7 { 8 private float temperature; 9 private final Subject subject; 10 11 public ConcreteObserver(final Subject subject) 12 { 13 this.subject = subject; 14 this.subject.registerObserver(this); 15 } 16 17 public float getTemperature() 18 { 19 return temperature; 20 } 21 22 public void setTemperature(final float temperature) 23 { 24 this.temperature = temperature; 25 } 26 27 @Override 28 public void update(final float temperature) 29 { 30 this.temperature = temperature; 31 } 32 } 33 34 public interface Subject 35 { 36 public void registerObserver(Observer o); 37 38 public void removeObserver(Observer o); 39 40 public void notifyObservers(); 41 42 } 43 44 public class ConcreteSubject implements Subject 45 { 46 private final List<Observer> observers; 47 private float temperature; 48 49 public float getTemperature() 50 { 51 return temperature; 52 } 53 54 private void temperatureChanged() 55 { 56 this.notifyObservers(); 57 } 58 59 public void setTemperature(final float temperature) 60 { 61 this.temperature = temperature; 62 this.temperatureChanged(); 63 } 64 65 public ConcreteSubject() 66 { 67 observers = new ArrayList<Observer>(); 68 } 69 70 @Override 71 public void registerObserver(final Observer o) 72 { 73 observers.add(o); 74 } 75 76 @Override 77 public void removeObserver(final Observer o) 78 { 79 if (observers.indexOf(o) >= 0) 80 { 81 observers.remove(o); 82 } 83 } 84 85 @Override 86 public void notifyObservers() 87 { 88 for (final Observer o : observers) 89 { 90 o.update(temperature); 91 } 92 } 93 } 94 95 public class Client 96 { 97 public static void main(final String[] args) 98 { 99 final ConcreteSubject sb = new ConcreteSubject(); 100 sb.setTemperature((float) 20.00); 101 102 final Observer o = new ConcreteObserver(sb); 103 sb.setTemperature((float) 21.00); 104 105 } 106 }