登录    关于
马育民老师的博客

马育民的博客

QQ:65242847

JAVA装饰器(者)模式

说明

装饰器模式(Decorator Pattern),向一个现有的对象添加新的功能,同时又不改变其结构。

这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,提供了额外的功能

优点

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点

多层装饰比较复杂。

应用场景

扩展类的功能

真实例子

BufferedInputStream 缓冲流

关键代码:

//原有类
InputStream inputStream = new FileInputStream(filepath);

//装饰类,传入原有类对象,通过装饰类,增加额外功能
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);

InputStream类已经写好了,功能完善,已经正常使用。

但有些情况下,需要额外功能,,通过 BufferedInputStream装饰器类,增加额外功能

例子

轿车具备完整的功能,可以正常使用

但有些时候,需要加装 车顶行李箱,装衣服、裤子,在不需要时,还可以卸下

通过装饰器模式,设计这一功能

轿车接口

public interface ICar {
    public void drive(String dest);
}

轿车类

该类已经是一个完整的类,可以正常使用

public class Car implements ICar{
    @Override
    public void drive(String dest) {
        System.out.println("出发去 "+dest);
    }
}

抽象装饰器类

其作用是:装饰器类继承该类

public abstract class CarDecorator implements ICar{

    protected ICar car;
    public CarDecorator(ICar car) {
        this.car=car;
    }

    @Override
    public void drive(String dest) {
        car.drive(dest);
    }
}

装饰器类

增加 放行李、移除行李功能

public class BootCar extends CarDecorator{
    private List<String> clothesList =new ArrayList();

    public BootCar(ICar car) {
        super(car);
    }

    @Override
    public void drive(String dest) {
        if(!clothesList.isEmpty()){
            System.out.print("带上 ");
            for(String item: clothesList){
                System.out.print(item+" ");
            }
        }
        super.drive(dest);
    }

    /**
     * 放衣服
     * @param clothes
     */
    public void put(String clothes){
        clothesList.add(clothes);
    }

    /**
     * 移除
     * @param clothes
     */
    public void remove(String clothes){
        clothesList.remove(clothes);
    }
}

测试装饰器类

在不改变 原有轿车类 的情况下,增加 放行李、移除行李功能

ICar car=new Car();
BootCar bCar=new BootCar(car);
bCar.put("T恤");
bCar.put("沙滩裤");
bCar.put("沙滩鞋");
bCar.remove("T恤");
bCar.drive("海南岛");

测试原有轿车类

原有的轿车类没有改变,仍然可以使用

ICar car=new Car();
car.drive("公司");

原文出处:https://malaoshi.top/show_1IX1I752MrKw.html