裝飾模式 – JAVA編程語言程序開發技術文章

java IO中使用瞭一個非常重要的設計模式:裝飾模式。裝飾模式的使用是復雜的IO變得簡單,免除瞭實現IO操作需要的繁瑣操作。理解裝飾模式對於正確使用IO很重要。下面是簡單的裝飾模式例子,從過程上闡釋瞭裝飾模式的內涵。

首先,需要瞭解什麼是裝飾模式:裝飾模式(Decorator Pattern)又叫包裝模式(Wrapper Pattern),它以對客戶端透明的方式擴展對象的功能。是繼承關系的一種替代方案。

換言之,裝飾模式用一種另外的方式實現瞭繼承這一面向對象編程的基本功能。也就是說,裝飾模式可以在不創造更多子類的情況下,將對象的功能加以擴展。

我們知道,java IO中需要完成對不同輸入輸出源的操作,如果單純的使用繼承這一方式,無疑需要很多的類。比如說,我們操作文件需要一個類,實現文件的字節讀取需要一個類,實現文件的字符讀取又需要一個類….一次類推每個特定的操作都需要一個特定的類。這無疑會導致大量的IO繼承類的出現。顯然對於編程是很不利的。而是用裝飾模式則可以很好的解決這一問題,在裝飾模式中:節點流(如FileInputStream)直接與輸入源交互,之後通過過濾流(FilterInputStream)進行裝飾,這樣獲得的io對象便具有某幾個的功能。很好的拓展瞭IO的功能。

裝飾模式的角色:

1.抽象構建角色(Component)

給出一個抽象接口,以規范準備接受附加責任的對象。顯然,從功能上看,這一角色對應IO操作中的InputStream/OuputStream這些底層的抽象類。

2.具體構建角色(Concrete Component)

定義一個將要接收附加責任類的對象。也就是實現瞭抽象構建角色的方法聲明。它應該對應IO操作中的節點流,即直接與輸入輸出源交互的流。

3.裝飾角色(Decorator)

持有一個構建(Component)的引用,並定義一個與抽象構件接口一致的接口。它應該對應IO操作中的裝飾流(即FilterInputStream)。

4.具體裝飾角色(Concrete Decorator)

負責給構件對象“貼上”附加的責任。也就是擴展構件對象的功能。它對應於IO中的具體過濾流,即FilteInpuStreamr的子類。

以下是一個簡單演示裝飾模式的代碼:

首先是抽象構建角色(Component.java)

[java] 
/**
 * 裝飾模式:是繼承關系的擴展,增加對象的功能。可以在不創造更多子類的情況下
 * 對類的功能進行擴展
 *裝飾模式的角色:
 *1.抽象構件角色(對應於io中的InputStream)
 *2.具體構件角色(對應於Io中的節點流)
 *3.裝飾角色(對應於IO中的FilterStream)
 *4.具體裝飾角色(對應於IO中的裝飾器)
 */ 
public interface Component 

    public void doSomething(); 
     

然後是具體構建角色(ConcreteComponent.java),實現瞭抽象構件中的方法
[java]
public class ConcreteComponent implements Component 

 
    @Override 
    public void doSomething() 
    { 
        System.out.println("功能A"); 
    } 
     

接著是裝飾角色(Decorator.java)持有一個構建(Component)的引用,並定義一個與抽象構件接口一致的接口。即引用瞭ConcreteComponent.java中的doSomeThing()方法。
[java] 
public class Decorator implements Component 

    private Component component; 
    public Decorator(Component component) 
    { 
        this.component = component; 
    } 
    @Override 
    public void doSomething() 
    { 
        component.doSomething(); 
    } 
     

最後是具體的裝飾角色,即直接呈現給用戶的裝飾角色。這裡構建瞭兩個裝飾角色(ConcreteDecorator1.java 和ConcreteDecorator2.java)
 ConcreteDecorator1.java
[java]
public class ConcreteDecorator1 extends Decorator 

 
    public ConcreteDecorator(Component component) 
    { 
        super(component); 
    } 
    @Override 
    public void doSomething() 
    { 
        super.doSomething(); 
        this.doAnotherThing(); 
    } 
    private void doAnotherThing() 
    { 
        System.out.println("功能B"); 
    } 
     

ConcreteDecorator2.java
[java]
public class ConcreteDecorator2 extends Decorator 

 
    public ConcreteDecorator1(Component component) 
    { 
        super(component); 
         
    } 
    @Override 
    public void doSomething() 
    { 
        super.doSomething(); 
        this.doAnotherThing(); 
    } 
    private void doAnotherThing() 
    { 
        System.out.println("功能C"); 
    } 
     

現在我們測試一下:

[java] 
public class Client 

    public static void main(String[] args) 
    { 
        Component component = new ConcreteComponent(); 
        //相當於 InputStream stream = new FileInputStream("filepath");得到節點流 
        Component component2 = new ConcreteDecorator(component); 
        //相當於 InputStream stream2 = new BufferedInputStream(stream);過濾流裝飾節點流 
        Component component3 = new ConcreteDecorator1(component2); 
        //相當於 InputStream stream3 = new DataInputStream(stream2);過濾流裝飾過濾流 
        component3.doSomething(); 
        //相當於 stream3.read();調用方法 
     
    } 

打印結果:
功能A
功能B
功能C

通過測試結果我們看出,三個類一個接口最終實現瞭對象功能的擴展。(調用瞭三個方法)。用另一種方式,實現瞭繼承所能完成的功能。這就是裝飾模式。

 

發佈留言