裝飾者模式

定義:動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式相比生成子類更爲靈活。

 

結構圖:

 

Component: 

定義一個對象接口,可以給這些對象動態地添加職責。 

public interface Component
{
	void operation();
}
 

Concrete Component: 

定義一個對象,可以給這個對象添加一些職責。 

public class ConcreteComponent implements Component
{
	public void operation()
	{
		// Write your code here
	}
}
 

Decorator: 

維持一個指向Component對象的引用,並定義一個與 Component接口一致的接口。 

public class Decorator implements Component
{
	public Decorator(Component component)
	{
		this.component = component;
	}
	
	public void operation()
	{
		component.operation();
	}
	
	private Component component;
}
 

Concrete Decorator: 

在Concrete Component的行爲之前或之後,加上自己的行爲,以“貼上”附加的職責。 

public class ConcreteDecorator extends Decorator
{
	public void operation()
	{
		//addBehavior也可以在前面
		
		super.operation();
		
		addBehavior();
	}
	
	private void addBehavior()
	{
		//your code
	}
}


 

模式的簡化:

1. 如果只有一個Concrete Component類而沒有抽象的Component接口時,可以讓Decorator繼承Concrete Component。

2. 如果只有一個Concrete Decorator類時,可以將Decorator和Concrete Decorator合併。

 

裝飾模式在Java I/O庫中的應用:

編寫一個裝飾者把所有的輸入流內的大寫字符轉化成小寫字符:

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class LowerCaseInputStream extends FilterInputStream
{
	protected LowerCaseInputStream(InputStream in)
	{
		super(in);
	}
	
	@Override
	public int read() throws IOException
	{
		int c = super.read();
		return (c == -1 ? c : Character.toLowerCase((char) c));
	}
	
	@Override
	public int read(byte[] b, int offset, int len) throws IOException
	{
		int result = super.read(b, offset, len);
		
		for (int i = offset; i < offset + result; i++)
		{
			b[i] = (byte) Character.toLowerCase((char) b[i]);
		}
		
		return result;
		
	}
}


測試我們的裝飾者類:

import java.io.*;

public class InputTest
{
	public static void main(String[] args) throws IOException
	{
		int c;
		
		try
		{
			InputStream in = new LowerCaseInputStream(new BufferedInputStream(
					new FileInputStream("D:\\test.txt")));
			
			while ((c = in.read()) >= 0)
			{
				System.out.print((char) c);
			}
			
			in.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章