大家好,又见面了,我是全栈君。
|–什么是装饰模式。
装饰模式:是你还是你,一切拜托你(借用老崔经典词)。
它是由继承出现的。先有继承,再有装饰。
回顾继承
优点:提高复用性,让能够反复使用。通过方法重写利用后期扩展。
坏处:因为类与类之间的继承关系。但他们关系增强。耦性也就高了。不符合java宗旨:低耦合。高内聚。
对照方下:
a:
有一个Witer体系
|–TxtWrite
|–Mp3Write
|–DIDWrite
上面是一个普通子类实现。调用者认为运行太慢,要求对三者进行增强(高效|缓冲)。改动例如以下
class myBuffereWrite exetends Write{ //接收子类:Fu f = new Zi(); private Write ziWrite; public BuffereWrite(Write ziWrite) { this.ziWrite = ziWrite; } public void writeLine(String line) { //使用ziWrite进行整容处理。然后一行数据保存到write中。 } public void close() { ziWrite.clese();//多态(调用的还是子类)! } public void flash(){ ziWrite.flash();//多态(调用的还是子类)。 } ....//重写Write的抽象方法。调用的myBuffereWrite中的,再方法里边调用是传送ziWrite。仅仅只是在调用它之前给它做了一些手术。
}
|–总结
1:比方你使用Write的高效功能,那你就创建myBuffereWrite,传递你的对其高效的对象,比方FileWrite();
2:装饰模式体现了对一个对象(功能)的增强(高内聚),然后紧密性比較弱(低耦合)。
3:JDK中用的装饰就挺多的,比方BufferedWriter(Writer out);PrintStream(OutputStream out);ObjectInputStream(InputStream in)等。
|–代码演示样例
模拟BuffereReader装饰类
package com.Decoration; import java.io.IOException; import java.io.Reader; /** * @author hubiao * 模拟BuffereReader装饰类 * * 分析:模拟一个类,就是自定一个类。实现它的特有方法:ReadLine(); * 1:模拟什么:特有方法 * 2:你有什么:依据装饰特点。自定的类继承一个抽象类,由于BuffereReader的readLine底层也是继承Reader中的。* 我们要做的。也是继承Reader,写一个与BuffereReader一样的ReadLine方法来。 */public class MyBuffere extends Reader { /*Reader是一个抽象类的父类。将须要高效的类都实现了它。
都是它的子类。
*/ private Reader reader = null; public MyBuffere(Reader reader){ this.reader = reader; } public int read(char[] cbuf, int off, int len) throws IOException { return reader.read(cbuf, off, len); } public String readLine() throws IOException { /** * 1:这里要思考,使用 * A:read(char[] cbuf, int off, int len);一次读取一缓冲区 * B:read();//一次读取一个字符串 * 2:分析 * 我们模拟readLine目的是为了模拟什么?还不是为了实现BufferedReader中的readerLine一次读取一行的高效方法。 * 然后使用A方法不合适,由于它一次读取一个char容量定义的长度,我们封装好的代码非常难获知调用者要读取的数据文本的每行数据有多长。
* 使用B方法的优点,是一次读取一个字符,当遇到\r\n就说明是一行的结束。则说一行读取完成,那怎么一行的数据每一个字符用什么保存呢? * 使用String, 这...太可怕了吧。由于我们知道String在java中是一个常量池。
一但赋值,将不可变。
所以选择效率高的StringBuilder * 把每一个字符拼接到StringBuffer中。再返回给调用者。 */ //单字符容器 StringBuffer buffer = new StringBuffer(); //每一个字符 int read = 0; while((read = reader.read())!=-1) { char chr = (char) read; if(chr=='\r') continue; if(chr=='\n') return buffer.toString(); else buffer.append(chr); } //防止读取的是最后一行。则没有\r\n。那么再推断缓冲区中是否有值?假设有,则再返回。 if(buffer.length() > 0 ) return buffer.toString(); else return null; } public void close() throws IOException { reader.close(); }}
模拟LineNumberReader
/** * @author hubiao * 模拟LineNumberReader * 也是相同,模拟,就是自定一个类,模拟需求给出的特殊方法:获取每一个行号,然后读取每一行。 */ public class MyLineNumberReader extends Reader{ /*接收传递子类对象,Fu f = new Zi();//多态*/ private Reader reader; private int lineNumber;//行号 public MyLineNumberReader(Reader reader) { this.reader = reader; } public int read(char[] cbuf, int off, int len) throws IOException { return reader.read(cbuf, off, len); } public String readLine() throws IOException { //单字符容器 StringBuffer buffer = new StringBuffer(); //每一个字符 int read = 0; while((read = reader.read())!=-1)//-1表示读取到流的结尾! { char chr = (char) read; if(chr=='\r') continue; if(chr=='\n'){ lineNumber++; return buffer.toString(); } else buffer.append(chr); } //防止读取的是最后一行,则没有\r\n。那么再推断缓冲区中是否有值?假设有,则再返回。if(buffer.length() > 0 ){ lineNumber++; return buffer.toString(); }else return null; } public void close() throws IOException { reader.close(); } public int getLineNumber() { return lineNumber; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; }}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115396.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...