(七)Java架构师成长之路-设计模式:装饰器模式

一.定义

在不改变原有对象行为的基础上,扩展对象的功能。

属于结构型模式

二.通用写法

一般来说装饰器模式有这么几个功能

Component:抽象组件

ConcreteComponent:具体的组件,也就是被装饰的对象

Decorator:抽象装饰器

ConcreteComponent:具体的装饰器

下面来看一个简单的例子

买煎饼的时候可以加鸡蛋可以加火腿,也可以什么都不加。我们用装饰器模式来模式一下这个场景

首先定义一个抽象组件

public abstract class Pancake {

    protected abstract String getName();

    protected abstract Double getPrice();
}

定义一个具体的组件,实现抽象组件的方法

public class BasePancake extends Pancake{
    protected String getName() {
        return "煎饼";
    }

    protected Double getPrice() {
        return 5d;
    }
}

然后我们定义一个抽象的装饰器,这个抽象装饰器有个特点:它一定是有一个抽象组件作为参数的构造方法

public abstract class PancakeDecorator extends Pancake{

    private Pancake pancake;

    public PancakeDecorator(Pancake pancake) {
        this.pancake = pancake;
    }

    public  String getName() {
        return this.pancake.getName();
    }
    
    public Double getPrice() {
        return this.pancake.getPrice();
    }
}

具体的装饰器,EggDecorator,加鸡蛋的煎饼

public class EggDecorator extends PancakeDecorator{

    private Pancake pancake;

    public EggDecorator(Pancake pancake) {
        super(pancake);
    }

    public String getName() {
        return super.getName() + "+一个鸡蛋";
    }

    public Double getPrice() {
        return super.getPrice() + 1d;
    }
}

具体的装饰器,SausageDecorator,加香肠的煎饼

public class SausageDecorator extends PancakeDecorator{
    public SausageDecorator(Pancake pancake) {
        super(pancake);
    }

    @Override
    public String getName() {
        return super.getName() + "+一个香肠";
    }

    @Override
    public Double getPrice() {
        return super.getPrice() + 2d;
    }
}

测试类:

public class Test {

    public static void main(String[] args) {
        Pancake pancake = new BasePancake();
        System.out.println(pancake.getName() + ",总价:" + pancake.getPrice());
        Pancake pancakeEgg = new EggDecorator(pancake);
        System.out.println(pancakeEgg.getName() + ",总价:" + pancakeEgg.getPrice());
        Pancake pancakeSausage = new SausageDecorator(pancakeEgg);
        System.out.println(pancakeSausage.getName() + ",总价:" + pancakeSausage.getPrice());
    }
}

输出

我们通过使用装饰器模式,在不改变原有对象行为的基础上,给它增加了其他功能,使得一个煎饼可以加鸡蛋加火腿,也可以再定义其他的类加其他的材料

三.装饰器模式的优缺点

优点:符合开闭原则,代码易扩展,耦合度低

缺点:装饰器类容易变多,给代码阅读和维护带来挑战

四.装饰器模式在源码中的应用

FileInputStream、BufferedInputStream、Cache

五.装饰器模式和代理模式的区别

装饰器模式也是一种静态代理模式,但它强调功能的扩展,而代理模式强调功能的增强。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值