分類(常見的設計模式)
1.創建型模式
a) 工廠模式
b) 抽象工廠模式
c) 單例模式
d) 建造者模式
2.結構型模式
a) 適配器模式
b) 裝飾器模式
c) 橋接模式
d) 代理模式
3.行為型模式
a) 命令模式
b) 迭代器模式
c) 策略模式
d) 觀察者模式
六大原則
1、開閉原則
對擴展開放,對修改關閉。
2、里氏代換原則
任何基類可以出現的地方,子類一定可以出現。
3、依賴倒轉原則
依賴於抽象而不依賴於具體。
4、接口隔離原則
使用多個隔離的接口,比使用單個接口要好。
5、迪米特法則,又稱最少知道原則
一個實體應當盡量少地與其他實體之間發生相互作用,使得系統功能模塊相對獨立。
6、合成復用原則
盡量使用合成/聚合的方式,而不是使用繼承。
一、工廠模式
作用
一個抽象的接口,多個抽象接口的實現類,一個工廠,用來實例化抽象的接口。
優點
一個調用者想創建一個對象,直接向工廠請求即可,不需要知道具體實現,以提高系統的可維護性、可擴展性。
缺點
產品修改時,工廠也要進行修改。
代碼
二、抽象工廠模式
作用
抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創建其他工廠。
優點
當一個產品類型(每一類中有多個產品)被設計成一起工作時,有良好的維護性。
缺點
產品類擴展困難。
例
三、單例模式
作用
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
特點
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
懶漢式
線程不安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
線程安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
雙檢鎖
public class Singleton {
private static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
靜態內部類
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
餓漢式
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
四、建造者模式
作用
建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個復雜的對象。
應用實例
肯德基里,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。
角色
抽象建造者角色:一個抽象接口,以規范產品對象的各個組成成分的建造。
具體建造者角色:實現抽象建造者Builder所聲明的接口,給出一步一步地完成創建產品實例的操作。
導演者角色:擔任這個角色的類調用具體建造者角色以創建產品對象。應當指出的是,導演者角色並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者角色。
產品角色:產品便是建造中的復雜對象。一般來說,一個系統中會有多於一個的產品類,而且這些產品類並不一定有共同的接口,而完全可以是不相關聯的。
例子
五、適配器模式
作用
將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以在一起工作。
模式中的角色
1.目標接口(Target):客戶所期待的接口。目標可以是具體的或抽象的類,也可以是接口。
2.需要適配的類(Adaptee):需要適配的類或適配者類。
3.適配器(Adapter):實現了目標接口,通過包裝一個需要適配的對象,把原接口轉換成目標接口。
通過適配器把需要適配的類轉成目標類
優點
- 接口可以轉成自己希望的另一個接口
- 提高了類的復用。
缺點
過多地使用適配器,會讓系統非常零亂,不易整體進行把握。
例子
六、裝飾者模式
作用
對已有的業務邏輯進一步的封裝,使其增加額外的功能。即向一個現有的對象添加新的功能,同時又不改變其結構。
優點
可以提供比繼承更多的靈活性。
缺點
多層裝飾比較復雜。
例子
實物基類
雞肉
鴨肉
裝飾者基類
蒸-裝飾者
烤-裝飾者
七、橋接模式
作用
將抽象部分與實現部分分離,使它們都可以獨立的變化。把兩個角色之間的繼承關系改為了耦合的關系。
例子
八、代理模式
作用
一個類代理另一個類的功能。
模式中的角色
- 抽象角色:聲明真實對象和代理對象的共同接口。
2. 代理角色:代理對象角色內部含有對真實對象的引用,繼承了抽象對象。
3. 真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。
缺點
由於在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。
例子
九、命令模式
作用
將一個命令封裝成一個對象,可以對命令接受者進行不同的命令處理。
組成
命令接受者:執行命令的對象。
命令:操作命令接受者執行命令。
命令對象入口:要求命令對象執行請求,通常會持有命令對象,可以持有很多的命令對象。
例子
十、迭代器模式
作用
這種模式用於順序訪問集合對象的元素,不需要知道集合對象的底層表示。
通過容器獲取迭代器,通過迭代器遍歷元素。
角色
1.迭代器接口
2.迭代器具體實現
3.抽象容器
4.具體容器
例子
迭代器接口
public interface Iterator {
public Object first();
public Object previous();
public Object next();
public boolean hasNext();
}
具體迭代器
public class MyIterator implements Iterator{
private List<Object> list;
private int index = 0;
public MyIterator(List<Object> list) {
this.list = list;
}
@Override
public Object previous() {
if((this.index - 1) < 0){
return null;
}else{
return this.list.get(--index);
}
}
@Override
public Object next() {
if((this.index + 1) >= this.list.size()){
return null;
}else{
return this.list.get(++index);
}
}
@Override
public boolean hasNext() {
if(this.index < (this.list.size() - 1)){
return true;
}
return false;
}
@Override
public Object first() {
if(this.list.size() <= 0){
return null;
}else{
return this.list.get(0);
}
}
}
容器接口
package com.pichen.dp.behavioralpattern.iterator;
public abstract class Container {
public abstract Iterator iterator();
public abstract void put(Object obj);
}
具體容器
public class MyContainer extends Container{
private List<Object> list;
public MyContainer() {
this.list = new ArrayList<Object>();
}
@Override
public void put(Object obj){
this.list.add(obj);
}
@Override
public Iterator iterator() {
return new MyIterator(list);
}
}
十一、策略模式
作用
將多個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。
組成
1.抽象策略角色:通常由一個接口或者抽象類實現。
2.具體策略角色: 包裝了相關的算法和行為。
3.環境角色: 持有一個策略類的引用,最終給客戶端調用。
實際舉例
旅行的出游方式,選擇騎自行車、坐汽車,每一種旅行方式都是一個策略。
例子
十二、觀察者模式
作用
它定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。
優點
1.觀察者模式在被觀察者和觀察者之間建立一個抽象的耦合。
2.觀察者模式支持廣播通訊。被觀察者會向所有的登記過的觀察者發出通知。
缺點
1.如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
2.如果在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能導致系統崩潰。
3.觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發生變化的,而僅僅只是知道觀察目標發生了變化。
結構圖
- Subject:抽象主題(抽象被觀察者),每個主題都可以有任意數量的觀察者,抽象主題提供一個接口,可以增加和刪除觀察者對象。
- ConcreteSubject:具體主題(具體被觀察者),把所有觀察者對象保存在一個集合里,在具體主題的內部狀態發生改變時,給所有注冊過的觀察者發送通知。
- Observer:抽象觀察者,是觀察者者的抽象類,它定義了一個更新接口,使得在得到主題更改通知時更新自己。
- ConcrereObserver:具體觀察者,是實現抽象觀察者定義的更新接口,以便在得到主題更改通知時更新自身的狀態。
例子