Java装饰器设计模式详解:实例讲解与应用场景完全指南

装饰器设计模式用于在运行时修改对象的功能,同时不会影响同一类的其他实例,因此每个对象都可以具有修改后的行为。装饰器设计模式是结构型设计模式之一(例如适配器模式、桥接模式、组合模式),它使用抽象类或接口以及组合关系来实现。

装饰器设计模式

我们通常使用继承或组合来扩展对象的行为,但这种方式是在编译时完成的,并且适用于类的所有实例。我们无法在运行时动态添加新功能或移除现有行为——这正是装饰器模式的应用场景。假设我们想要实现不同种类的汽车——我们可以创建Car接口来定义组装方法,然后有一个基本汽车类,进一步扩展为运动汽车和豪华汽车。实现的层次结构将如下图所示。但是,如果我们想要在运行时获得既具有运动汽车特性又具有豪华汽车特性的汽车,实现就会变得复杂;如果我们还想指定特性添加的顺序,则会更加复杂。想象一下,如果我们有十种不同类型的汽车,使用继承和组合的实现逻辑将难以管理。为了解决这种编程情况,我们在Java中应用装饰器模式。我们需要以下组件来实现装饰器设计模式。

  1. 组件接口 – 定义将要实现的方法的接口或抽象类。在我们的案例中,Car将作为组件接口。
    package com.Olivia.design.decorator;
    
    public interface Car {
        public void assemble();
    }
  2. 组件实现 – 组件接口的基本实现。我们可以将BasicCar类作为组件的实现。
    package com.Olivia.design.decorator;
    
    public class BasicCar implements Car {
        @Override
        public void assemble() {
            System.out.print("基本汽车。");
        }
    }
  3. 装饰者 – 装饰者类实现组件接口,并且与组件接口具有”有一个”(HAS-A)关系。组件变量应该对子装饰者类可访问,所以我们将该变量设置为受保护的。
    package com.Olivia.design.decorator;
    
    public class CarDecorator implements Car {
        protected Car car;
        
        public CarDecorator(Car c) {
            this.car = c;
        }
        
        @Override
        public void assemble() {
            this.car.assemble();
        }
    }
  4. 具体装饰者 – 扩展基本装饰者功能并相应地修改组件的行为。我们可以将LuxuryCar和SportsCar作为具体装饰者类。
    package com.Olivia.design.decorator;
    
    public class SportsCar extends CarDecorator {
        public SportsCar(Car c) {
            super(c);
        }
        
        @Override
        public void assemble() {
            super.assemble();
            System.out.print(" 添加运动汽车特性。");
        }
    }
    package com.Olivia.design.decorator;
    
    public class LuxuryCar extends CarDecorator {
        public LuxuryCar(Car c) {
            super(c);
        }
        
        @Override
        public void assemble() {
            super.assemble();
            System.out.print(" 添加豪华汽车特性。");
        }
    }

装饰者设计模式 – 类图

装饰者设计模式测试程序

package com.Olivia.design.test;

import com.Olivia.design.decorator.BasicCar;
import com.Olivia.design.decorator.Car;
import com.Olivia.design.decorator.LuxuryCar;
import com.Olivia.design.decorator.SportsCar;

public class DecoratorPatternTest {
    public static void main(String[] args) {
        Car sportsCar = new SportsCar(new BasicCar());
        sportsCar.assemble();
        System.out.println("\n*****");
        
        Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
        sportsLuxuryCar.assemble();
    }
}

请注意,客户端程序可以在运行时创建不同类型的对象,并且还可以指定执行的顺序。以上测试程序的输出为:

基本汽车。 添加运动汽车特性。
*****
基本汽车。 添加豪华汽车特性。 添加运动汽车特性。

装饰者设计模式 – 重要要点

  • 装饰器设计模式有助于提供运行时修改能力,因此更加灵活。当选择项较多时,它易于维护和扩展。
  • 装饰器设计模式的缺点是它使用大量相似类型的对象(装饰器)。
  • 装饰器模式在Java IO类中被广泛使用,例如FileReader、BufferedReader等。
bannerAds