設計模式之觀察者模式(Observe)-泛型擴充套件
阿新 • • 發佈:2018-12-15
設計模式之觀察者模式(Observer)
擴充套件部分是很精彩
意圖
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。
場景
觀測天氣(機器觀測,人工觀測),天氣變化時,觀測者做相應的處理
天氣觀測示例
天氣型別
public enum WeatherType {
SUNNY, RAINY, WINDY, COLD;
@Override
public String toString() {
return this.name().toLowerCase();
}
}
觀測者介面
public interface WeatherObserver {
void update(WeatherType currentWeather);
}
天氣類
public class Weather {
private WeatherType currentWeather;
private List<WeatherObserve> observes;
public Weather(){
currentWeather = WeatherType.SUNNY;
observes = new ArrayList<>();
}
public void addObserver(WeatherObserve observe){
observes.add(observe);
}
public void removeObserver(WeatherObserve observe){
observes.remove(observe);
}
public void timePassBy(){
WeatherType[] types = WeatherType.values();
currentWeather = types[ (currentWeather.ordinal()+1)%types.length];
System.out.println(MessageFormat.format("The weather change to {0}",currentWeather));
notifyObservers();
}
private void notifyObservers(){
for (WeatherObserve observe : observes){
observe.update(currentWeather);
}
}
}
機器觀測類
public class HobbitObserve implements WeatherObserve {
@Override
public void update(WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The hobbits are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The hobbits look for cover from the rain.");
break;
case SUNNY:
System.out.println("The happy hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The hobbits hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
人工觀測
public class OrcsObserve implements WeatherObserve{
@Override
public void update(WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The orcs are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The orcs look for cover from the rain.");
break;
case SUNNY:
System.out.println("The orcs hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The orcs hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
測試
@Test
public void observeTest(){
Weather weather = new Weather();
weather.addObserver(new HobbitObserve());
weather.addObserver(new OrcsObserve());
weather.timePassBy();
weather.timePassBy();
weather.timePassBy();
weather.timePassBy();
weather.timePassBy();
}
類圖
觀測者模式擴充套件
使用泛型進行擴充套件
觀察目標需繼承此類 S:觀測類 O:觀察者類 A:觀測引數
public abstract class Observable<S extends Observable<S,O,A>,O extends Observer<S,O,A>,A> {
protected List<O> observers;
public Observable(){
observers = new CopyOnWriteArrayList<>();
}
public void addObserver(O observer){
observers.add(observer);
}
public void remove(O observer){
observers.remove(observer);
}
public void notifyObserver(A arguments){
for (O observer : observers){
observer.update((S) this,arguments);
}
}
}
觀察者介面
public interface Observer<S extends Observable<S,O,A>,O extends Observer<S,O,A>,A> {
void update(S subject,A argument);
}
天氣觀察者
public interface Race extends Observer<GWeather,Race,WeatherType> {
}
天氣類
public class GWeather extends Observable<GWeather,Race,WeatherType> {
private WeatherType currentWeather;
public GWeather(){
currentWeather = WeatherType.SUNNY;
}
public void timePassBy(){
WeatherType[] enumsValues = WeatherType.values();
currentWeather = enumsValues[(currentWeather.ordinal()+1)%enumsValues.length];
System.out.println(MessageFormat.format("The weather change to {0}",currentWeather));
notifyObserver(currentWeather);
}
}
機器觀察
public class GHobbitObserver implements Race {
@Override
public void update(GWeather subject, WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The hobbits are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The hobbits look for cover from the rain.");
break;
case SUNNY:
System.out.println("The happy hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The hobbits hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
人工觀察
public class GOrcsObserver implements Race {
@Override
public void update(GWeather subject, WeatherType currentWeather) {
switch (currentWeather) {
case COLD:
System.out.println("The orcs are shivering in the cold weather.");
break;
case RAINY:
System.out.println("The orcs look for cover from the rain.");
break;
case SUNNY:
System.out.println("The orcs hobbits bade in the warm sun.");
break;
case WINDY:
System.out.println("The orcs hold their hats tightly in the windy weather.");
break;
default:
break;
}
}
}
測試
@Test
public void genericTest(){
GWeather gWeather = new GWeather();
gWeather.addObserver(new GOrcsObserver());
gWeather.addObserver(new GHobbitObserver());
gWeather.timePassBy();
gWeather.timePassBy();
gWeather.timePassBy();
gWeather.timePassBy();
}
泛型做的是型別限制
類圖