UML-GoF設計模式

 

 

我認爲,本章是重點中的重點。並不是23個模式都被普遍應用,其中經常使用和最爲有效的大概有15個模式。前端

一、適配器(Adapter)算法

1)、使用場景數據庫

使用一個已經存在的類,但若是他的接口,也就是他的方法和你的要求不相同時,考慮使用是適配器模式。

就是說,雙方都不修改本身的代碼的時候,能夠採用適配器模式。

2)、結構圖ide

3)、相關模式this

外觀對象:隱藏外部系統的資源適配器也被視爲外觀對象,由於資源適配器使用單一對象封裝了對子系統或系統的訪問。
資源適配器:當包裝對象時爲不一樣外部接口提供適配時,該對象叫資源適配器

4)、準則spa

類名後綴爲「Adapter」。

5)、用到的GRASP原則3d

 二、工廠模式日誌

1)、使用場景code

該模式也常稱爲「簡單工廠」或「具體工廠」。如:
1)、存在複雜建立邏輯
2)、爲提升內聚而分離建立者職責(關注點分離)
所以,建立稱爲工廠的純虛構對象來處理這些建立職責。

2)、結構server

 

通常xxxFactory應該是單實例類。

3)、相關模式

一般使用 單例模式 來訪問工廠模式。

由誰建立工廠呢?通常採用單例模式。

三、單例模式

1)、使用場景

只有惟一實例的類即爲「單實例類」。對象須要全局可見性和單點訪問。
所以,建議對類定義靜態方法用以返回單實例。

2)、相關模式

單例模式:一般用於建立工廠對象和外觀對象

以上整合例子:

四、策略模式

1)、使用場景

銷售的訂價策略(也可叫作規則、政策或算法)具備多樣性。在一段時間內,對於全部的銷售可能會有10%的折扣,後期可能會對超出200元的銷售給予10%的折扣,而且還會存在其餘大量的變化。

所以,在單獨的類中分別定義每種策略/規則/政策/算法,而且使其具備共同接口

 

2 )、結構

 

 

 

 

策略模式,共同的方法內傳入的參數,一般是上下文對象,上圖就是sale。

3)、結合工廠模式

1)、使用工廠模式建立這些策略類
2)、使用單例模式建立工廠類。

 

五、組合模式

1)、使用場景

若是有重疊怎麼辦?好比:
1)老年人折扣20%
2)購物金額滿200元享受15%折扣

所以,如何可以處理像原子對象同樣,(多態的)處理一組對象或具備組合結構的對象呢?
答:定義組合和原子對象的類,使他們具備相同的接口。

2)、結構

2)、相關模式

一般與策略命令模式一塊兒使用。

六、外觀模式

1)、使用場景

對一組徹底不一樣的實現或接口(如子系統中的實現和接口)須要公共、統一的接口,隱藏掉子系統複雜的實現或接口。從而使關注點分離。
如:slf4j、通訊前置
其與適配器的區別在於,facade模式針對同職能接口的抽象並提供公共、統一的接口,強度的是統一。而adapter模式針對的是適配不一樣接口且老接口不改的場景,強調的是適配

2)、結構

3)、例子

class Program
    {
        static void Main(string[] args)
        {
            Facade facade = new Facade();

            facade.MethodA();
            facade.MethodB();

            Console.Read();

        }
    }

    class SubSystemOne
    {
        public void MethodOne()
        {
            Console.WriteLine(" 子系統方法一");
        }
    }

    class SubSystemTwo
    {
        public void MethodTwo()
        {
            Console.WriteLine(" 子系統方法二");
        }
    }

    class SubSystemThree
    {
        public void MethodThree()
        {
            Console.WriteLine(" 子系統方法三");
        }
    }

    class SubSystemFour
    {
        public void MethodFour()
        {
            Console.WriteLine(" 子系統方法四");
        }
    }

    class Facade
    {
        SubSystemOne one;
        SubSystemTwo two;
        SubSystemThree three;
        SubSystemFour four;

        public Facade()
        {
            one = new SubSystemOne();
            two = new SubSystemTwo();
            three = new SubSystemThree();
            four = new SubSystemFour();
        }

        public void MethodA()
        {
            Console.WriteLine("\n方法組A() ---- ");
            one.MethodOne();
            two.MethodTwo();
            four.MethodFour();
        }

        public void MethodB()
        {
            Console.WriteLine("\n方法組B() ---- ");
            two.MethodTwo();
            three.MethodThree();
        }
    }
View Code

 

4)、相關模式

外觀模式一般經過單例模式訪問。

七、觀察者模式(Observer)

1)、定義

觀察者模式又叫「發佈-訂閱(Publish/Subscribe)」模式、又叫「委派事件模型」。
之因此被稱爲觀察者模式,是由於監聽器或訂閱者在對相應事件進行觀察。
之因此被稱爲委派事件模型,是由於發佈者將事件處理委派給了監聽器(訂閱者)

2)、使用場景

例子:支付成功後,
1)記錄日誌
2)寫數據庫
3)前端展現支付結果
傳統方式,將以上3個關注點耦合在一塊兒寫。隨着業務需求愈來愈多,致使很難維護。

總結:當一個對象的改變須要同時改變其餘對象時,並且還不知道有多少對象有待改變時,應該考慮使用觀察者模式。

3)、結構

 

4)、例子

public abstract class Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    //增長觀察者
    public void attach(Observer observer) {
        observers.add(observer);
    }
    //移除觀察者
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    //通知
    public void notify1() {
        observers.forEach(o->o.update());
    }
}
public abstract class Observer {
    public abstract void update();
}
public class ConcreteSubject extends Subject {
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }

}
public class ConcreteObserver extends Observer {
    private String name;
    private String observerState;
    private ConcreteSubject subject;

    public ConcreteObserver( ConcreteSubject subject,String name) {
        this.subject = subject;
        this.name = name;
    }

    @Override
    public void update() {
        observerState = subject.getSubjectState();
        System.out.println("觀察者"+name+"的新狀態是"+observerState);
    }

    public ConcreteSubject getSubject() {
        return subject;
    }

    public void setSubject(ConcreteSubject subject) {
        this.subject = subject;
    }
}
public class Main {
    public static void main(String[] args) {
        ConcreteSubject s = new ConcreteSubject();

        s.attach(new ConcreteObserver(s, "X"));
        s.attach(new ConcreteObserver(s, "Y"));
        s.attach(new ConcreteObserver(s, "Z"));

        s.setSubjectState("ABC");
        s.notify1();

    }
}
--輸出
觀察者X的新狀態是ABC
觀察者Y的新狀態是ABC
觀察者Z的新狀態是ABC
View Code

5)、小結

A、一個事件支持多個訂閱者

public static void main(String[] args) {
    ConcreteSubject s = new ConcreteSubject();
    //多個訂閱者
    s.attach(new ConcreteObserver(s, "X"));
    s.attach(new ConcreteObserver(s, "Y"));
    s.attach(new ConcreteObserver(s, "Z"));
    //一個事件
    s.setSubjectState("ABC");
    s.notify1();

}

B、訂閱者可動態添加或刪除

public abstract class Subject {
    private List<Observer> observers = new ArrayList<Observer>();
    //增長觀察者
    public void attach(Observer observer) {
        observers.add(observer);
    }
    //移除觀察者
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    //通知
    public void notify1() {
        observers.forEach(o->o.update());
    }
}
相關文章
相關標籤/搜索