Java 装饰器模式Decorator详解及实现步骤

《Java装饰器模式Decorator详解及实现步骤》装饰器模式通过组合动态扩展对象功能,避免继承导致的类爆炸,适用于运行时灵活添加职责的场景,广泛应用于JavaI/O和Spring框架,提升代码可... ...

在 Java 的www.cppcns.com世界里,设计模式是开发者手中的利器,它们帮助我们以更优雅、更灵活的方式构建软件系统。今天,我们就来深入探讨其中一种非常实用的设计模式 &mdash) : 6 _ e Y e;— 装饰器模式(U : [ i C G D mDecoratoO : .r2m l [ T S k p N * : u _ Pattern)。​

一、装x N b 5 2 A b饰器模式概X F t C Y N a述​

装饰器模式属于结构型设计模式,它允许向一个现W B q 4 S P H v有的i { ! E j n9 A m X r对象添加新的功能0 4 C 0 p ) O ],同时又\ y e R & ( j v –不改变其结构。这就好比给一个普通的杯子加上杯盖、杯套,让它具备保温、防烫等x C D \ v 4 S Y (功能,而杯子本C k c z y 4 5 kg X ; p v P身的基本结构K b e o l e @ _ 3[ E 0 G ? #并没有发生变化。在软件开发中X w 0 2 L y y v N,当我们需+ n Q S 2 ) 3 3要在运行时动态地为对象添加职责,并且避免通过继承来扩展功能带来的类层次结构复杂c 9 g n ( z K L x问题时,装饰器模式就派上用场了。​

装饰器模式主– S w g E x o d I要包含5 1 K [ i u以下几个角色:​

  1. 抽象组件(Co7 ? eI z : R . z A U T x 4 B c HmponeG e 8 a m ~ G 0nt):定义; | N\ E 6 [ &个抽象接口= ~ P 3 9 s 5 Y B,规范具体组件, v D S和装饰器的行为。​
  2. 具体组件(Concrete Com: F x 6 q $ oponent):实& 4 1 s u g _现抽象~ 0 # C a组件接口J g A I 5 Z W,是被装饰的u C ; Z具体对I L ( L? 1 ] 8 f y– Y s 7 o } ^ 3 \ 7 J :L q 4 , .
  3. 抽象] E ~ – r装饰K 6 5 @ # $ t器(Decorator):继承或实现抽S j ( * Y .象组j i/ q W 2 } 4 a 1 J i i 8件接口,持O 2 8 } X $ * Z有一个抽W e. H k * [象组_ h .件的引用,并定义一|~ 4 . j A g z c ?个可以动态添加职6 t S 3 Q O责的方法。| x & A P S m g
  4. _ ( % @ K t `O 7 E g y a v体装饰器(Conf ] B ^ A D 0 &c6 B = ! Y C I X Wrete D0 u } d F y Aece t u # O R 4 , Horator)V 2 . @ ^ ~:实现抽象j y i H装饰器接口k % ,,负责为具体组件添加具体8 q C q , x C A f的功能。

Java 装饰器模式Decorator详解及实现步骤

二、装c S ^ 3饰器模l F R 7 7 Z # 8I t 8 h P K的实现步骤

1.故事背景:机器% Z p E i人功能扩展的两种方案

^ w , X 9 _ z智能家居领域,某z u , \科技公司推出了第一代家用机器$ 0 5 S V人,它具备三个核编程心功能:对话、唱B ! 7 i 4 r v歌和播放q { v音乐。

Java 装饰器模式Decorator详解及实现步骤

// 第一代机器人:基础功能
interface Robot {
void talk();    // 对话
void sing();    // 唱歌
void playMusic(); // 播放音乐
}
class FirstGenerationRobot implements Robot {
@Override
public void talk() {
System.out.println("机器人:你好,我能陪你聊天");
}
@Override
public void sing() {
System.out.println("机器人:正在播放《青花瓷》");
}
@Override
public void playMusic() {
System.out.println("机器人:正在播放轻音乐");
}
}

随着用户需求升级,% [ s厂家希望扩展%, c o i [ q : 2 $机器人的功能,让它能够扫地和跳舞。针c k ~ # * V对这个需求,有两种技术方案可供选择:

Java 装饰器模式Decorator详解及实现步骤

⑴.方P E W { h | 6 lF I ] y ~ a z V一:传统继承(厂家升p H 9 .级方案)

厂家选择开发第二代机器= 3 Q B人,通过继承第一代产a ) p p .品并添加新功% 6 1 v能:

接口定义

// 基础接口:第一代机器人支持的功能
interface Robot {
void talk();
void sing();
void playMusic();
}

类实现

// 第一代机器人(基础实现)
class FirstGenerationRobot implements Robot {
@Override
public void talk() {
System.out.println("对话中...");
}
@Override
public void sing() {
System.out.println("正在唱歌...");
}
@Override
public void playMusic() {
System.out.println("播放音乐中...");
}
}
// 第二代机器人:通过继承方式扩展功能
class SecondGenerationRobot extends FirstGenerationRobot {
public void sweep() {
System.out.println("正在扫地...");
}
public void dance() {
System.out.println("正在跳舞...");
}
}

测试代V D i , . )e o f D 7 w

public class InheritanceTest {
public static void main(String[] args) {
System.out.println("=== 继承方式测试 ===");
SecondGenerationRobot robot = new SecondGenerationRobot();
robot.talk();
robot.sing();
rhttp://www.cppcns.comobot.playMusic();
robot.sweep();  // 扩展功能
robot.dance();   // 扩展功能
}
}

3 j K m n q h S.方案v 7 2 ! n L H6 , b v D 4:装饰器模式

Java 装饰器模式Decorator详解及实现步骤

通过组合方式动0 ~ M态添加1 { K s l y新功能:

以下是根据机器人例4 % 6 F y C 7 _ 2子实现的装饰器模式代码及详细解释:

抽象K 2 t m h h\ m k )6 / T w z 2 O o J件(t 5 G x 6 S / J ]Robo# { J # 3t 接口a X ^ z ^ H e 0

interface Robot {
void talk();   // 对话
void sing();   // 唱歌
void playMusic(); // 放音乐
}
  • 作用:定义3 m 5 W L O机器人的基本功能,@ ^ Y作为装饰器模式的&d @ 0 y G a % U C u n ]核心接口,} 2 ( g & @ 4规范所有机器人(包括原始机器人和装P T P t d饰后_2 O S , * r \ K % _ ! { y F l | $的机2 , J ^ S 7器人)的行为。

具体组件} ? d n # s # } r(第一代机器人)

class FirstGenerationRobot implements Robot {
@Override
public void talk() {
System.out.println("第一代机器人:对话");
}
@Override
public void sing() {
System.out.println("第一代机器人:唱歌");
}
@Override
public void playMusic() {
System.out.println("第一代机器人:放音乐");
}
}
  • 作用:实现抽象组件,是被f t $ – o装饰的原始对象(第一代机器人,具有& r T Y基本功| ? ?q = 9 8 + I h u 6 6 P p B能)。$ | j

抽象装饰器(RobotDecoratorX T 6 P I

abstract class RobotDecorator implements Robot {
protected Robot robot; // 持有被装饰的机器人对象
public RobotDecorator(Robot robot) {
this.robot = robot;
}
// 转发原始功能(保持原有功能不变)
@Override
public void talk() {
robot.talk();
}
@Override
public void sing() {
robot.sing();
}
@Override
public void playMusic() {
robot.playMusic();
}
}
  • 作用:作为装? 3 W v [ f y i饰器的基a % = k X Kz 3 & D F TL g Q b0 k { .继承抽象组件接口,通过组合(| ] 2 J U d .关联M L C} G v h J b x)持x 1 a r # I v /有原始机器人对象。它实现了原始功能的U d : mH n ? s h B ! N j Z R Z #转发,确保装饰时不破坏原有功能,同时a 1 ! I =为具体装饰器提供统一的0 = y w扩展框架。

具体装饰器(添g A ] l on J \ 4 1D ` I _ g W拖地和跳\ Q D _ h @ ` sU ^ H 2 d & W k 6 5z g U J s E m c功能)

Java 中的 sj Q * _uperF n i r q l ] 关键字

// 拖地装饰器:继承自RobotDecorator,用于为机器人添加拖地功能
class SweepFloorDecorator extends RobotDecorator {
// 构造函数:接收被装饰的机器人实例
public SweepFloorDecorator(Robot robot) {
http://www.cppcns.com  // 通过super调用父类构造函数,保存对原始机器人的引用
super(robot);
}
public void sweepFloor() { // 新增功能:拖地
System.out.println("装饰后:拖地");
}
}
// 跳舞装饰器
class DanceDecorator extends RobotDecorator {
public DanceDecorator(Robot robot) {
super(robot);
}
public void dance() { // 新增功能:跳舞
System.out.println("装饰后:跳舞");
}
}

测试代码

public class RobotDemo {
public static void main(String[] args) {
// 原始机器人(第一代)
Robot robot = new FirstGenerationRobot();
robot.talk();   // 原始功能:对话
robot.sing();   // 原始功能:唱歌
robot.playMusic(); // 原始功能:放音乐
// 装饰器扩展:添加拖地功能
SweepFloorDecorator decoratedwithSweep = new SweepFloorDecorator(robot);
decoratedWithSweep.talk(); // 保留原始功能
decoratedWithSweep.sweepFloor(); // 新增功能:拖地
// 再装饰:添加跳舞功能
DanceDecorator fullyDecorated = new DanceDecorator(decoratedWithSweep);
fullyDecorated.talk(); // 保留原始功能
// 正确调用拖地功能
decoratedWithSweep.sweepFloor(); // 拖地功能
// 新增功能:跳舞
fullyDecorated.dance();
}
}

Java 装饰器模式Decorator详解及实现步骤

装饰器! . R V w ) , c模式通d /N Z D = ) ` 7 g @ | = $组合( _ T ) C ] N而非继承! q H 8 f,实现了运行时动态扩展对象功能,避免了J O [ |继承带来的类爆炸问Q S l c A V k题,Y N j \y d q E U _ N S是处理 “对象功能扩展&rdF e X o x Lquo; 的优雅方案。在机器人例子中,利用装] & ~ 7 I V S i S饰器模式,无需等待厂家更新(继承方式)3 v b \ .,即可快速! : w . o为第一代G &m A E E机器人添加拖地、跳舞功能,体现了模式的灵` Y 5 = W ) g $ F活性和实用性。

Java 装饰器模式Decorator详解及实现步骤

  • R I E y K + { d w承机制– M s a f适合功能较为稳定、扩展需求明确的场景,实现简单,但不够灵活。
  • 装饰器模式f 1 ~ x合需要动态组合功能9 C Y、避免类爆炸的情况,虽然实现% , r `略复杂,但更符合, % f i –开闭原则(对扩展开放,对修改关闭)。

三、流程图和内存图H | F 5 i \

Java 装饰器模式Decorator详解及实现步骤

Java 装饰器模式Decorator详解及实现步骤

1.创建基础机y . n器人

Robot robot = new FirstGenerationRobot();
  • 创建第一代机C Z a 3 9 5 j B D器人实例,具备基础功2 / % }E = w * H 6能(taK } J H ( W X ] 7lk/sing/playMusipythonc)

2.第一次O ! X i u [ +? # | ! G饰:添加拖地功能

SweepFloorDecorator decoratedWithSweep = new SweepFloorDecorator(robot);
  • SweepFloorDecoratorH : K Q I V ~ f有对j J / G原始机器人的引用
  • 继承– T U T C b r |RobotDecorator的默认实现(转发所有4 R s 2方法调用)

3.调用原始功| ` . @ g 5 X Zd z X f G M ? 2

decoratedWithSweep.talk();
  • 执行流程:
    • dE iT _ 7 l F e h .ecoratedWithSweep.talk()调用G z tRobotDecorator的实k , [
    • RobotDecorator转发给被O w # J Z装饰对象K b @ wrobot.talf : }u O z t P Y y # ik(7 \ M)
    • 最终执行G = { IFir% t [ + :stGene_ g o 3 J w E ? 9rationRo@ S Fbot^ 7! o ` l Q v x 8 = V C po a *.0 w w 2 X w L * `talk()

4.调用新增功能

decoratedWithSweep.sweepFloor();
  • 直接调用SweeC p G ( t Q ZpF2 o w g \ /loorDecorator新增@ O ~ y # o C W的方法
  • 输出2 8 G V o J B:"\ v D Q装饰后:拖地"

5.j : C 0 G 4 }第二次装饰:添加跳舞功能

DanceDecorator fullyDecorated = new DanceDecorator(decoratedWithSweep);
  • DanceDe\ @ ; i i c {corator持有@ , KSg Q m c M 8wey H \ { u y P (epFU e x } g m S iloox } d s - irDec@ ? q u V [ woras + | % -k & Y ; V g ftor的引用
  • 形成装饰器i k 42 N P c g \ \套结构:0 * { |Dancf g g = f ! O m seDecorat+ U 5 i o C n For -> SweepFloorDecorator -> FirstGeneI P S ` wratiY o = Z c o 5onRobot

6.调用原始功能(多. T \ L . D \ ;F Lb R & ak [ f + a ( } S r X & W层装饰P ; A =后)

fullyDecorated.talk();
  • 执行流程s c ) y .; 5 $ { A t S
    • fullyDecorr b 0ated.tah 4 b e v X g )lk()o h B g z E tRobotDecu 4 : 4 q qorator的实) n o 7 ^
    • 7 [ P @ N发给被装W $ A饰对象:C * ( [ # ` j }decorateu 1 ~ X ! = K 2 4dWithSwB ^ S = ^ 1 Seep.talk(5 0 ; 3 [)
    • decoratedWD 1 $ t S r nithSweepz ^ 3 G.talk()再次7 X V ` = G转发:robo# R F et( i X g ( f y (.talk()
    • 最终执行FiQx d A = I / I I b ? + OrstGenerationRobot.talk(){ 6 Z p

7.调] 7 = ` T 3 ;用第一层装饰器功能

decoratedWithSweep.sweepFloor();
  • 必须] , * 0通过: X ( T F ; #decoratei 2 % 7 x |dWu 1 D 1 M jithSweep引用调用
  • 因为fullyDe# c 7 o Ncor$ b u G rated类型是DanceDecorator,没有直接暴露sw? A j 1 fee @ 5 $ o M ZepFlb t J 3 Poor()方法

8.调用第S – ] r z N二层装饰器功能

fullyDecorated.dance();
  • | | { 7接调用DaS H 0 } WnceDq ( @ 5 2 !ecorator新增的方法a 7 D U
  • 输出:&quotf f k c O ; \;n; U 0 C 1 8 Dn 1 } g i ; g @ P So ~ @ r R饰后:跳舞"w 8 6

3 个Robot引用的| p 0 * } (\ 8 1 9向对X – l

  1. 变量rp W 4 J h i ) b cobo- u g y Atd w p 7

    • 类型:Robot
    • 指向:FirstGeneratiG 8 O + 0of 2 / R m j _nRobo, & J J p .t实例(} ) / E x e Y原始机器人)
  2. Sweepg 6 u KFloorDecow J L t B ,X w ~ ` _ !rator内部的robot成员变量

    • 类型:Robo) 3 . G t b _ at(父# y : R Q \ } g )RobotDecoratorprotecteT ? m *? ; ) f 7dY [ B Robot robot
    • 指向z + _ Q R U B WFirstGeneX - z R Z t 6ra= D = i a 3tionRo+ 8 T * ^ , C Pbo9 & G # ct实例(与变量robo7 ] \ } nt指向同一个R s 6 Zm i x hK b C p @ O 0 Y n P象)
  3. Danco ^ ` seDecoratoI ^ H Y yrI L N ^d ( ,部的robot成员变量

    • 类型:Robot% P 7 \ Y 7(父类RoboF S . | vtDS ] } 6 ` j 5 . EecoratorH ? *c ; a ^ )protO B Z Q r |ected RoZ Q X .bot rd Q Iobot{ z X ; S & S `
    • g ? z _ ! 2 t k K向:Swt ! # z G D ceepFloorDev ? g D } s \ !corator实例(与前两个引用指向不同对象)

7d 0 : Y ) * E s .用的* ; y ]内存地址比较

Robot robot = new FirstGenerationRobot();
SweepFloorDecorator decoratedWithSweep = new SweepFloorDecorator(robot);
DanceDecorator fullyDecorated = new DanceDecorator(decoratedWithSweep);
// 内存地址比较(假设对象内存地址为示例值)
robot: 0x1000                  // 指向 FirstGenerationRobot
decoratedWithSweep.robot: 0x1000  // 指向 FirstGenerationRobot(与 robot 相同)
fullyDecorated.robot: 0x2000    // 指向 SweepFloorDecorator(与前两者不同)
  • roboO B O atdecoratedWithSwep q @ep.roU D . G {bot) 0 ` @ f } 8向相j I _ & 2 $ \同对象(内存地址均为0xf J t X ? g B { 11000)。
  • fully| - | f l A | . #DeO . 5! ] \ E { W f Y ccorated.\ $ ur: i % j % 3 X 0oboA t . st指向不同对象(内= p , u z } A存地址0x\ / a Z ] #2000,即SweY & ` ; * \ D ~epFloorDecorat$ K = ? ]o^ ] Jr实例)r J D

四、实f s j O I战中的装饰器模式

1. Java I/O9 C { V n h r J ) 库中的应用

// 输入流装饰示例:
InputStream fileInput = new FileInputStream("data.txt");
InputStream bufferInput = new BufferedInputStream(fileInput);
DataInputStream dataInput = new DataInputStream(bufferInput);
// 功能动态组合:
// 基础功能:FileInputStream
// 装饰1:添加缓冲功能 BufferedInputStream
// 装饰2:添加数据处理功能 DataInputStream

2. Spring 框架中的应K _ _ A5 l R ! Q ;

// Spring Security的认证过滤器链:
FilterChain filterChain = new UsernamePasswordAuthenticationFilter(
new BasicAuthenticationFilter(
new SecurityContextPersistenceFilter()
)
);
// 每个过滤器都是一个装饰器,动态增强请求处理能力

到此这A R ^ d l D C篇关于Javv * n h _ `a 装饰E I k ) { W H器模式Dec– = u # Rorator详解及实现B { V T 6 C Wn D : M | j骤的文{ 6 ~章就介绍到这了,更多相j 6 ] P C H x A ?关Java 装饰G w $器模式Decor. I R \ 5 i bQ % ~ b Nator内E # H W容请搜索编程客栈(`_ A 1 L – y . _: Q B n [ F (www.cI v *N & Gppcns.com)以前的文章或继续浏览下面的相关文章希望大家以后多多} R H & m h D支持l 4 &w b w M 9 _ ZW D W m编程客栈(wwwQ _ R p Z E.cr G Z { Kppcns.com)t + 4M # z X i ( y 3 – # A 9 v :

本文标题: Java 装饰器模式Den u : ; 9corp } ^ _ 8 I Y Bator详解及实现步骤
本文地址: http://wz / 8 p * Vww.cppcns.com/r{ W y ? i i z quaB z ! ~ A Gnjian/java/O N H . 1 j + 8 N717012.html
搜索