裝飾模式:java
在不改變接口的前提下,動態擴展對象的訪問。
動態繼承,讓類具備在運行期改變行爲的能力。
裝飾模式,突出的是運行期增長行爲,這和繼承是不一樣的,繼承是在編譯期增長行爲。
強調:加強設計模式
代理模式:ide
在不改變接口的前提下,控制對象的訪問。
1.從封裝的角度講,是爲了解決類與類之間相互調用而由此致使的耦合關係,能夠說是接口的另一個層引用。
好比:在a類->b代理->c類這個關係中,c類的一切行爲都隱藏在b中。即調用者不知道要訪問的內容與代理了什麼對象。
2.從複用的角度講,能夠解決不一樣類調用一個複雜類時,僅僅因較小的改變而致使整個複雜類新建一個類。
好比:a類->c類1;b類->c類2。
能夠變爲a類->ca代理類->c類;b類->cb代理類-c類。
代理模式,是類之間的封裝和(某方面的)複用。
強調:限制測試
下面經過一個例子來講明二者的不一樣。當咱們衝咖啡的時候,首先你要拿咖啡粉衝好一杯咖啡,而後你能夠考慮是否加方糖或牛奶。this
那麼咖啡這個東西就能夠經過糖或奶或者糖和奶,變成加糖的咖啡、加奶的咖啡、加糖加奶的咖啡。spa
可是它仍是一杯咖啡,只是它的屬性進行了擴展。.net
接下來分別經過裝飾模式與代理模式,模擬這個過程。設計
1.裝飾模式3d
測試代碼:代理
1 Cafe cafe = new ConcreteCafe(); 2 3 Cafe milkCafe = new MilkDecorator(cafe); 4 milkCafe.getCafe(); 5 System.out.println("----------------------------------------"); 6 Cafe sugarCafe = new SugarDecorator(cafe); 7 sugarCafe.getCafe(); 8 System.out.println("----------------------------------------"); 9 Cafe sugarMilkCafe = new MilkDecorator(new SugarDecorator(new ConcreteCafe())); 10 sugarMilkCafe.getCafe(); 11 System.out.println("----------------------------------------"); 12 Cafe milkSugarCafe = new SugarDecorator(new MilkDecorator(cafe)); 13 milkSugarCafe.getCafe(); 14 System.out.println("----------------------------------------");
就像使用IO流同樣:
1 BufferedReader in1 = new BufferedReader(new InputStreamReader(new FileInputStream(file)));//字符流 2 DataInputStream in2 = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));//字節流
// DataInputStream-從數據流讀取字節,並將它們裝換爲正確的基本類型值或字符串
// BufferedInputStream-能夠經過減小讀寫次數來提升輸入和輸出的速度
對類進行了功能的加強。
2.代理模式
測試代碼:
1 Cafe cafe = new Proxy(); 2 cafe.getCafe();
如今能夠很清楚的看到:
1. 裝飾模式可讓使用者直觀的看到加強了哪些功能,而代理模式徹底限制了使用者。
2. 對裝飾模式來講,裝飾者(Decorator)和被裝飾者(Cafe)都實現同一個 接口。
3. 對代理模式來講,代理類(Proxy Class)和真實處理的類(Real Class)都實現同一個接口。
4. 此外,不論咱們使用哪個模式,均可以很容易地在真實對象的方法前面或者後面加上自定義的方法。
明顯的,裝飾模式能夠動態的擴展對象的行爲。
好比某對象有30項行爲,可是在第一階段用到1-20行爲,第二階段用到11-30項行爲,因此這時候,就能夠只定義11-20的行爲。
在第一階段運行時,能夠將1-10的行爲以「裝飾1」給加上
到第二階段運行時,能夠將「裝飾1」去掉,將21-30的能以「裝飾2」給加上。
可是繼承是在編譯期增長行爲。
優勢:
1. 裝飾模式能夠提供比繼承更多地靈活性。
2. 能夠經過一種動態的方式來擴展一個對象的功能,在運行時選擇不一樣的裝飾器,從而實現不一樣的行爲。
3. 經過使用不一樣的具體裝飾類以及這些裝飾類的排列組合,能夠創造出不少不一樣行爲的組合。能夠使用多個具體裝飾類來裝飾同一對象,獲得功能更爲強大的對象。
4. 具體構件類與具體裝飾類能夠獨立變化,用戶能夠根據須要增長新的具體構件類和具體裝飾類,在使用時再對其進行組合,原有代碼無須改變,符合「開閉原則」。
缺點:
1. 會產生不少的小對象(具體裝飾類),增長了系統的複雜性。
2. 這種比繼承更加靈活機動的特性,也同時意味着裝飾模式比繼承易於出錯,排錯也很困難,對於屢次裝飾的對象,調試時尋找錯誤可能須要逐級排查,較爲煩瑣。
裝飾者模式:
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:10:23 5 */ 6 package cafe; 7 8 /** 9 * @author zhengbinMac 10 * 抽象構件角色 11 */ 12 public interface Cafe { 13 14 public void getCafe(); 15 16 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:11:03 5 */ 6 package cafe; 7 8 /** 9 * @author zhengbinMac 10 * 具體構件角色 11 */ 12 public class ConcreteCafe implements Cafe{ 13 14 @Override 15 public void getCafe() { 16 System.out.println("上一杯原味咖啡!"); 17 } 18 19 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:13:41 5 */ 6 package cafe; 7 8 /** 9 * @author zhengbinMac 10 * 裝飾角色 11 */ 12 public class Decorator implements Cafe{ 13 14 public Cafe cafe; 15 16 public Decorator(Cafe cafe) { 17 this.cafe = cafe; 18 } 19 20 @Override 21 public void getCafe() { 22 cafe.getCafe(); 23 } 24 25 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:13:29 5 */ 6 package cafe; 7 8 /** 9 * @author zhengbinMac 10 * 具體裝飾角色 11 */ 12 public class MilkDecorator extends Decorator{ 13 14 public MilkDecorator(Cafe cafe) { 15 super(cafe); 16 } 17 18 @Override 19 public void getCafe() { 20 super.getCafe(); 21 this.addMilk(); 22 } 23 24 private void addMilk() { 25 System.out.println("加奶!"); 26 } 27 28 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:14:22 5 */ 6 package cafe; 7 8 /** 9 * @author zhengbinMac 10 * 具體裝飾角色 11 */ 12 public class SugarDecorator extends Decorator{ 13 14 public SugarDecorator(Cafe cafe) { 15 super(cafe); 16 } 17 18 @Override 19 public void getCafe() { 20 super.getCafe(); 21 this.addSugar(); 22 } 23 24 private void addSugar() { 25 System.out.println("加糖!"); 26 } 27 28 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:18:32 5 */ 6 package cafe; 7 8 import java.io.BufferedInputStream; 9 import java.io.BufferedReader; 10 import java.io.DataInputStream; 11 import java.io.File; 12 import java.io.FileInputStream; 13 import java.io.IOException; 14 import java.io.InputStream; 15 import java.io.InputStreamReader; 16 import java.util.Date; 17 18 /** 19 * @author zhengbinMac 20 * 測試類 21 */ 22 public class Test { 23 24 public static void main(String[] args) throws IOException { 25 Cafe cafe = new ConcreteCafe(); 26 27 Cafe milkCafe = new MilkDecorator(cafe); 28 milkCafe.getCafe(); 29 System.out.println("----------------------------------------"); 30 Cafe sugarCafe = new SugarDecorator(cafe); 31 sugarCafe.getCafe(); 32 System.out.println("----------------------------------------"); 33 Cafe sugarMilkCafe = new MilkDecorator(new SugarDecorator(new ConcreteCafe())); 34 sugarMilkCafe.getCafe(); 35 System.out.println("----------------------------------------"); 36 Cafe milkSugarCafe = new SugarDecorator(new MilkDecorator(cafe)); 37 milkSugarCafe.getCafe(); 38 System.out.println("----------------------------------------"); 39 40 File file = new File("/Users/zhengbinMac/test.txt"); 41 42 FileInputStream in2 = new FileInputStream(file); 43 byte[] tempByte = new byte[1024]; 44 int hasRead = 0; 45 System.out.println("開始時間:" + new Date().getTime()); 46 while((hasRead = in2.read(tempByte)) > 0) { 47 System.out.println(new String(tempByte,0,hasRead)); 48 } 49 System.out.println("結束時間:" + new Date().getTime()); 50 in2.close(); 51 52 System.out.println("----------------------------------------"); 53 54 FileInputStream in4 = new FileInputStream(file); 55 byte[] tempByte2 = new byte[(int)file.length()]; 56 System.out.println("開始時間:" + new Date().getTime()); 57 in4.read(tempByte2); 58 System.out.println("結束時間:" + new Date().getTime()); 59 in4.close(); 60 System.out.println(new String(tempByte2)); 61 62 System.out.println("----------------------------------------"); 63 64 // DataInputStream in3 = new DataInputStream(new FileInputStream(file)); 65 // String s; 66 // System.out.println("開始時間:" + new Date().getTime()); 67 // while((s=in3.readLine()) != null) { 68 // System.out.println(s); 69 // } 70 // System.out.println("結束時間:" + new Date().getTime()); 71 // in3.close(); 72 73 System.out.println("----------------------------------------"); 74 75 // DataInputStream in5 = new DataInputStream(new BufferedInputStream(new FileInputStream(file))); 76 // String s1; 77 // System.out.println("開始時間:" + new Date().getTime()); 78 // while((s1 = in5.readLine()) != null) { 79 // System.out.println(s1); 80 // } 81 // System.out.println("結束時間:" + new Date().getTime()); 82 // in5.close(); 83 84 System.out.println("----------------------------------------"); 85 86 BufferedReader in6 = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 87 String s2; 88 System.out.println("開始時間:" + new Date().getTime()); 89 while((s2 = in6.readLine()) != null) { 90 System.out.println(s2); 91 } 92 System.out.println("結束時間:" + new Date().getTime()); 93 in6.close(); 94 95 System.out.println("----------------------------------------"); 96 97 98 } 99 100 }
代理模式:
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月26日 下午8:30:42 5 */ 6 package cafe3; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public interface Cafe { 13 14 public void getCafe(); 15 16 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月26日 下午8:32:08 5 */ 6 package cafe3; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class ConcreteCafe implements Cafe{ 13 14 @Override 15 public void getCafe() { 16 System.out.println("上一杯原味咖啡!"); 17 } 18 19 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月26日 下午8:33:05 5 */ 6 package cafe3; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class Proxy implements Cafe{ 13 14 private ConcreteCafe concreteCafe; 15 16 public Proxy() { 17 this.concreteCafe = new ConcreteCafe(); 18 } 19 20 @Override 21 public void getCafe() { 22 concreteCafe.getCafe(); 23 addMilk(); 24 addSugar(); 25 } 26 27 private void addMilk() { 28 System.out.println("加奶!"); 29 } 30 31 private void addSugar() { 32 System.out.println("加糖!"); 33 } 34 35 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月26日 下午8:38:51 5 */ 6 package cafe3; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class Test { 13 14 public static void main(String[] args) { 15 Cafe cafe = new Proxy(); 16 cafe.getCafe(); 17 } 18 19 }
繼承:
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:30:41 5 */ 6 package cafe2; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class Cafe { 13 14 public void getCafe() { 15 System.out.println("來一杯原味咖啡!"); 16 } 17 18 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:32:32 5 */ 6 package cafe2; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class MilkCafe extends Cafe{ 13 14 @Override 15 public void getCafe() { 16 super.getCafe(); 17 this.addMilk(); 18 } 19 20 private void addMilk() { 21 System.out.println("加奶!"); 22 } 23 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:31:09 5 */ 6 package cafe2; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class SugarCafe extends Cafe{ 13 14 @Override 15 public void getCafe() { 16 super.getCafe(); 17 this.addSugar(); 18 } 19 20 private void addSugar() { 21 System.out.println("加糖!"); 22 } 23 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月26日 下午3:01:26 5 */ 6 package cafe2; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class SugarMilkCafe extends Cafe{ 13 @Override 14 public void getCafe() { 15 super.getCafe(); 16 this.addSugarAndMilk(); 17 } 18 19 private void addSugarAndMilk() { 20 System.out.println("加糖!"); 21 System.out.println("加奶!"); 22 } 23 }
1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All right reserved. 4 * 2016年6月23日 上午11:33:22 5 */ 6 package cafe2; 7 8 /** 9 * @author zhengbinMac 10 * 11 */ 12 public class Test { 13 14 public static void main(String[] args) { 15 Cafe milkCafe = new MilkCafe(); 16 milkCafe.getCafe(); 17 18 Cafe sugarCafe = new SugarCafe(); 19 sugarCafe.getCafe(); 20 21 Cafe sugarMilkCafe = new SugarMilkCafe(); 22 sugarMilkCafe.getCafe(); 23 } 24 25 }