设计模式4:装饰模式(1)
2015-09-12 21:07
302 查看
作用:
基于已经存在的功能提供增强功能。
将扩展的类作为新的类的构造函数参数传入,然后对这个类进行装饰处理。
为了让装饰者有被装饰的功能,需要存在继承关系。
简单的点讲就是为了扩展一个已定义好的类的功能,而不修改原来类的定义,原来的类仍然可以继续使用,现在定义一个新的类继承原来的类,同时在这个新的类中定义父类的成员变量,同时在构造方法中将外界的一个父类对象传给这个成员变量,然后既可以通过这个成员变量使用父类的方法,同时又可以增加新的方法实现对父类功能的扩充。例如IO流中很多类都采用了装饰模式,如BufferedReader类是装饰了Reader类,LineNumberReader类装饰了BufferedReader类。
示例1:
示例2:
未完,待续。
基于已经存在的功能提供增强功能。
将扩展的类作为新的类的构造函数参数传入,然后对这个类进行装饰处理。
为了让装饰者有被装饰的功能,需要存在继承关系。
简单的点讲就是为了扩展一个已定义好的类的功能,而不修改原来类的定义,原来的类仍然可以继续使用,现在定义一个新的类继承原来的类,同时在这个新的类中定义父类的成员变量,同时在构造方法中将外界的一个父类对象传给这个成员变量,然后既可以通过这个成员变量使用父类的方法,同时又可以增加新的方法实现对父类功能的扩充。例如IO流中很多类都采用了装饰模式,如BufferedReader类是装饰了Reader类,LineNumberReader类装饰了BufferedReader类。
示例1:
package com.qianfeng.decorator; public class Demo12 { public static void main(String[] args) { Person p1 = new Zhansan(); p1.show(); Person p2 = new JeansDecorator(p1); p2.show(); Person p3 = new ShirtDecorator(p1); p3.show(); } } interface Person { void show();// 显示一个人 } abstract class DecoratorPerson implements Person { private Person person; DecoratorPerson(Person person) { this.person = person; } } class JeansDecorator extends DecoratorPerson { JeansDecorator(Person person) { super(person); // TODO Auto-generated constructor stub } @Override public void show() { System.out.println("穿牛仔裤的person"); } } class ShirtDecorator extends DecoratorPerson { ShirtDecorator(Person person) { super(person); // TODO Auto-generated constructor stub } @Override public void show() { System.out.println("穿t恤的person"); } } class Zhansan implements Person { @Override public void show() { System.out.println("没有任何装饰的张三"); } }
示例2:
package com.qianfeng.decorator; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class Demo13 { // LineNumberReader 装饰类,继承了BufferedReader public static void main(String[] args) throws IOException { FileReader fr = new FileReader("src/temp.txt"); // LineNumberReader lnr = new LineNumberReader(fr); // String line = null; // lnr.setLineNumber(100); // while ((line = lnr.readLine()) != null) { // System.out.println(lnr.getLineNumber() + ":" + line); // } // lnr.close(); MyLineNumberReader lnr = new MyLineNumberReader(fr); String line = null; // lnr.setLineNumber(1000); while ((line = lnr.MyReadLine()) != null) { System.out.println(lnr.getLineNumber() + ":" + line); } lnr.myClose(); } } /* * setLineNumber():设置起始行号 * * myReadLine():每次读取一行 * * getLineNumber():获得当前行号 */ class MyBufferedReader { private Reader r; // 真正读取功能的类 private char[] arr = new char[512];// 相当于缓冲区 private int index; // 数组下标 private int count; // 统计缓冲区中字符个数 public MyBufferedReader(Reader r) { this.r = r; } // 实现一次读取一个的功能 public int myRead() throws IOException { // 缓冲区中是否有数据 if (count == 0) { // 从文件中读取数据到缓冲区,返回值读取的字符数 count = r.read(arr); index = 0; // 下标为0 } if (count < 0) // 文件末尾 return -1; // 从缓冲区中读取一个字符 int num = arr[index]; index++;// 下标+1 // 数量-1 count--; return num; } // 一次读取一行 public String myReadLine() throws IOException { StringBuilder sb = new StringBuilder(); int num; while ((num = myRead()) != -1) { if (num == '\r') continue; else if (num == '\n') return sb.toString(); else sb.append((char) num); } return null; } // 关闭流 public void myClose() throws IOException { r.close(); } } class MyLineNumberReader extends MyBufferedReader { private int lineNumber; public MyLineNumberReader(Reader r) { super(r); } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } public int getLineNumber() { return this.lineNumber; } // 每次读取一行,行号+1 public String MyReadLine() throws IOException { ++lineNumber; return super.myReadLine(); } }
未完,待续。
相关文章推荐
- 【HTML】常用跨域技术
- POJ 3130 How I Mathematician Wonder What You Are!(半平面交求多边形的核)
- HDU1231 最大连续子序列
- 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。
- 通过gdb快速定位“段错误”的位置
- zxing实现二维码解析和生成
- QQ空间留言的JS
- 【转】关于微信开发者平台移动应用获取签名解决问题
- 测试你是否和LTC水平一样高 1407 (简单数学题)
- 超轻量级的安卓SlidingMenu库
- linux操作系统中的文件目录结构详细介绍
- Docker 根本不适合用于本地开发环境
- MATLAB中find函数用法
- The Suspects 并查集
- posix线程栈
- 判断浏览器是否安装pdf插件
- Android JNI的动态注册
- 终于拿到了软件开发的第一桶金
- ViewPager+可缩放ImageView的使用
- TCP粘包,UDP不存在粘包问题