黑马程序员-装饰设计模式

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
概念(纯个人理解)

想创建一个B类,在A类的基础上增强一些功能,但考虑到更改A类的代码时可能会导致一些错误。因此在B类的构造方法中接受A类的引用,在B类中基于A的对象提供更强功能。这种设计模式就叫装饰设计模式。

 

装饰与继承的区别:

继承的逻辑结构:

Reader

|-- TextReader

|--BufferedTextReader

|-- MediaReader

|--BufferedMediaReader

|-- DataReader

|--BufferedDataReader

说明:通过上面的框架可以看出,如果Reader类下面还有其他子类,并想对此子类进行Buffered功能时,仍需要再继承一个。这就造成了代码臃肿。

 

装饰的逻辑结构: 

Reader

|-- TextReader

|-- MediaReader

|-- DataReader

|--BufferedReader(Reader r)

装饰设计模式,则是将修饰类,与被装饰的类放在同一级别中。找到被装饰类们的共同类型,将其传递到装饰类的构造方中。

	package com.lxh.io;
	import java.io.*;
	// 装饰类与被装饰类是同一级别的,都继承了同一个父类。
	public class MyBufferedReader extends Reader {
	
		// 创建构造函数,且该构造函数的参数为抽象出来的同一类型。传入一个FileReader
		private Reader r;
		// 构造函数没有返回类型,因为类的名称,就是返回类型了。
		public MyBufferedReader(Reader r) {
			this.r = r;
		}
		
		public String myReadLine() throws IOException{
			int ch;
			StringBuilder sb = new StringBuilder();
			// FileReader的返回值是int类型的字符。
			while((ch = r.read()) != -1) {
				//当判断结尾是\r\n 时,返回字符串。
				if(ch == '\r')
					continue;
				if(ch == '\n')
					//将StringBuilder转换成为String类型。
					return sb.toString();
				// 将int转换成char
				sb.append((char)ch);
			}
			// 当最后一行时,如果结尾处没有回车,在while循环中就不能将这一行字符加到
			// StringBuffer中,故此需要再判断一次。
			if(sb.length() != 0) {
				return sb.toString();
			}
			//当是流的最后时,返回null。
			return null;
		}
		// close()方法
		public void myClose()  throws IOException{
			r.close();
		}
		
		// 实现read方法的抽象方法。
		public void close() throws IOException {
			r.close();
		}
		public int read(char[] cbuf, int off, int len) throws IOException {
			return r.read(cbuf, off, len);
		}
	}
package com.lxh.io;
import java.io.*;
import java.io.FileReader;
import java.io.IOException;

public class TestMyBuffer {

	public static void main(String[] args) {
		MyBufferedReader myBuf = null;
		FileReader fr = null;
		try {
			fr = new FileReader("BufferdWriterDemo.txt");
			myBuf = new MyBufferedReader(fr);
			String line = null;
			while((line = myBuf.myReadLine()) != null) {
				System.out.println(line);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				myBuf.myClose();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
	}

}

MyLinebumberReader

添加个功能。

getLineNumber

setLineNumber

readLine

 

因为很多的方法和MyBufferedReader类中的方法是相同的,所以继承该类。

package com.lxh.io;
import java.io.*;

public class MyLineNumberReader extends MyBufferedReader {
	
	public MyLineNumberReader(Reader r) {
		super(r);
		// TODO Auto-generated constructor stub
	}
	
	private int num ;
	// 设置处理num的方法
	public void mySetLineNumber(int num) {
		this.num = num ;
	}

	public int myGetLineNumber() {
		return this.num ;
	}
	
	public String myReadLine() throws IOException{
		num++;
		return super.myReadLine();
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值