装饰者设计模式

/*
装饰设计模式:
当想要对已有的对象进行功能增强时,
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么自定义的该类成为装饰类。

装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象提供更强的功能。



装饰类和继承的区别:

MyReader //专门用于读取数据的类。继承体系:
	|--MyTextReader
		|--MyBufferTextReader
	|--MyMediaReader
		|--MyBufferMediaReader
	|--MyDataReader
		|--MyBufferDataReader

class MyBufferReader
{
	private MyBufferTextReader text;
	private MyBufferMediaReader media;
	private MyBufferDataReader data;
	MyBufferReader(MyBufferTextReader text)
	{
		this.text = text;
	}
	MyBufferReader(MyBufferMediaReader media)
	{
		this.media = media;
	}
	MyBufferReader(MyBufferDataReader data)
	{
		this.data = data;
	}
}
上面这个类扩展性很差。
找到其参数的共同类型,通过多态的形式,可以提高扩展性。
eg:
class MyBufferReader extends MyReader
{
	private MyReader r;
	MyBufferReader(MyReader r)
	{
		this.r = r;
	}
}

通过装饰类优化后:
    |--MyTextReader
	|--MyMediaReader
	|--MyDataReader
	|--MyBufferReader

装饰模式比继承要灵活,避免了继承体系的臃肿,而且降低了类与类之间的关系。

装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能。
所以装饰类和被装饰类通常都是属于一个体系中的。
*/

class Person{
	public void eat(){
		System.out.println("吃饭");
	}
}

/*对Person进行增强*/
class SuperPerson{
	private Person p;
	SuperPerson(Person p){
		this.p = p;
	}
	public void superEat(){
		System.out.println("开胃菜");
		p.eat();
		System.out.println("甜点");
	}
}

class PersonDemo{
	public static void main(String[] args) {
		Person p = new Person();
		//p.eat();
		SuperPerson sp = new SuperPerson(p);
		sp.eat();
	}
}
/*-----------------------------------------------------------------*/
/*
eg:自定义字符流缓冲区包装类。
*/
import java.io.*;
class MyBufferedReader extends Reader{
	private Reader r;
	MyBufferedReader(Reader r){
		this.r = r;
	}

	//可以一次读一行数据的方法
	public String MyReaderLine()throws IOException{
		/*
			定义一个临时容器。原BufferedReader封装的是字符数组。
			为了演示方便,定义一个StringBuilder容器。因为最终还是要变成字符串。
		*/
		StringBuilder sb = new StringBuilder();
		while((int ch = r.read()) != -1){
			if(ch == '\r')
				continue;
			if(ch == '\n')
				return sb.toString();
			else
				sb.append((char)ch);
		}
		if(sb.length() != 0)
			return sb.toString();
		return null;
	}
	public void MyClose()throws IOException{
		r.close();
	}

	/*
		覆盖Reader类中的抽象方法。
	*/
	public void close()throws IOException{
		r.close();
	}
	public int read(char[] cbuf,int off,int len)throws IOException{
		return r.read(cbuf,off,len);
	}
}

class MyBufferedReaderDemo{
	public static void main(String[] args){
		FileReader fr = null;
		MyBufferedReader mybr = null;
		try{
			fr = new FileReader("copyText.java");
			mybr = new MyBufferedReader(fr);
			while((String line = mybr.myReadLine()) != null){
				System.out.println(mybr.MyReaderLine()+":"+line);
			}
		}catch (IOException e){
			throw new IOException("读写失败!");
		}finally{
			try{
				if(mybr != null)
					mybr.myClose();
			}catch (IOException e){
				throw new IOException("读写失败!");
			}	
		}
	}
}
/*
eg:自定义带行号的字符流包装类。
*/
import java.io.*;
class MyLineNumberReader extends MyBufferedReader{
	//private Reader r;
	private int lineNumber;

	MyLineNumberReader(Reader r){
		//this.r = r;
		super(r);
	}
	/*
	public String myReadLine()
	{
		lineNumber ++;
		StringBuilder sb = new StringBuilder();

		while((int ch == r.read) != -1){
			if(ch == '\r')
				continue;
			if(ch == '\n')
				return sb.toString();
			else
				sb.append((char)ch);
		}
		if(sb.length() != 0)
			return sb.toString();
		return null;
	}
	*/
	public void setLineNumber(int lineNumber){
		this.lineNumber = lineNumber;
	}
	public void getLineNumber(){
		return lineNumber;
	}
	/*
	public void myClose()
	{
		r.close();
	}
	*/
}

class MyLineNumberReaderDemo{
	public static void main(String[] args){
		FileReader fr = null;
		MyLineNumberReader mylnr = null;
		try{
			fr = new FileReader("copyText.java");
			mylnr = new MyLineNumberReader(fr);
			while((String line = mylnr.myReadLine()) != null){
				System.out.println(mylnr.getLineNumber()+":"+line);
			}
		}catch (IOException e){
			throw new IOException("读写失败!");
		}finally{
			try{
				if(mylnr != null)
					mylnr.myClose();
			}catch (IOException e){
				throw new IOException("读写失败!");
			}	
		}
	}
}
/*
eg:自定义字节流缓冲区包装类。
*/
import java.io.*;
class MyBufferedInputStream{
	private InputStream in;

	private byte[] buffer = new byte[1024];

	private int pos = 0;

	private int count = 0;

	MyBufferedInputStream(InputStream in){
		this.in = in;
	}

	//一次读一个字节,从缓冲区(字节数组)获取。
	public int myRead() throws IOException{
		//通过in对象读取硬盘上数据,并存储buffer中
		if(count == 0){
			count = in.read(buffer);
			if(count < 0)
				return -1;
			pos = 0;
			byte b = buffer[pos];

			count --;
			pos ++;
			return b&255;
		}else if(count > 0){
			byte b = buffer[pos];

			count --;
			pos ++;
			return b;
		}
		return -1;
	}
	public void MyClose(){
		in.close();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值