设计模型-装饰器模式

装饰器模式

装饰器模式 可以在不改变原有对象的情况下拓展其功能。装饰器模式通过组合替代继承来扩展原始类的功能。在一些继承关系比较复杂的场景(如IO) 比较实用。

​ 可以对原始类嵌套使用 多个装饰器。为了实现这一效果,装饰器类需要跟原始类继承相同的抽象类和实现相同的接口

使用场景

  1. 需要在运行时动态的给一个对象增加额外职责(功能)时
  2. 需要给一个现有的类增加职责,但是又不想通过继承

IO中的装饰器模式

​ JavaIO中 FilterOutputStream/FilterInputStream 是 InputStream的装饰类

class FilterOutputStream extends OutputStream {

    protected OutputStream out;


    public FilterOutputStream(OutputStream out) {
        this.out = out;
    }

FilterOutputStream 持有了OutputStream的一个引用

下面给出一个相关的例子

类结构图

​ 首先我们有一个ICoffee接口,里面有一个制作咖啡的接口方法makeCoffee()。要进行装饰的类 OriginalCoffee 和装饰者基类CoffeeDecorator(一般为抽象类)实现了此接口。CoffeeDecorator类里面持有一个ICoffee引用,我们第一步会把要装饰那个原始对象赋值给这个引用,那样在装饰者类中才可以调用到那个被装饰的对象的方法。MilkDecoratorSugarDecorator 都继承至CoffeeDecorator, 都是具体的装饰者类。

相关代码

  • ICoffee 接口
    public interface ICoffee{
        void makeCoffee();
    }
  • OriginalCoffee
    public static class OriginalCoffee implements ICoffee{
        @Override
        public void makeCoffee(){
            System.out.println("Original Coffee");
        }
        public OriginalCoffee(){}
    }
  • CoffeeDecorator
    public static abstract class CoffeeDecorator implements ICoffee{
        private ICoffee iCoffee;

        public CoffeeDecorator(ICoffee iCoffee){
            this.iCoffee = iCoffee;
        }

        @Override
        public void makeCoffee(){
            iCoffee.makeCoffee();
        }
    }
  • SugarCoffee和MilkCoffee

        public static class SugarCoffee extends CoffeeDecorator{
            public SugarCoffee(ICoffee iCoffee){
                super(iCoffee);
            }
    
            @Override
            public void makeCoffee(){
                System.out.println("Add sugar");
                super.makeCoffee();
            }
        }
    
        public static class MilkCoffee extends CoffeeDecorator{
            public MilkCoffee(ICoffee iCoffee){
                super(iCoffee);
            }
    
            @Override
            public void makeCoffee(){
                System.out.println("Add milk");
                super.makeCoffee();
            }
        }
    

使用代码

        // 原始对象
        ICoffee coffee = new OriginalCoffee();
        coffee.makeCoffee();
        System.out.println("------------------");

        // 第一次增强
        coffee = new SugarCoffee(coffee);
        coffee.makeCoffee();
        System.out.println("------------------");

        //第二次增强
        coffee = new MilkCoffee(coffee);
        coffee.makeCoffee();
        System.out.println("-------------------");

输出结果

Original Coffee
------------------
Add sugar
Original Coffee
------------------
Add milk
Add sugar
Original Coffee
-------------------
posted @ 2025-03-28 14:31  aidan_8  阅读(21)  评论(0)    收藏  举报