Java 设计模式之装饰模式,Java 装饰模式,java装饰模式和代理模式的区别
Java 设计模式之装饰模式,Java 装饰模式
java装饰模式和代理模式的区别
================================
©Copyright 蕃薯耀 2021-07-01
https://www.cnblogs.com/fanshuyao/
一、Java 装饰模式
1、接口(Component,抽象构件)
public interface FastFood { /** * 花费金额 * @return */ public double cost(); /** * 描述 * @return */ public String desc(); }
2、具体的实现类(ConcreteComponent,具体构件,或者基础构件)
/** * 炒饭,具体的类 * */ public class FriedRice implements FastFood{ @Override public double cost() { return 10; } @Override public String desc() { return "炒饭"; } }
3、装饰抽象类(Decorator,装饰角色)
/** * 配菜抽象类 * */ public abstract class SideDish implements FastFood{ //快餐类 private FastFood fastFood; public SideDish(FastFood fastFood) { this.fastFood = fastFood; } @Override public double cost() { return fastFood.cost(); } @Override public String desc() { return fastFood.desc(); } }
4、装饰类子类(ConcreteDecorator,具体装饰角色)
public class SideDishEgg extends SideDish { public SideDishEgg(FastFood fastFood) { super(fastFood); } @Override public double cost() { return 1 + super.cost(); } @Override public String desc() { return "鸡蛋" + " + " + super.desc(); } }
5、装饰类子类2(ConcreteDecorator,具体装饰角色)
public class SideDishPork extends SideDish { public SideDishPork(FastFood fastFood) { super(fastFood); } @Override public double cost() { return 2 + super.cost(); } @Override public String desc() { return "猪肉" + " + " + super.desc(); } }
6、测试结果
public class Client { public static void main(String[] args) { FastFood fastFood = new FriedRice(); System.out.println(fastFood.desc()); System.out.println(fastFood.cost()); System.out.println("--------------------------------------------------"); FastFood fastFoodEgg = new SideDishEgg(fastFood); System.out.println(fastFoodEgg.desc()); System.out.println(fastFoodEgg.cost()); System.out.println("--------------------------------------------------"); FastFood fastFoodEgg2 = new SideDishEgg(fastFoodEgg); System.out.println(fastFoodEgg2.desc()); System.out.println(fastFoodEgg2.cost()); System.out.println("--------------------------------------------------"); FastFood fastFoodEgg3 = new SideDishPork(fastFoodEgg2); System.out.println(fastFoodEgg3.desc()); System.out.println(fastFoodEgg3.cost()); } }
炒饭 10.0 -------------------------------------------------- 鸡蛋 + 炒饭 11.0 -------------------------------------------------- 鸡蛋 + 鸡蛋 + 炒饭 12.0 -------------------------------------------------- 猪肉 + 鸡蛋 + 鸡蛋 + 炒饭 14.0
二、Java 装饰器模式在Java I/O的实现
InputStream作为抽象构件,其有如下几种具体基础构件
字节数据:ByteArrayInputStream
文件流;FileInputStream
字符缓冲流;StringBufferInputStream
FilterInputStream作为装饰器在JDK中是一个普通类,其下面有多个具体装饰器:
BufferedInputStream、DataInputStream。
以BufferedInputStream为例,使用它就是避免每次读取时都进行实际的写操作,起着缓冲作用,加快读写操作。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class Stream4FileStreamBufferStream { /** * 普通文件流 * @throws IOException */ public static void fileInputStream() throws IOException { long start = System.currentTimeMillis(); InputStream is = new FileInputStream("c:/img/00.mp4"); OutputStream os = new FileOutputStream("c:/img/11.mp4"); byte[] buffer = new byte[1024]; int length; while((length = is.read(buffer)) != -1) { os.write(buffer, 0, length); } os.close(); is.close(); long end = System.currentTimeMillis(); //消耗时间: //小文件(210M)时间:1407 1230 1405 //大文件(1.7G)时间:37001 24138 System.out.println("end - start=" + (end - start)); System.out.println("执行完成。"); } /** * 使用缓冲流 * @throws IOException */ public static void fileInputStreamBuffer() throws IOException { long start = System.currentTimeMillis(); InputStream is = new FileInputStream("c:/img/00.mp4"); OutputStream os = new FileOutputStream("c:/img/22.mp4"); //缓冲流,加快文件输入输出 BufferedInputStream bufferedInputStream = new BufferedInputStream(is);//DEFAULT_BUFFER_SIZE = 8192 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(os); byte[] buffer = new byte[1024]; int length; while((length = bufferedInputStream.read(buffer)) != -1) { bufferedOutputStream.write(buffer, 0, length); } bufferedOutputStream.close(); bufferedInputStream.close(); os.close(); is.close(); long end = System.currentTimeMillis(); //消耗时间: //小文件(210M)时间:368 330 396 //大文件(1.7G)时间:32049 32378 System.out.println("end - start=" + (end - start)); System.out.println("执行完成。"); } public static void main(String[] args) throws IOException { fileInputStream(); //fileInputStreamBuffer(); } }
【Java 输入输出流,Java InputStream FileInputStream OutputStream FileOutputStream】使用见:
https://www.cnblogs.com/fanshuyao/p/14679868.html
三、Java 设计模式之代理模式,Java 静态代理,Java 动态代理
https://www.cnblogs.com/fanshuyao/p/14911666.html
四、java装饰模式和代理模式的区别
代理模式:
侧重于不能直接访问一个对象,只能通过代理来间接访问,起到保存对象的作用。
装饰器模式:
是因为没法在编译器就确定一个对象的功能,需要运行时动态的给对象添加职责,所以只能把对象的功能拆成一个个的小部分,动态组装。
装饰模式可以装了又装,层层包裹; 代理一般不会代了又代。
五、java装饰模式的优点和缺点
装饰模式的优点:
解决过多子类问题,解决多组合的情况下子类过多的问题
装饰模式的缺点:
多层的装饰会导致业务逻辑复杂,不利于理解
(时间宝贵,分享不易,捐赠回馈,^_^)
================================
©Copyright 蕃薯耀 2021-07-01
https://www.cnblogs.com/fanshuyao/