首页 » 软件开发 » 设计模式——装饰器模式(装饰设计模式)详解(装饰模式构件角色子类)

设计模式——装饰器模式(装饰设计模式)详解(装饰模式构件角色子类)

少女玫瑰心 2024-07-24 22:36:31 0

扫一扫用手机浏览

文章目录 [+]

装饰器模式的主要优点有:

装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果装饰器模式完全遵守开闭原则

其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

装饰器模式的结构与实现

通常情况下,扩展一个类的功能会使用继承方式来实现。
但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。
如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰器模式的目标。
下面来分析其基本结构和实现方法。

设计模式——装饰器模式(装饰设计模式)详解(装饰模式构件角色子类) 软件开发
(图片来自网络侵删)
1. 模式的结构

装饰器模式主要包含以下角色。

抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

装饰器模式的结构图如图 1 所示。

图1 装饰器模式的结构图

2. 模式的实现

装饰器模式的实现代码如下:

package decorator;public class DecoratorPattern { public static void main(String[] args) { Component p = new ConcreteComponent(); p.operation(); System.out.println("---------------------------------"); Component d = new ConcreteDecorator(p); d.operation(); }}//抽象构件角色interface Component { public void operation();}//具体构件角色class ConcreteComponent implements Component { public ConcreteComponent() { System.out.println("创建具体构件角色"); } public void operation() { System.out.println("调用具体构件角色的方法operation()"); }}//抽象装饰角色class Decorator implements Component { private Component component; public Decorator(Component component) { this.component = component; } public void operation() { component.operation(); }}//具体装饰角色class ConcreteDecorator extends Decorator { public ConcreteDecorator(Component component) { super(component); } public void operation() { super.operation(); addedFunction(); } public void addedFunction() { System.out.println("为具体构件角色增加额外的功能addedFunction()"); }}

程序运行结果如下:

创建具体构件角色调用具体构件角色的方法operation()---------------------------------调用具体构件角色的方法operation()为具体构件角色增加额外的功能addedFunction()装饰器模式的应用实例

【例1】用装饰器模式实现游戏角色“莫莉卡·安斯兰”的变身。

分析:在《恶魔战士》中,游戏角色“莫莉卡·安斯兰”的原身是一个可爱少女,但当她变身时,会变成头顶及背部延伸出蝙蝠状飞翼的女妖,当然她还可以变为穿着漂亮外衣的少女。
这些都可用装饰器模式来实现,在本实例中的“莫莉卡”原身有 setImage(String t) 方法决定其显示方式,而其 变身“蝙蝠状女妖”和“着装少女”可以用 setChanger() 方法来改变其外观,原身与变身后的效果用 display() 方法来显示,图 2 所示是其结构图。

图2 游戏角色“莫莉卡·安斯兰”的结构图

程序代码如下:

package decorator;import java.awt.;import javax.swing.;public class MorriganAensland { public static void main(String[] args) { Morrigan m0 = new original(); m0.display(); Morrigan m1 = new Succubus(m0); m1.display(); Morrigan m2 = new Girl(m0); m2.display(); }}//抽象构件角色:莫莉卡interface Morrigan { public void display();}//具体构件角色:原身class original extends JFrame implements Morrigan { private static final long serialVersionUID = 1L; private String t = "Morrigan0.jpg"; public original() { super("《恶魔战士》中的莫莉卡·安斯兰"); } public void setImage(String t) { this.t = t; } public void display() { this.setLayout(new FlowLayout()); JLabel l1 = new JLabel(new ImageIcon("src/decorator/" + t)); this.add(l1); this.pack(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); }}//抽象装饰角色:变形class Changer implements Morrigan { Morrigan m; public Changer(Morrigan m) { this.m = m; } public void display() { m.display(); }}//具体装饰角色:女妖class Succubus extends Changer { public Succubus(Morrigan m) { super(m); } public void display() { setChanger(); super.display(); } public void setChanger() { ((original) super.m).setImage("Morrigan1.jpg"); }}//具体装饰角色:少女class Girl extends Changer { public Girl(Morrigan m) { super(m); } public void display() { setChanger(); super.display(); } public void setChanger() { ((original) super.m).setImage("Morrigan2.jpg"); }}

程序运行结果如图 3 所示。

图3 游戏角色“莫莉卡·安斯兰”的变身

装饰器模式的应用场景

前面讲解了关于装饰器模式的结构与特点,下面介绍其适用的应用场景,装饰器模式通常在以下几种情况使用。

当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。
例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
当对象的功能要求可以动态地添加,也可以再动态地撤销时。

装饰器模式在 Java 语言中的最著名的应用莫过于 Java I/O 标准库的设计了。
例如,InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。

下面代码是为 FileReader 增加缓冲区而采用的装饰类 BufferedReader 的例子:

BufferedReader in = new BufferedReader(new FileReader("filename.txt"));String s = in.readLine();装饰器模式的扩展

装饰器模式所包含的 4 个角色不是任何时候都要存在的,在有些应用环境下模式是可以简化的,如以下两种情况。

(1) 如果只有一个具体构件而没有抽象构件时,可以让抽象装饰继承具体构件,其结构图如图 4 所示。

图4 只有一个具体构件的装饰器模式

(2) 如果只有一个具体装饰时,可以将抽象装饰和具体装饰合并,其结构图如图 5 所示。

图5 只有一个具体装饰的装饰器模式

标签:

相关文章

语言中的借用,文化交融的桥梁

自古以来,人类社会的交流与发展离不开语言的传播。在漫长的历史长河中,各民族、各地区之间的文化相互碰撞、交融,产生了许多独特的语言现...

软件开发 2025-01-01 阅读1 评论0

机顶盒协议,守护数字生活的新卫士

随着科技的飞速发展,数字家庭逐渐走进千家万户。在这个时代,机顶盒成为了连接我们与丰富多彩的数字世界的重要桥梁。而机顶盒协议,作为保...

软件开发 2025-01-01 阅读1 评论0

语言基础在现代社会的重要性及方法步骤

语言是人类沟通的桥梁,是社会发展的基础。语言基础作为语言学习的基石,对于个人、社会乃至国家的发展具有重要意义。本文将从语言基础在现...

软件开发 2025-01-01 阅读2 评论0

粤语电影,传承文化,点亮时代之光

粤语电影,作为中国电影产业的一朵奇葩,以其独特的地域特色、丰富的文化内涵和鲜明的艺术风格,赢得了广大观众的喜爱。本文将从粤语电影的...

软件开发 2025-01-01 阅读3 评论0

苹果游戏语言,塑造未来娱乐体验的基石

随着科技的飞速发展,游戏产业逐渐成为全球娱乐市场的重要支柱。在我国,游戏产业更是蓬勃发展,吸引了无数玩家和投资者的目光。而在这其中...

软件开发 2025-01-01 阅读1 评论0