常用設計模式Java——Design pattern
阿新 • • 發佈:2018-11-25
設計模式
- 設計模式(Design Pattern)是一套被反覆使用、多數人知曉的、經過分類的、程式碼設計經驗的總結。
- 使用設計模式的目的:為了程式碼複用,增加可維護性
- 面向物件思想設計原則
- 單一職責原則
- 高內聚、低耦合
- 每個類應該只有一個職責,對外只能提供一種功能,而引起類變化的原因應該只有一個。
- 開閉原則
- 核心思想是:一個物件對擴充套件開放,對修改關閉。
- 對類的改動是通過增加程式碼進行的,而不是修改現有程式碼。
- 里氏替換原則
- 核心思想:在任何父類出現的地方都可以用它的子類來替代。
- 同一個繼承體系中的物件應該有共同的行為特徵。
- 依賴注入原則
- 核心思想:要依賴於抽象,不要依賴於具體實現。
- 在程式設計的時候針對抽象類或者介面程式設計,而不是針對具體實現程式設計。
- 介面分離原則
- 核心思想:不應該強迫程式依賴它們不需要使用的方法。
- 一個介面不需要提供太多的行為,一個介面應該只提供一種對外的功能,不應該把所有的操作都封裝到一個介面中。
- 迪米特原則
- 核心思想:一個物件應當對其他物件儘可能少的瞭解
- 降低各個物件之間的耦合,提高系統的可維護性。在模組之間應該只通過介面程式設計,而不理會模組的內部工作原理,它可以使各個模組耦合度降到最低,促進軟體的複用
- 單一職責原則
- 設計模式就是實現了這些原則,從而達到了程式碼複用、增加可維護性的目的。
常見的設計模式
- 簡單工廠模式和工廠方法模式(介面)
- 模版設計模式(抽象類)
- 裝飾設計模式(IO流)
- 單例設計模式(多執行緒)
- 介面卡模式(GUI)
單例模式
- 概述:單例模式就是要確保類在記憶體中只有一個物件,該例項必須自動建立,並且對外提供。
- 優點:在系統記憶體中只存在一個物件,因此可以節約系統資源,對於一些需要頻繁建立和銷燬的物件單例模式無疑可以提高系統的效能。
- 缺點:沒有抽象層,因此擴充套件很難。職責過重,在一定程式上違背了單一職責原則。
- Q:如何保證類在記憶體中只有一個物件
- 構造方法私有化
- 在成員變數位置建立一個物件
- 對外提供公共的方法訪問
- 程式碼實現
- 餓漢式:類一載入就建立物件
- 不會出問題的單例模式
- 懶漢式:呼叫的時候,才去建立物件
- 懶載入(延遲載入)
- 執行緒安全問題
- 餓漢式:類一載入就建立物件
//餓漢式:
private static Student s = new Student();
private Student(){}
public static Student getStudent(){ return s; }
//懶漢式:
private Student(){}
private static Student s = null;
public synchronized static Student getStudent(){
if(s == null){
s = new Student();
}
return s;
}
- JDK提供的一個單例模式的應用
- Runtime:每個 Java 應用程式都有一個 Runtime 類例項,使應用程式能夠與其執行的環境相連線。
- exec(String command):可以執行cmd命令
簡單工廠模式
- 概述:又叫靜態工廠方法模式,它定義一個具體的工廠類負責建立一些類的例項
- 優點:客戶端不需要在負責物件的建立,從而明確了各個類的職責
- 缺點:這個靜態工廠類負責所有物件的建立,如果有新的物件增加,或者某些物件的建立方式不同,就需要不斷的修改工廠類,不利於後期的維護
- 程式碼案例
public class AnimalFactory {
private AnimalFactory() { }
public static Animal createAnimal(String type) {
if("dog".equals(type)) {
return new Dog();
}else if("cat".equals(type)) {
return new Cat();
}
return null;
}
}
工廠方法模式
- 概述:工廠方法模式中抽象工廠類負責定義建立物件的介面,具體物件的建立工作由繼承抽象工廠的具體類實現。
- 優點:客戶端不需要在負責物件的建立,從而明確了各個類的職責,如果有新的物件增加,只需要增加一個具體的類和具體的工廠類即可,不影響已有的程式碼,後期維護容易,增強了系統的擴充套件性
- 缺點:需要額外的編寫程式碼,增加了工作量
- 程式碼案例
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal {
public void eat() {
System.out.println("貓吃魚!");
}
}
//需要貓
f = new CatFactory();
a = f.createAnimal();
a.eat();
public interface Factory {
public abstract Animal createAnimal();
}
public class CatFactory implements Factory {
public Animal createAnimal() {
return new Cat();
}
}
介面卡模式(GUI)
- 概述:將一個類的介面轉換成另外一個客戶希望的介面。從而使原來不能直接呼叫的介面變的可以呼叫。
- 優點:讓本來不適合使用的介面變得適合使用
- 缺點:一次只能適配一個類,使用有一定的侷限性
- Q:介面(方法比較多)——實現類(僅僅使用一個,也得把其他方法實現)
- 解決方案:介面 —— 介面卡類(實現介面,僅僅空實現) —— 實現類(用哪個實現哪個)
- 程式碼案例:
/*
* 讓窗體關閉
* 事件源:視窗
* 事件:對窗體的處理
* 事件處理:關閉視窗(System.exit(0))
* 事件監聽
*/
/*f.addWindowListener(new WindowListener() {
public void windowOpened(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
System.exit(0);
}
public void windowClosed(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
});*/
# 介面卡類改進:
//設定窗體關閉
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
模組設計模式(抽象類)
- 概述:模版方法模式就是定義一個演算法的骨架,而將具體的演算法延遲到子類中來實現
- 優點:使用模版方法模式,在定義演算法骨架的同時,可以很靈活的實現具體的演算法,滿足使用者靈活多變的需求
- 缺點:如果演算法骨架有修改的話,則需要修改抽象類
- 程式碼實現
public abstract class GetTime {
public long getTime(){
long startTime = System.currentTimeMillis();
code();
long endTime = System.currentTimeMillis();
return endTime-startTime;
}
public abstract void code();
}
裝飾設計模式(IO流)
- 概述:裝飾模式就是使用被裝飾類的一個子類的例項,在客戶端將這個子類的例項交給裝飾類。是繼承的替代方案
- 優點:使用裝飾模式,可以提供比繼承更靈活的擴充套件物件的功能,它可以動態的新增物件的功能,並且可以隨意的組合這些功能
- 缺點:正因為可以隨意組合,所以就可能出現一些不合理的邏輯
- 程式碼實現
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));