Java修煉之道--設計模式
一、概述
1、設計模式是人們在面對同類型軟體工程設計問題所總結出的一些有用經驗。模式不是程式碼,而是某類問題的通用設計解決方案
2、4人組Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides總結寫了《設計模式》
3、設計模式的優點和用途
4、學習設計模式最好的方式:在你的設計和以往的工程裡尋找何處可以使用它們
5、設計模式的本質目的是使軟體工程在維護性、擴充套件性、變化性、複雜度方面成O(N)
6、OO(Object Oriented)是原則,設計模式是具體方法、工具
設計模式怎麼分類,每一類都有哪些?【螞蟻金服內推】
設計模式怎麼用到專案中?【阿里面經】
二、設計模式
單例模式
工廠模式
觀察者模式
介面卡模式(Adapter)
2018/7/15
意圖
把一個類介面轉換成另一個使用者需要的介面。介面卡模式讓那些介面不相容的類可以一起工作
型別
介面卡模式的別名為包裝器(Wrapper)模式,它既可以作為類結構型模式,也可以作為物件結構型模式。在介面卡模式定義中所提及的介面是指廣義的介面,它可以表示一個方法或者方法的集合。
- 物件介面卡:(傳入物件)組合方式,但是更靈活推薦使用這種方式
- 類介面卡:(多重繼承)繼承方式,效率更高
類圖
實現
鴨子(Duck)和火雞(Turkey)擁有不同的叫聲,Duck 的叫聲呼叫 quack() 方法,而 Turkey 呼叫 gobble() 方法。
要求將 Turkey 的 gobble() 方法適配成 Duck 的 quack() 方法,從而讓火雞冒充鴨子!
public interface Duck {
void quack();
}
public interface Turkey {
void gobble();
}
public class WildTurkey implements Turkey {
@Override
public void gobble() {
System.out.println("gobble!");
}
}
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void quack() {
turkey.gobble();
}
}
public class Client {
public static void main(String[] args) {
Turkey turkey = new WildTurkey();
Duck duck = new TurkeyAdapter(turkey);
duck.quack();
}
}
JDK
模仿方法模式
策略模式(Strategy)
2018/7/11
意圖
- 定義一系列演算法,封裝每個演算法,並使它們可以互換。
- 策略模式可以讓演算法獨立於使用它的客戶端。
類圖
- Strategy 介面定義了一個演算法族,它們都具有 behavior() 方法。
- Context 是使用到該演算法族的類,其中的 doSomething() 方法會呼叫 behavior(),setStrategy(in Strategy) 方法可以動態地改變 strategy 物件,也就是說能動態地改變 Context 所使用的演算法。
與狀態模式的比較
狀態模式的類圖和策略模式類似,並且都是能夠動態改變物件的行為。
但是狀態模式是通過狀態轉移來改變 Context 所組合的 State 物件,而策略模式是通過 Context 本身的決策來改變組合的 Strategy 物件。
所謂的狀態轉移,是指 Context 在執行過程中由於一些條件發生改變而使得 State 物件發生改變,注意必須要是在執行過程中。
狀態模式主要是用來解決狀態轉移的問題,當狀態發生轉移了,那麼 Context 物件就會改變它的行為;而策略模式主要是用來封裝一組可以互相替代的演算法族,並且可以根據需要動態地去替換 Context 使用的演算法。
實現
設計一個鴨子,它可以動態地改變叫聲。這裡的演算法族是鴨子的叫聲行為。
public interface QuackBehavior {
void quack();
}
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("quack!");
}
}
public class Squeak implements QuackBehavior{
@Override
public void quack() {
System.out.println("squeak!");
}
}
public class Duck {
private QuackBehavior quackBehavior;
public void performQuack() {
if (quackBehavior != null) {
quackBehavior.quack();
}
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
public class Client {
public static void main(String[] args) {
Duck duck = new Duck();
duck.setQuackBehavior(new Squeak());
duck.performQuack();
duck.setQuackBehavior(new Quack());
duck.performQuack();
}
}
squeak!
quack!
JDK
- java.util.Comparator#compare()
- javax.servlet.http.HttpServlet
- javax.servlet.Filter#doFilter()
責任鏈模式
裝飾者模式
迭代器模式(Iterator)
2018/7/16
- 反應器模式
- 常用的八種掌握就行,原理,使用
- 單例、工廠、觀察者重點
所瞭解的設計模式,單例模式的注意事項,jdk原始碼哪些用到了你說的設計模式
- 所瞭解的設計模式
- 工廠模式:定義一個用於建立物件的介面,讓子類決定例項化哪一個類, Factory Method 使一個類的例項化延遲到了子類。
- 單例模式:保證一個類只有一個例項,並提供一個訪問它的全域性訪問點;
- 介面卡模式:將一類的介面轉換成客戶希望的另外一個介面,Adapter 模式使得原本由於介面不相容而不能一起工作那些類可以一起工作。
- 裝飾者模式:動態地給一個物件增加一些額外的職責,就增加的功能來說, Decorator 模式相比生成子類更加靈活。
- 代理:為其他物件提供一種代理以控制對這個物件的訪問
- 迭代器模式:提供一個方法順序訪問一個聚合物件的各個元素,而又不需要暴露該物件的內部表示。
- 單例模式的注意事項
- 儘量使用懶載入
- 雙重檢索實現執行緒安全
- 構造方法為private
- 定義靜態的Singleton instance物件和getInstance()方法
- jdk原始碼中用到的設計模式
- 裝飾器模式:IO流中
- 迭代器模式:Iterator
- 單利模式: java.lang.Runtime
- 代理模式:RMI
三、設計模式常見問題
1.什麼是高內聚,低耦合?
附錄:參考資料
設計模式之禪