Component(被装饰对象基类)
定义对象的接口,可以给这些对象动态增加职责;
ConcreteComponent(具体被装饰对象)
定义具体的对象,Decorator可以给它增加额外的职责;
Decorator(装饰者抽象类)
维护指向Component实例的引用,定义与Component一致的接口;
ConcreteDecorator(具体装饰者)
具体的装饰对象,给内部持有的具体被装饰对象增加具体的
装饰者模式小结:
OO原则:动态地将责任附加到对象上。
想要扩展功能,装饰者提供有别于继承的另一种选择。
要点:
1、继承属于扩展形式之一,但不见得是达到弹性设计的最佳方案。
2、在我们的设计中,应该允许行为可以被扩展,而不须修改现有的代码。
3、组合和委托可用于在运行时动态地加上新的行为。
4、除了继承,装饰者模式也可以让我们扩展行为。
5、装饰者模式意味着一群装饰者类,这些类用来包装具体组件。
6、装饰者类反映出被装饰的组件类型(实际上,他们具有相同的类型,
都经过接口或继承实现)。
7、装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,
甚至将被装饰者的行为整个取代掉,而达到特定的目的。
8、你可以有无数个装饰者包装一个组件。
9、装饰者一般对组建的客户是透明的,除非客户程序依赖于组件的具体类型。
十三、常见编码格式
1、iso-8859-1:单字节的编码格式,一般用于英文0-255之间
2、GBK/GB2312:中文国际编码,以双字节的编码格式,GBK 比 GB2312字符集更大
3、unicode:java的默认编码,以双字节的编码格式,不兼容iso-8859-1,单字节也
用双字节来表示。浪费存储空间。
4、UTF-8:以不定长(1-6)字节的编码格式,可以表示国际上的所有文字,更有利于存储空间的合理利用。
通常情况下,在程序造成乱码的:
(1)程序编码与本机编码不一致
(2)客户端程序与服务器程序的编码不一致
转换编码的方式:
比如把一个iso-8859-1编码的字符串转成 GBK 编码
String s = new String(data.getBytes("iso-8859-1"),"GBK");
补充作业:
1、使用装饰者模式:以游戏人物角色为背景,人物的等级技能,添加附加的技能。
2、找一个大文件(100M),实现文件的分割,合并
十四、NIO
NIO:New IO,从 JDK1.4加入,目的为了提高 IO 流的读取和写入效率
处理的数据格式是:块
NIO中提供的缓冲区(数组)
ByteBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer
CharBuffer
ShortBuffer
缓冲区的三个重要变量:
position:位置
limit:限制
capacity:容量
创建缓冲区,并分配缓冲区大小
//字节缓冲区
ByteBuffer buf = ByteBuffer.allocate(10);
示例1:
/**
* 使用NIO复制文件
* @throws IOException
*/
private static void copy() throws IOException{
long start = System.currentTimeMillis();
//创建一个文件通道,该通道指向一个目标文件
FileChannel fcIn = new FileInputStream("c:\\3D0.jpg")
.getChannel();
FileChannel fcOut = new FileOutputStream("c:\\liyan.jpg")
.getChannel();
//[10,20,30,40,50,60,70,80,90]
ByteBuffer buf = ByteBuffer.allocate(1024);
int i=1;
while(fcIn.read(buf)!=-1){
System.out.println(i++);
buf.flip();//反转缓冲区
fcOut.write(buf);
buf.clear();//还原缓冲区的状态
}
fcIn.close();
fcOut.close();
System.out.println("copy success");
long end = System.currentTimeMillis();
System.out.println("耗时(毫秒):"+(end-start));
}
示例2:
/**
* 使用内存映射复制文件
*/
private static void randomAccessFileCopy(){
try {
//创建指向目标文件的RandomAccessFile
RandomAccessFile in = new RandomAccessFile(
new File("c:\\3D0.jpg"),"r");
RandomAccessFile out = new RandomAccessFile(
new File("c:\\36D_liyan.jpg"),"rw");
//获取通道
FileChannel fcIn = in.getChannel();
FileChannel fcOut = out.getChannel();
//映射内存缓冲区
long size = fcIn.size();
MappedByteBuffer inBuf =
fcIn.map(MapMode.READ_ONLY, 0,size );
MappedByteBuffer outBuf =
fcOut.map(MapMode.READ_WRITE, 0,size);
//从源文件的缓冲区中把数据放到目标文件的缓冲区
for(int i=0;i<size;i++){
outBuf.put(inBuf.get());
}
//关闭(同时写入数据块)
fcIn.close();
fcOut.close();
in.close();
out.close();
System.out.println("copy success");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
文件操作的性能比较:
速度最快的方式:使用内存映射