常用设计模式__之【装饰设计模式】


装饰模式的体现之一:

BufferedReader 类中readLine()方法

原理readLine()调用的还是read()方法,在硬盘上一个一个的读取,暂时存储起来,当读取到换行符时就把读取的值返回完成一行数据的读取

模拟BufferedReader类中readLine方法

import java.io.*;
class MyBufferedReader 
{
	private FileReader r;	//私有化成员变量
	MyBufferedReader(FileReader r)//将读取流对象传入构造函数
	{	
		this.r=r;
	}
	public String myReadLine() throws IOException//可以一次读取一行的方法
	{//定义临时容器,原BufferReader封装了字符数组
		StringBuilder sb = new StringBuilder();//最终数据还是要转成字符串,为了方便,定义StringBuilder容器
		int ch = 0;
		while ((ch=r.read()) !=-1)
		{					
			if (ch=='
')//Windows中java换行符是 

				continue;//
			if (ch=='
')
				return sb.toString();//当读取到换行时,将缓冲区中字符串返回
			else
				sb.append((char)ch);//读取不到换行,缓冲区就一直增加,由于ch是read返回的该字符在码表中的int值,所以要强转
		}
		if(sb.length() !=0)		//此判断是为了处理文件末尾没有换行符的情况
			return sb.toString();
		return null;//方法明确了返回值为String,
	}
	public void myClose() throws IOException
	{
		r.close();
	}
}
readLine()是read()方法的增强,BufferedReader是FileReader类的增强类,
将被增强类的对象作为参数传入增强类 

装饰设计模式

当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,提供加强功能,自定的该类称为装饰类

示例:

class Person{
	public void eat(){
		System.out.println("吃饭");
	}
}
class SuperPerson{//装饰类
	private Person p;	//将被装饰的类作为成员变量
	SuperPerson(Person p){//嵌入到装饰类
		this.p = p;
	}
	public void superEat(){	//装饰类更强大的功能
		System.out.println("开胃菜");
		p.eat();
		System.out.println("饭后甜点");
		System.out.println("Smoke~");
	}
}
class  DecorateDemo{
	public static void main(String[] args) {
		Person p = new Person();
		SuperPerson sp = new SuperPerson(p);
		sp.superEat();
	}
}

装饰和继承的关系:

通过继承生成子类同样可以达到扩展功能的效果,但是相比之下,装饰模式降低了两个类之间的关联度,具有更高的灵活性和扩展性

MyReader//专门用于读取数据的类。
	|--MyTextReader
		|--MyBufferTextReader
	|--MyMediaReader
		|--MyBufferMediaReader
	|--MyDataReader
		|--MyBufferDataReader
class MyBufferReader{
	MyBufferReader(MyTextReader text)
	{}
	MyBufferReader(MyMediaReader media)
	{}
}
上面这个类扩展性很差。找到其参数的共同类型。通过多态的形式。可以提高扩展性。

class MyBufferReader extends MyReader{//组合结构
	private MyReader r;
	MyBufferReader(MyReader r)
	{}
}

通过继承将每一个子类都具备缓冲功能。而继承体系比较复杂,并不利于扩展。
现在优化思想。单独描述一下缓冲内容。将需要被缓冲的对象。传递进来。
也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单。优化了体系结构。

优化后的体系:

MyReader//专门用于读取数据的类。
	|--MyTextReader
	|--MyMediaReader
	|--MyDataReader
	|--MyBufferReader//

装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常是都属于一个体系中的。

装饰模式的体现之二:

BufferedReader的子类LineNumberReader
主要方法:setLineNumber(int x),设置当前行号
和getLineNumber(),获得当前行号

示例:

import java.io.*;
class  LineNumberReaderDemo	
{
	public static void main(String[] args) throws IOException
	{
		FileReader fr = new FileReader("LineNumberReaderDemo.java");
		LineNumberReader lnr = new LineNumberReader(fr);
		String line = null;
		lnr.setLineNumber(10);//设置当前行号
		while ((line=lnr.readLine()) !=null)
		{
			System.out.println(lnr.getLineNumber()+" : "+line);
		}
		lnr.close();
	}
}

手动模拟实现一个LineNumberReader类

class MyLineNumberReader extends MyBufferedReader //继承,参考之前的readLine()实现
{
	MyLineNumberReader(Reader r){	//继承自父类,省略成员的私有化步奏
		super(r);
	}
	public String myReadLine() throws IOException{
		lineNumber++;			//相对于父类的readline()仅增加了计数功能
		return super.myReadLine();//继承自父类
	}
	public void setLineNumber(int lineNumber){	//子类特有方法
		this.lineNumber = lineNumber;
	}
	public int getLineNumber(){	//子类特有方法
		return lineNumber;
	}//关闭流的动作父类中已经实现了,不需要再覆盖,直接调用即可
}


原文地址:https://www.cnblogs.com/Joure/p/4337214.html