装饰者模式是对已有的类型进行扩展
作用:对一个进行扩展升级,扩展是在原代码执行的基础之上加一些扩展代码
要求:装饰者模式要求:装饰者和被装饰应该实现同一个类型
1.需求:想要将一个类里面的方法进行扩展升级,结合之前的知识会让这个类成为另外一个类的父类,即使用继承,在子类中区重写此方法,但是这样形成了继承关系,耦合度太高。所以引入了装饰者模式
package test;
//1.装饰者模式中要求:装饰者中含有装饰者的引用
//装饰者类
public class BufferedReaderTest { // BufferedReaderTest
//关联关系
FileReaderTest reader; //被装饰者
//构造方法
BufferedReaderTest(FileReaderTest reader){
this.reader = reader;
}
public void m1() {
System.out.println("扩展代码");
reader.close();
}
}
//被装饰者类
public class FileReaderTest {
public void close() {
System.out.println("被装饰者方法");
}
}
//测试程序
public class Test {
public static void main(String[] args) {
BufferedReaderTest brt = new BufferedReaderTest(new FileReaderTest());
brt.close(); //可以观察到,调用了装饰者的close方法,在该方法里面,被装饰者的close方法也调用了
}
}
装饰者模式要求:装饰者和被装饰应该实现同一个类(或接口)
再来重写以上程序
//定义一个抽象类,让装饰者与被装饰者都去实现它
public abstract class Reader {
abstract void close();
}
//被装饰者方法
public class FileReaderTest extends Reader {
public void close() {
System.out.println("被装饰者方法");
}
}
public class BufferedReaderTest extends Reader { // BufferedReaderTest
//关联关系
Reader reader; //被装饰者
//构造方法
BufferedReaderTest( reader){
this.reader = reader;
}
public void close() {
System.out.println("扩展代码");
reader.close();
}
}
测试
public class Test {
public static void main(String[] args) {
BufferedReaderTest brt = new BufferedReaderTest(new FileReaderTest());
brt.close();
}
}
DataInputStream DataoutputStream
java.io.OutputStream
java.io.FilterOutputStream
java.io.DataOutputStream 数据字节输出流
用法:可以将内存中的"int i = 10;" 写入硬盘,写进去的不是字符串,写进去的是二进制数据 ,带类型
public class DataOutputStreamTest {
public static void main(String[] args) throws Exception {
//创建数据字节输出流
DataOutputStream dos = new DataOutputStream(new FileOutputStream("f:\\temp2")); //查看API文档,构造方法内部需要传入一个OutputStream(抽象类),它的子类FileOutputStream
//准备数据
byte b = 10;
int s = 3548;
boolean b2 = true;
long b3 = 120555454;
double b4 = 12.45;
//写
dos.writeByte(b);
dos.writeInt(s);
dos.writeBoolean(b2);
dos.writeLong(b3);
dos.writeDouble(b4);
dos.writeChars("用户名");
//写入后为二进制文件,带着类型,看不懂
//刷新
dos.flush();
//关闭
dos.close();
//创建数据字节输入流
DataInputStream dis = new DataInputStream((new FileInputStream("f:\\temp2")));
System.out.println(dis.readByte());
System.out.println(dis.readInt());
System.out.println(dis.readBoolean());
System.out.println(dis.readLong());
System.out.println(dis.readDouble());
System.out.println(dis.readChar());
System.out.println(dis.readChar());
System.out.println(dis.readChar());
//读
//注意:要使用该流读取数据,必须先要知道文件的存储格式,按照什么顺序写进去,就要按什么顺序读出来
dis.close();
}
}
PrintStream PrintWriter
java.io.PrintStream; 标准的输出流,默认打印到控制台.以字节方式
java.io.PrintWriter; 以字符方式
注意可以转移输出,进而可以打印日志
package printStream;
import java.io.*;
import java.text.*;
import java.util.*;
public class PrintStreamTest {
public static void main(String[] args) throws Exception {
//传统方式
System.out.println("sdsd");
SimpleDateFormat ds = new SimpleDateFormat("y年M月d日 H:m:sss SSSS");
m1();
//新方式,但是需要到io包
PrintStream ps = System.out; //(System.out返回的是一个PrintStream类型)
ps.println("sdsd");
//可以改变输出方向。 System下的静态方法 setOut(PrintStream out)
System.setOut(new PrintStream(new FileOutputStream("f://log")));
//这种方法也可以
/* System.setOut(new PrintStream("f://log")); */
//需求,记录m1方法开始执行的时间和执行结束的时间,放入日志
//这样在输出,就不再默认输出到控制台,而是输出到log下
Date d1 = new Date();
System.out.println("m1方法开始执行:"+ds.format(d1));
m1();
Date d2 = new Date();
System.out.println("m1方执行结束:"+ds.format(d2));
/*通常使用以上的方法来记录日志*/
}
public static void m1() {
System.out.println("m1测试方法");
}
}