java 装饰器模式
http://eneasy.iteye.com/blog/174840
http://www.cnblogs.com/ikuman/archive/2013/01/29/2877913.html
1.意圖:?
??? 在一個對象的外圍創建一個稱為裝飾器的封裝,動態地給這個對象添加一些額外的功能。?
2.類圖:?
?????
3.原理:?
????? 在一個對象的外圍創建一個稱為裝飾器的封裝,動態地給這個對象添加一些額外的功能。以對客戶端透明的方式擴展對象的功能。?
?????? 裝飾器模式又稱為包裹模式(wrapper),因為一個具體裝飾器都將下一個具體裝飾器或具體構件類包裹起來。如有三個裝飾器類Decorator1, Decorator2, Decorator3,它們的典型的創建過程為new Decorator1(new Decorator2(new Decorator3(new ConcreteComponent()))).?
??? 這樣Decorator1包裹了Decorator2,Decorator2包裹了Decorator3,Decorator3包裹了ConcreteComponent對象,每一層包裹都提供了新的功能。如圖:?
interface Person {void doCoding(); }class Employee implements Person {public void doCoding() {System.out.println("程序員寫程序");} }abstract class Manager implements Person {public abstract void doCoding(); }class ManagerA extends Manager {private Person person;public ManagerA(Person person) {super();this.person = person;}public void doCoding() {doEarlyWork();person.doCoding();}public void doEarlyWork() {System.out.println("項目經理A做需求分析");System.out.println("項目經理A做架構設計");} }class ManagerB extends Manager {private Person person;public ManagerB(Person person) {super();this.person = person;}public void doCoding() {person.doCoding();doEndWork();}public void doEndWork() {System.out.println("項目經理B做收尾工作");} }public class Decorator {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubPerson employee = new Employee();employee = new ManagerA(employee);employee = new ManagerB(employee);employee.doCoding(); }}
項目經理A做需求分析
項目經理A做架構設計
程序員寫程序
項目經理B做收尾工作
優點:?
??? 裝飾器與繼承的目的都是擴展對象的功能,但裝飾器提供了比繼承更大的靈活性,可以動態的決定是“粘上”還是“去掉”一個裝飾。?
????? 通過使用不同的具體裝飾類和這些類的排列組合,可以創建出很多不同行為的組合。?
??? 缺點:?
??? 裝飾器比繼承關系使用更少的類,但比繼承關系使用更多的對象,更多的對象會使查錯變得更困難,特別是這些對象看上去很像的時候。?
實際應用中的例子:java i/o
還是head first中的圖清晰明了
第二層是concretcomponents和abstract decorator
concretcomponents是實現具體或者核心任務的類(負責實際將磁盤上的數據讀入到內存), concret decorators只是在這個核心任務類的基礎上做些前處理或者后處理的事情
第三層是concret decorators,實現的是對某一個concret component和其他concrete decorator的包裝或者修飾
比如,InputStream in = new ?BufferedInputStream(new FileInputStream("txt"));
FileInputStream是一個concrete component, 其作用是讀取磁盤上的文件,將其的一個對象給BufferedInputStream對象的一個成員變量,其中BufferedInputStream是一個concrete decorator, 由具體的修飾類對具體成分類進行“后處理”或者“預處理”,其作用就是調用FileInputStream讀取磁盤上的文件,但是在BufferedInputStream內部使用緩沖區,加速文件讀取。
也可以寫成這樣的形式
InputStream in = new LineNumberInputStream(new BufferedInputStream(new FileInputStream("tt")));
具體修飾類可以多次“包裝”
可以自己實現一個具體修飾類
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream;//concrete decorator class LowerInputStream extends FilterInputStream {public LowerInputStream(InputStream in) {super(in);}public int read() throws IOException {int c = super.read();return (c == -1? c: Character.toLowerCase((char)c));}public int read(byte[]b, int offset, int len) throws IOException {int result = super.read(b, offset, len);for (int i = 0; i < len; ++i) {b[i] = (byte)Character.toLowerCase((char)b[i]);}return result;} }public class Decorator {public static void main(String[] args) throws Exception{// TODO Auto-generated method stubInputStream in = new LowerInputStream(new BufferedInputStream(new FileInputStream("tt")));int c;while((c = in.read()) >=0) {System.out.print((char)c);}}}
上面分析的是面向字節流的類,接下來分析面向字符流的
其中最重要的是InputStreamReader,起到將字節流按照指定編碼改變為字符流的作用
從上圖可以看到,StreamDecoder是一個適配器,將InputStream字節流,按照Reader的接口改變成字符流
其實InputStreamReader也可以看做一個適配器,將StreamDecoder,按照Reader接口進行改裝
如果把InputStreamReader看做一個具體component,那么BufferedReader就是一個具體的修飾類
所以,我們通常這樣寫
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("D:/cplus/norm/norm/exp"), "UTF-8"));
總結
以上是生活随笔為你收集整理的java 装饰器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 动态代理深度学习(Proxy,
- 下一篇: java适配器模式