HeadFirst设计模式学习笔记
原則
- 找出應(yīng)用中需要變化之處,將變化之處獨立出來,與不需要變動的部分分開
- 針對接口編程,而不是針對實現(xiàn)編程
- 多用組合,少用繼承
設(shè)計模式
策略模式(strategy pattern)
實例首先,定義抽象類和接口
然后定義具體的類并實現(xiàn)接口
public class FlyNoWay implements FlyBehavior {@Overridepublic void fly() {System.out.println("oh, i cannot fly!");} } public class FlyRocketPower implements FlyBehavior {@Overridepublic void fly() {System.out.println("i can fly ~~~~");} } public class ModelDuck extends Duck {public ModelDuck() {this.setFlyBehavior(new FlyNoWay());} }使用
public class Main {public static void main(String[] args) {System.out.println("-------- God made a model duck with mud --------");Duck duck = new ModelDuck();duck.display();duck.performFly();System.out.println("-------- God gives the model duck the ability to fly --------");duck.setFlyBehavior(new FlyRocketPower());duck.performFly();} }分析
對于鴨子來說,飛行能力是一種變動的能力,有些鴨子能飛,而有些鴨子不能。如果直接在Duck這個抽象類中就定義了鴨子的飛行能力,顯然并不合適;如果將飛行能力抽象為一個接口,讓每個能飛行的鴨子都繼承這個接口的話,會存在一個問題,即:每個會飛行的鴨子都需要實現(xiàn)這個接口的飛行方法,從而使飛行這個功能存在代碼重復(fù)。因此,在策略模式中,采用這樣一種方法,即:將飛行能力抽象為一個接口,但是該接口是以組合的形式作為Duck的一個字段,并在Duck內(nèi)部提供performFly方法來調(diào)用接口。這樣做的好處是:可以根據(jù)情況,將不同的飛行行為注入到不同的Duck子類中(復(fù)用飛行行為的實現(xiàn)代碼),甚至可以在程序運行的時候,動態(tài)替換其飛行行為。
觀察者模式
實例定義接口
接口實現(xiàn)
public class MySubject implements Subject{ArrayList<Observer> observers;float temperature;public MySubject(){observers=new ArrayList<Observers>();}public void registerObserver(Observer o){observers.add(o);}public void deleteObserver(Observer o){int index=observers.indexof(o);if(index>=0)observers.remove(index);}public void notifyAllObservers(){for(Observer o:observers)o.update(temperature,humidity,pressure);}public void setMeasurements(float temperature){this.temperature=temperature;notifyAllObservers();} }public class MyObserver implements Observer{Subject subject;public MyObserver(Subject s){this.subject=s;s.registerObserver(this);}public void update(float temperature){System.out.println("得到來自subject的消息");} }使用
MySubject ms=new MySubject(); Observer o=new MyObserver(ms); //一旦調(diào)用該方法來更新MySubject中的數(shù)據(jù),則所有注冊過的Observer都會得到通知 ms.setMeasurements(temperature);分析
兩種角色:subject 和 observer。observer訂閱subject,subject中的數(shù)據(jù)有變化時,能推送到各個已經(jīng)訂閱的observer上去。并且,這兩種角色都是以接口的形式定義。
關(guān)鍵在于:subject中維護著一張所有已訂閱該subject的observer列表;observer中含有指向subject的引用。
在java種,也存在observable抽象類和observer接口,分別對應(yīng)觀察者模式中的subject接口和observer接口。并且,在observable中,每次調(diào)用notifyObservers()方法之前,都需要調(diào)用setChange()方法,用來將標明狀態(tài)改變的標志位設(shè)為true。notifyObservers()方法在內(nèi)部會判斷標志位是否為true,只有在位true的情況下才會真正的通知觀察者(由于observable是一個抽象類,而java是單繼承,所以在一定情況下存在限制)。
總結(jié)
以上是生活随笔為你收集整理的HeadFirst设计模式学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “约见”面试官系列之常见面试题第四十四篇
- 下一篇: Vue中 $ref 的用法