算是最近學設計模式(HEAD FIRST設計模式)的一個總結吧,力求用最精簡的代碼說明其設計本質。
第一個模式:策略模式
代碼:
1 interface refuel { 2 public void fuelUp(); 3 } 4 5 6 class car { 7 refuel fuelType; 8 9 public void setFuelType(refuel type) { 10 this.fuelType = type; 11 } 12 13 public void fuelUp() { 14 fuelType.fuelUp(); 15 } 16 17 } 18 19 20 class fuelUpWith_93 implements refuel { 21 22 @Override 23 public void fuelUp() { 24 System.out.println("Fueled up with No.93 gasoline"); 25 } 26 27 } 28 29 30 class fuelUpWith_97 implements refuel { 31 32 @Override 33 public void fuelUp() { 34 System.out.println("Fueled up with No.97 gasoline"); 35 } 36 37 }
說明:汽車都需要加油,但是不同汽車加不同的油,通過讓汽車持有一個具體實現加油算法的對象(通常向上轉型為其接口),在汽車加油的時候直接調用這個接口,讓其自己實現這種汽車加油的相關算法。
設計思想:解耦合,這個設計模式最大的優點是:能保證復用所有相同的代碼(只要你的汽車持有了其使用的汽油類型),又能保證當你需要一種新的實現的時候可以快速加入進去(寫一種實現基礎接口的算法實現)而不需要修改原有代碼。
第二個設計模式:觀察者模式
代碼(JAVA內置實現):
1 import java.util.Observable; 2 import java.util.Observer; 3 4 public class Main { 5 6 public static void main(String[] args) { 7 School highSchool = new School(); 8 Student Jack = new Student("Jack"); 9 Student Tom = new Student("Tom"); 10 Jack.register(highSchool); 11 Tom.register(highSchool); 12 highSchool.termBegins(); 13 } 14 } 15 16 17 class School extends Observable { 18 19 public void termBegins() { 20 this.setChanged(); 21 this.notifyObservers(); 22 } 23 24 } 25 26 27 class Student implements Observer { 28 29 Observable o; 30 String name; 31 32 public Student(String name) { 33 this.name = new String(name); 34 } 35 36 public void register(Observable o) { 37 this.o = o; 38 o.addObserver(this); 39 } 40 41 @Override 42 public void update(Observable o, Object arg) { 43 if (o instanceof School) { 44 System.out.println(name + " go to schoole"); 45 } 46 } 47 48 }
代碼(手動實現):
1 import java.util.ArrayList; 2 3 public class Main { 4 5 public static void main(String[] args) { 6 Student Jack = new Student("Jack"); 7 Student Tom = new Student("Tom"); 8 School highSchool = new School(); 9 highSchool.register(Jack); 10 highSchool.register(Tom); 11 highSchool.termBegins(); 12 } 13 } 14 15 16 class School { 17 18 ArrayList<Student> stuList = new ArrayList<Student>(); 19 20 public void register(Student stu) { 21 stuList.add(stu); 22 } 23 24 public void termBegins() { 25 this.notifyObservers(); 26 System.out.println("Welcome to school!"); 27 } 28 29 private void notifyObservers() { 30 for (Student stu : stuList) { 31 stu.update(); 32 } 33 } 34 } 35 36 37 class Student { 38 39 String name; 40 41 public Student(String name) { 42 this.name = new String(name); 43 } 44 45 public void update() { 46 System.out.println(name + " go to school"); 47 } 48 49 }
說明:把學生(觀察者)對象交給學校(被觀察者)。當學校開學時,一個一個去“通知”,讓其持有的學生對象作出對應的反應。
設計思想:當需要變化的時候通知觀察者們。Swing組件中大量用到(反應鼠標點擊消息等等)。其他沒啥很特別的東西。
第三個設計模式:裝飾者模式
代碼:
1 public class Main { 2 3 public static void main(String[] args) { 4 coffee myCoffee = new Mocha(new Milk(new regularCoffee())); 5 System.out.println(myCoffee.getName()); 6 } 7 } 8 9 10 interface coffee { 11 12 public int getCost(); 13 14 public String getName(); 15 16 } 17 18 19 class regularCoffee implements coffee { 20 21 @Override 22 public int getCost() { 23 return 5; // 最最普通的一杯咖啡底價5元 24 } 25 26 @Override 27 public String getName() { 28 return "咖啡"; // 最最普通的咖啡 29 } 30 31 } 32 33 34 abstract class coffeeDecorator implements coffee { 35 36 coffee oriCoffee; 37 38 } 39 40 41 class Milk extends coffeeDecorator { // 牛奶,加牛奶的修飾器 42 43 public Milk(coffee c) { 44 this.oriCoffee = c; 45 } 46 47 @Override 48 public int getCost() { 49 return oriCoffee.getCost() + 3; // 加一份牛奶再加3元 50 } 51 52 @Override 53 public String getName() { 54 return "牛奶" + oriCoffee.getName(); // 加一份牛奶的話,名字上也要加一份牛奶前綴 55 } 56 57 } 58 59 60 class Mocha extends coffeeDecorator { // 摩卡,加巧克力的修飾器 61 62 public Mocha(coffee c) { 63 this.oriCoffee = c; 64 } 65 66 @Override 67 public int getCost() { 68 return oriCoffee.getCost() + 4; // 加一份巧克力再叫4元 69 } 70 71 @Override 72 public String getName() { 73 return "摩卡" + oriCoffee.getName(); // 加一份巧克力的話,名字也加一個前綴 74 } 75 76 }
說明:每一次新建一個裝飾者(Mocha或者Milk或者你寫的別的什么),都依賴於一個傳入的參數(目前的咖啡),在這個基礎上繼續添加裝飾。
設計思想:一些類可能有自由組合的可能(比如咖啡),你很難一次把他們寫全(從設計上也不應該如此),於是便應該用裝飾者模式讓使用者自己去搭配。每一次經過修飾就在傳入參數的基礎上進行修改。
第四個設計模式:工廠模式
首先要說的是工廠模式這個名字讓人迷惑,因為很多模式好像都和工廠模式有關系:
1,靜態工廠模式 : 一般是說用靜態方法寫的簡單工廠模式。
2,簡單工廠模式 :就是一個類,里面封裝了某個類的構造方法,不僅調配構造參數,也許還有別的工作要做。
3,工廠方法模式 :在工廠中定義一個創建對象的接口,但是讓子類去實現(通過Abstract)具體的創建過程。(和模板方法模式有點像)
4,抽象工廠模式 :提供一個接口,用來創建相關或依賴對象的家族。
關於工廠方法模式和抽象工廠模式可以看:看這篇文章
第五個設計模式:單例模式
代碼(餓漢模式):
1 class Singleton { 2 3 private static Singleton instance = new Singleton(); 4 5 private Singleton() { 6 7 } 8 9 public static Singleton getInstance() { 10 return instance; 11 } 12 13 }
說明:餓漢模式就是直接在類的靜態字段中寫上一個實例對象。由<clinit>方法自動在類加載結束的時候進行創建。JVM會保證類的加載線程安全,所以這種情況基本上不需要考慮多線程情況下的線程安全。但是問題還是有:生命周期不可以控制,這個類一加載就存在一個實例對象。
代碼(懶漢模式,雙重檢查模式+volatile):
1 class Singleton { 2 3 private volatile static Singleton instance; 4 5 private Singleton() { 6 7 } 8 9 public static Singleton getInstance() { 10 if (instance == null) { 11 synchronized (Singleton.class) { 12 if (instance == null) { 13 return new Singleton(); 14 } 15 } 16 } 17 return instance; 18 } 19 }
說明:看這篇文章的說明
設計思想:很多類只需要有一個實例,也許只能有一個實例,當嘗試獲取多個實例時會返回相同一個實例對象(或者返回null或者報錯)。