你好,这里是codetrend专栏“跟着GPT学设计模式”。
装饰者模式是一种结构型设计模式,它允许你在不修改已有对象的情况下,动态地向对象添加额外的功能。装饰者模式通过包装原始对象来扩展其功能,并提供了一种灵活的方式来组合多个装饰器。装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。
使用mermaid绘制的桥接模式类图如下:
classDiagram
class Component {
+operation(): void
}
class ConcreteComponent {
+operation(): void
}
class Decorator {
-component: Component
+operation(): void
}
class ConcreteDecoratorA {
+operation(): void
+addedBehavior(): void
}
class ConcreteDecoratorB {
+operation(): void
+addedState: string
}
Component <|-- ConcreteComponent
Component <|.. Decorator
Decorator <|-- ConcreteDecoratorA
Decorator <|-- ConcreteDecoratorB
该示意图中展示了一个简单的装饰者模式示例,其中 ConcreteComponent 是被装饰的对象,而 Decorator 和 ConcreteDecorator 是用于装饰该对象的装饰者。
装饰者模式的工作流程如下:
使用装饰者模式的好处是,它允许你动态地向对象添加功能,而无需修改已有代码。它遵循开闭原则,使得系统更灵活且易于扩展。此外,装饰者模式通过组合多个装饰器,可以实现各种不同的组合效果。
项目中使用装饰者模式的例子是 Java IO 库中的输入输出流(InputStream 和 OutputStream)。
在 Java IO 中,InputStream 和 OutputStream 是抽象组件,它们定义了读取和写入数据的基本接口。而具体组件则是实现了这些接口的类,例如 FileInputStream 和 FileOutputStream。
使用装饰者模式时,我们可以创建一个抽象装饰者类 FilterInputStream(继承自 InputStream),它持有一个被包装的 InputStream 对象,并通过调用父类的方法来扩展原始行为。
Java IO 中有许多具体装饰者类,例如 BufferedInputStream(用于提供缓冲读取功能)和 DataInputStream(用于读取不同类型的数据)。这些具体装饰者类继承自 FilterInputStream,通过调用父类的方法来扩展原始的读取行为,并在需要时添加额外的功能。
下面是一个简化的示例代码:
// 抽象组件
public abstract class InputStream {
public abstract int read();
}
// 具体组件
public class FileInputStream extends InputStream {
public int read() {
// 实现读取文件的逻辑
}
}
// 抽象装饰者
public abstract class FilterInputStream extends InputStream {
protected InputStream inputStream;
public FilterInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public int read() {
// 调用被装饰的 InputStream 对象的 read() 方法
return inputStream.read();
}
}
// 具体装饰者
public class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream inputStream) {
super(inputStream);
}
public int read() {
// 在调用父类的 read() 方法前后添加额外的缓冲读取功能
// ...
return super.read();
}
}
// 举例
public class FileToTextConverter {
public static void main(String[] args) {
String filePath = "path/to/your/file.txt"; // 替换为实际的文件路径
try (FileInputStream fis = new FileInputStream(filePath);
BufferedInputStream bis = new BufferedInputStream(fis)) {
StringBuilder sb = new StringBuilder(); // 使用 StringBuilder 储存文本内容
byte[] buffer = new byte[8192]; // 使用缓冲区进行读取,这里设置为 8KB
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
sb.append(new String(buffer, 0, bytesRead));
}
String text = sb.toString(); // 将 StringBuilder 转换为字符串
System.out.println(text); // 打印文件内容
} catch (IOException e) {
e.printStackTrace();
}
}
}
步骤1:创建抽象组件(Component)
public interface Beverage {
String getDescription();
double getCost();
}
步骤2:创建具体组件(ConcreteComponent)
public class Espresso implements Beverage {
public String getDescription() {
return "Espresso";
}
public double getCost() {
return 1.99;
}
}
步骤3:创建抽象装饰者(Decorator)
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
public abstract String getDescription();
public abstract double getCost();
}
步骤4:创建具体装饰者(ConcreteDecorator)
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
super(beverage);
}
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
public double getCost() {
return beverage.getCost() + 0.5;
}
}
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
super(beverage);
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double getCost() {
return beverage.getCost() + 0.3;
}
}
步骤5:使用装饰者模式
public class App {
public static void main(String[] args) {
// 创建一个具体组件对象
Beverage espresso = new Espresso();
// 使用装饰者对具体组件进行包装
Beverage milkEspresso = new Milk(espresso);
Beverage mochaMilkEspresso = new Mocha(milkEspresso);
// 进行操作,输出描述和总价格
System.out.println(mochaMilkEspresso.getDescription());
System.out.println("Cost: $" + mochaMilkEspresso.getCost());
}
}
输出结果:
Espresso, Milk, Mocha
Cost: $2.79
在上述示例中,我们创建了一个咖啡饮料的例子。Beverage 是抽象组件,Espresso 是具体组件;CondimentDecorator 是抽象装饰者,Milk 和 Mocha 是具体装饰者。通过装饰者模式,我们可以给具体组件添加额外的装饰来扩展其功能。
在 Main 类中,我们创建了一个 Espresso 的实例,并使用 Milk 和 Mocha 装饰它,最后输出了装饰后的描述和总价格。
以上内容基于GPT创建和整理。
来自一线全栈程序员nine的探索与实践,持续迭代中。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。