装饰模式 – 半透明装饰模式:
目录
在装饰模式的学习中,会出现一个透明装饰模式和半透明的装饰,是什么意思呢?
透明装饰模式
在透明装饰模式中要求客户端完全针对抽象编程,装饰模式的透明性要求客户端程序不应该将对象声明为具体构件类型或具体装饰类型,而应该全部声明为抽象构件类型。对客户端而言,具体构件类和具体装饰类对象没有任何区别。(缺点,无法单独调用装饰类的独有功能)
比如在例子中:都是用 ShapeDecorator 去声明要装饰的内容
半透明装饰模式
用具体装饰类型来定义装饰后的对象,而具体构件类型仍然可以使用抽象构件类型来定义,可以单独调用装饰的独有方法。(缺点:无法多次进行装饰)
是否透明,是根据装饰的对象是否根据抽象对象来定义去判断的。 半透明是运用具体的装饰类来声明,而非抽象类去声明。
I/O 应用
装饰模式在Java语言中的最典型的应用是Java I/O标准库的设计
由于Java I/O库需要很多性能的各种组合,如果这些性能都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量性能重复的类出现。而如果采用装饰模式,那么类的数目就会大大减少,性能的重复也可以减至最少。因此装饰模式是Java I/O库的基本模式。
Java I/O库的对象结构图如下,由于Java I/O的对象众多,因此只显示InputStream部分的内容。
根据上图可以看出:
● 抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。
● 具体构件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、ObjectInputStream, FilterInputStream等类扮演。它们实现了抽象构件角色所规定的接口。
源码:
输入流 InputStream
public abstract class InputStream implements Closeable {
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
public abstract int read() throws IOException;
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
public long skip(long n) throws IOException {
long remaining = n;
int nr;
if (n <= 0) {
return 0;
}
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte[] skipBuffer = new byte[size];
while (remaining > 0) {
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
if (nr < 0) {
break;
}
remaining -= nr;
}
return n - remaining;
}
public int available() throws IOException {
return 0;
}
public void close() throws IOException {}
public synchronized void mark(int readlimit) {}
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
public boolean markSupported() {
return false;
}
}
看 FileInputStream 的源码,添加了自己的一些方法,这意味着,其变成了半透明的装饰类
应用:
读取txt文件:
public class ReadTxtTest {
public static void main(String[] args) throws IOException {
String filePath="E:/yan.txt";
// 流式读取文件
DataInputStream dis = null;
try{
dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(filePath)
)
);
//读取文件内容
byte[] bs = new byte[dis.available()];
dis.read(bs);
String content = new String(bs);
System.out.println(content);
}catch (Exception e){
e.getMessage();
}finally{
dis.close();
}
}
}
结果:
岁月因温良而静好,时光因唯美而温馨。生命,因有你而丰盈,尘世,因你我执手而深情。若你回眸,菩提花开,何须繁华,何须盛装,你就是那抹最亮的光华,照亮我这一世前行的方向。
人生,有春也有秋,有暖自有寒,心灵的恬淡,缘于灵魂深处的爱。爱是所有坚持的理由,纵有千般磨难,亦是甜蜜的负担。生活里总是有太多压力,要么它把你压倒,要么你把它举起。爱是力量,也是希望,更是经年所有坚守的信念。爱,不必等待,因为生命的每一天都在悄无声息的流逝,轻盈而安静。爱,不必徘徊,因为它是你这一世发自内心的笃定。
poi读取excel文件
总结:
理解是否透明,主要是理解是否全使用抽象对象去声明对象。I/O操作,在工作中也常用,需要熟练使用。