java设计模式_装饰者模式
2021/4/17 14:26:57
本文主要是介绍java设计模式_装饰者模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1 概述
装饰者模式的目的是给类的弄能增强。
继承也能给类的功能增强。
2 举例说明(便于观察和理解装饰模式)
Writer类是写文件的类,有三个子类,TxtWriter,MP3Writer,AVIWriter
在writer中定义了写文件的标准,三个子类分别去实现Writer中的写方法
使用继承方式来对类增强
Writer
|-----TxtWriter
|-----MP3Writer
|-----AVIWriter
如果写文件的缓冲区是同样的原理,那么我们就可以把缓冲区抽取出来作为装饰器。
三个普通类
AviWriter.java
package cn.tx.demo; public class AviWriter { public void write() { System.out.println("写avi文件完成"); } }
Mp3Writer.java
package cn.tx.demo; public class Mp3Writer { public void write() { System.out.println("写mp3文件完成"); } }
TxtWriter.java
package cn.tx.demo; public class TxtWriter { public void write() { System.out.println("写txt文件完成"); } }
需求,比如想给TxtWriter,MP3Writer,AVIWriter类的write的方法进行加强,给这三个write方法加一个缓冲的步骤。
2.1 方式一:继承
创建一个Writer类
Writer.java
package cn.tx.demo; public class Writer { public void buffer() { System.out.println("助力的高效缓冲"); } }
让每一个类都继承这个Writer类后
AviWriter.java
package cn.tx.demo; public class AviWriter extends Writer{ public void write() { buffer(); System.out.println("写avi文件完成"); } }
Mp3Writer.java
package cn.tx.demo; public class Mp3Writer extends Writer{ public void write() { buffer(); System.out.println("写mp3文件完成"); } }
TxtWriter.java
package cn.tx.demo; public class TxtWriter extends Writer{ public void write() { buffer(); System.out.println("写txt文件完成"); } }
Test.java
package cn.tx.demo; public class Test { public static void main(String[] args) { TxtWriter tw = new TxtWriter(); tw.write(); } }
输出结果为:
助力的高效缓冲
写txt文件完成
结论:这种继承的方式需要改变每个类中的方法,对类中的方法有了侵略性。而我们想在不改变原有的东西的基础上,加强这个功能。
2.2 方式二:装饰者模式
角色:
1.抽象角色(定义写文件标准):Writer
2.具体的角色(实现写文件标准):三个子类TxtWriter,MP3Writer,AVIWriter
3.装饰角色[抽象](高效缓冲区):注意:也可以定义成抽象的,如果是抽象的就必须要有具体抽象角色
4.具体的装饰角色:来实现抽象装饰器中的增强方法。
代码实现:
目录结构
Writer.java
package cn.tx.demo; public abstract class Writer { public abstract void write() ; }
AviWriter.java
package cn.tx.demo; public class AviWriter extends Writer{ public void write() { System.out.println("写avi文件完成"); } }
TxtWriter.java
package cn.tx.demo; public class TxtWriter extends Writer{ public void write() { System.out.println("写txt文件完成"); } }
Mp3Writer.java
package cn.tx.demo; public class Mp3Writer extends Writer{ public void write() { System.out.println("写mp3文件完成"); } }
BufferTxWriter.java
package cn.tx.demo; public class BufferTxWriter extends Writer{ //定义一个Writer属性 Writer writer; public BufferTxWriter(Writer writer) { this.writer = writer; } @Override public void write() { //先来调用装饰方法 buffer(); //调用实际的写方法 writer.write(); } /* * 装饰方法 */ public void buffer() { System.out.println("加上高效的缓冲"); } }
Test.java
package cn.tx.demo; public class Test { public static void main(String[] args) { Writer writer = new BufferTxWriter(new AviWriter()); writer.write(); System.out.println("--------------------------------"); writer = new BufferTxWriter(new TxtWriter()); writer.write(); System.out.println("--------------------------------"); writer = new BufferTxWriter(new Mp3Writer()); writer.write(); } }
输出结果为:
加上高效的缓冲
写avi文件完成
--------------------------------
加上高效的缓冲
写txt文件完成
--------------------------------
加上高效的缓冲
写mp3文件完成
3 案例 23:00
3.1 案例需求
拷贝图片,拷贝文本......,在这个基础之上,加上一个拷贝文件的时候加上日志记录,考一个记一个,要求自动完成,不能手动完成。用装饰模式。
需要拷贝的文件:
拷贝到工程下的txfile文件夹下
实现代码:
Copy.java
package cn.tx.demoeg; public abstract class Copy { public abstract void copy(String fileName) throws Exception; }
BinCopy.java
package cn.tx.demoeg; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class BinCopy extends Copy{ @Override public void copy(String fileName) throws Exception { FileInputStream in = new FileInputStream("d:\\res\\"+fileName); FileOutputStream out = new FileOutputStream("txfile\\"+fileName); byte[] bs = new byte[1024]; while(in.read(bs) != -1) { out.write(bs); } out.close(); in.close(); } }
TxtCopy.java
package cn.tx.demoeg; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; public class TxtCopy extends Copy{ @Override public void copy(String fileName) throws Exception { BufferedReader br = new BufferedReader(new FileReader("d:\\res\\"+fileName)); PrintWriter pw = new PrintWriter("txfile\\"+fileName); String line = null; while((line = br.readLine()) != null){ pw.print(line); } pw.close(); br.close(); } }
LogCopy.java
package cn.tx.demoeg; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class LogCopy extends Copy{ private Copy copy; public LogCopy(Copy copy) { super(); this.copy = copy; } @Override public void copy(String fileName) throws Exception { copy.copy(fileName); log(fileName); } /* * 把拷贝的文件的记录都记在record.log里面 */ public void log(String fileName) throws IOException { //创建文件输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("record.log",true)); String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+ "--拷贝了文件--" +fileName; bw.write(str); bw.newLine(); bw.flush(); bw.close(); } }
Test.java
package cn.tx.demoeg; public class Test { public static void main(String[] args) throws Exception { LogCopy logCopy = new LogCopy(new BinCopy()); logCopy.copy("rz.jpg"); logCopy = new LogCopy(new TxtCopy()); logCopy.copy("test.txt"); } }
输出结果:
record.log
2021-04-17 12:36:59--拷贝了文件--rz.jpg 2021-04-17 12:38:34--拷贝了文件--rz.jpg 2021-04-17 12:38:34--拷贝了文件--test.txt
后续如果再想追加拷贝别的东西的方法,直接在新类Xxx.java中写自己拷贝的功能就行了,然后直接继承一下Copy类。
使用的时候还是和别的一样用,就带有日志记录功能。
试验:
在Test类中用
logCopy = new LogCopy(new Xxx());
logCopy.copy("要拷贝的文件名");
结果一样是可以在record.log中写下日志。
这篇关于java设计模式_装饰者模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)