《設計模式七》備忘錄、模板方法、狀態模式及設計模式設計總結

morpheus發表於2020-04-20

1.19 備忘錄模式-Memento

記錄狀態,便於回滾

使用場景:例如磁碟快照,虛擬機器快照,遊戲存檔等

  • Java中可以實現標記性介面,序列化需要存檔的類的狀態
public class A implements Serializable {
    int a = 1;
    int b = 2;
    B b = new B();
    b.setHello("hello");
}
public class B implements Serializable {

    public void setHello(String str) {
        System.out.println(str);
    }

}

// 存檔
public void save() throws Exception{
    A a = new A();
    File f = new File("d:test/a.data")
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
    oss.writeObject(a);
    oss.close();
}
// 讀盤
public void load() throws Exception{
    A a = new A();
    B b = new B();
    File f = new File("d:test/a.data")
    ObjectInputStream oiss = new ObjectInputStream (new FileInputStream(f));
    b = (B)ois.readObject();
    a = (A)ois.readObject();
    ois.close();
}

實質就是類的序列化和反序列化
序列化過程中transient修飾符,表示在序列化的過程中,transient修飾的類,進行透明處理,不進行序列化
總結:如果要序列化A,那麼A中其他物件的引用也要支援序列化,如果A中某個物件不需要序列化,可以使用transient使其透明化

序列化常被用來存檔,網路傳輸(不過目前基本不適用Java序列化進行網路傳輸,而是使用grpc,因為java的序列化傳輸會序列化很多屬性相關的用不到的東西,體量會比grpc大一到兩倍)

1.20 模板方法模式-TemplateMethod

通俗理解為鉤子函式

凡是我們重寫一個方法,系統幫我們重新呼叫的,都可以稱之為鉤子函式(模板方法)。

父類方法a呼叫的op1和op2兩個方法,子類重寫這兩個方法,呼叫父類的a方法,那麼被重寫的op1和op1們就會被父類呼叫

abstract class F {
    public void m() {
        op1();
        op2();
    }
    
    // 這兩個抽象方法就是留給子類去實現的
    abstract void op1();
    abstract void op2();
}

class C1 extends F {
    @Override
    void op1() {
        System.out.println("op1");
    }
    
    @Override
    void op2() {
        System.out.println("op2");
    }

}

public class Main{
    public static void main(String[] args) {
        F f = new C1();
        f.m();
    }
}

1.21 狀態模式-State

根據狀態決定行為

例如,TCP連線中的客戶端Open呼叫,如果服務端是開啟的狀態採用何種open策略,如果服務端是監聽的採用何種open策略,如果服務端是關閉的,何種open策略。這裡服務端的這幾個條件就可以抽象成一個State。該State包涵上述的三個狀態,具體的連線要實現這三個狀態。所以State模式不適合頻繁擴充套件的方法,適合狀態固定的模式

1.21.1 有限狀態機(FSM)

  • 例如:執行緒的遷移狀態
    新建,就緒,執行,掛起...等等,有限的狀態機。State和有限狀態機實質是兩個東西,不可混淆

總結

  • 看到某一個設計模式,要能想到這個模式的典型用法,聯想到使用場景。

重點設計模式

  1. 單例模式-singleton
  2. 工廠模式-Factory,包括靜態工程,動態工廠,Spring的Bean工廠
  3. 觀察者模式-Observer,監聽器,事件相關
  4. 介面卡模式-Adapter,IO的Stream流和Reader的轉換用來適配
  5. 代理模式-Proxy,靜態代理,動態代理,Spring的AOP

物件導向的六大原則

六大原則

  • OCP : 總綱,對擴充套件開放,對修改關閉
  • SRP : 類的職責要單一
  • LSP : 子類可以透明替換父類
  • DIR : 面向介面程式設計
  • ISP : 介面的職責要單一
  • LOD : 降低耦合

可維護性Maintainability

修改功能,需要改動的地方越少,可維護性越好

可複用性Reusability

程式碼可以被以後重複使用
寫出自己總結的類庫

可擴充套件性Extensibility/Scalability

新增功能無需修改原來程式碼

靈活性flexibility/mobility/adaptability

程式碼介面可以靈活呼叫

單一職責原則Single Responsiblity Principle

一個類別太大,被太累,負責單一的職責:Persion PersionManager

高內聚,低耦合

開閉原則 open-closed peinciple

對擴充套件開放,對修改關閉,儘量不修改原來的程式碼情況下進行擴充套件

抽象化,多型是開閉原則的關鍵

里氏替換原則Liscov Substitution Principle

所有使用父類的地方,必須能夠透明的使用子類物件,也就是說子類不要改父類的東西,不要更改父類的方法語義

例如F的子類是H:

F a = new F();
// 可以完全被替換為
F a = new H();

依賴倒置原則Dependency Inversion Priciple

  1. 依賴抽象,而不是依賴具體
  2. 面向抽象(介面)程式設計

介面隔離原則Interface Segregation Principle

每個介面應該承擔獨立的角色,不幹不該自己乾的事

  1. Flyable Runnable不該合二為一
  2. 避免子類實現不需要實現的方法
  3. 需要對客戶提供介面的時候,只需要暴露最小的介面

相關文章