您的位置:首页 > 其它

设计模式4:装饰模式(1)

2015-09-12 21:07 302 查看
  作用:

  基于已经存在的功能提供增强功能。

  将扩展的类作为新的类的构造函数参数传入,然后对这个类进行装饰处理。

  为了让装饰者有被装饰的功能,需要存在继承关系。

  简单的点讲就是为了扩展一个已定义好的类的功能,而不修改原来类的定义,原来的类仍然可以继续使用,现在定义一个新的类继承原来的类,同时在这个新的类中定义父类的成员变量,同时在构造方法中将外界的一个父类对象传给这个成员变量,然后既可以通过这个成员变量使用父类的方法,同时又可以增加新的方法实现对父类功能的扩充。例如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();
}

}


  

  未完,待续。

  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: