java 装饰器模式
http://eneasy.iteye.com/blog/174840
http://www.cnblogs.com/ikuman/archive/2013/01/29/2877913.html
1.意圖:?
??? 在一個對象的外圍創(chuàng)建一個稱為裝飾器的封裝,動態(tài)地給這個對象添加一些額外的功能。?
2.類圖:?
?????
3.原理:?
????? 在一個對象的外圍創(chuàng)建一個稱為裝飾器的封裝,動態(tài)地給這個對象添加一些額外的功能。以對客戶端透明的方式擴展對象的功能。?
?????? 裝飾器模式又稱為包裹模式(wrapper),因為一個具體裝飾器都將下一個具體裝飾器或具體構(gòu)件類包裹起來。如有三個裝飾器類Decorator1, Decorator2, Decorator3,它們的典型的創(chuàng)建過程為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("項目經(jīng)理A做需求分析");System.out.println("項目經(jīng)理A做架構(gòu)設(shè)計");} }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("項目經(jīng)理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(); }}
項目經(jīng)理A做需求分析
項目經(jīng)理A做架構(gòu)設(shè)計
程序員寫程序
項目經(jīng)理B做收尾工作
優(yōu)點:?
??? 裝飾器與繼承的目的都是擴展對象的功能,但裝飾器提供了比繼承更大的靈活性,可以動態(tài)的決定是“粘上”還是“去掉”一個裝飾。?
????? 通過使用不同的具體裝飾類和這些類的排列組合,可以創(chuàng)建出很多不同行為的組合。?
??? 缺點:?
??? 裝飾器比繼承關(guān)系使用更少的類,但比繼承關(guān)系使用更多的對象,更多的對象會使查錯變得更困難,特別是這些對象看上去很像的時候。?
實際應(yīng)用中的例子:java i/o
還是head first中的圖清晰明了
第二層是concretcomponents和abstract decorator
concretcomponents是實現(xiàn)具體或者核心任務(wù)的類(負責實際將磁盤上的數(shù)據(jù)讀入到內(nèi)存), concret decorators只是在這個核心任務(wù)類的基礎(chǔ)上做些前處理或者后處理的事情
第三層是concret decorators,實現(xiàn)的是對某一個concret component和其他concrete decorator的包裝或者修飾
比如,InputStream in = new ?BufferedInputStream(new FileInputStream("txt"));
FileInputStream是一個concrete component, 其作用是讀取磁盤上的文件,將其的一個對象給BufferedInputStream對象的一個成員變量,其中BufferedInputStream是一個concrete decorator, 由具體的修飾類對具體成分類進行“后處理”或者“預(yù)處理”,其作用就是調(diào)用FileInputStream讀取磁盤上的文件,但是在BufferedInputStream內(nèi)部使用緩沖區(qū),加速文件讀取。
也可以寫成這樣的形式
InputStream in = new LineNumberInputStream(new BufferedInputStream(new FileInputStream("tt")));
具體修飾類可以多次“包裝”
可以自己實現(xiàn)一個具體修飾類
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);}}}
上面分析的是面向字節(jié)流的類,接下來分析面向字符流的
其中最重要的是InputStreamReader,起到將字節(jié)流按照指定編碼改變?yōu)樽址鞯淖饔?/span>
從上圖可以看到,StreamDecoder是一個適配器,將InputStream字節(jié)流,按照Reader的接口改變成字符流
其實InputStreamReader也可以看做一個適配器,將StreamDecoder,按照Reader接口進行改裝
如果把InputStreamReader看做一個具體component,那么BufferedReader就是一個具體的修飾類
所以,我們通常這樣寫
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("D:/cplus/norm/norm/exp"), "UTF-8"));
總結(jié)
以上是生活随笔為你收集整理的java 装饰器模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 动态代理深度学习(Proxy,
- 下一篇: java适配器模式