java 装饰器模式

装饰器模式简介

装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构,这种类型的设计模式属于结构性模式,它是现有的类的一个包装。

装饰器模式创建了一个修饰类,将对象包装在修饰类中,在保持类方法签名完整性的前提下,提供了额外的功能。

我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀,装饰器模式可以帮助我们解决这个问题。

实现方式

装饰器模式包含四个核心角色:

  • 抽象组件(Component): 一个抽象接口或者类,定义了原始对象的装饰器对象,是具体组件类的父类或接口。
  • 具体组件(Concrete Component): 被装饰的原始对象,定义了需要添加新功能的对象。
  • 抽象装饰器(Decorator): 继承自抽象组件,包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象。
  • 具体装饰器(Concrete Decorator): 实现了抽象装饰器,负责向抽象组件添加新的功能。通常会在调用原始对象的方法之前或之后执行自己的操作。

1、Component 类充当抽象角色,不应该具体实现。
2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

根据一个例子来具体说明:
不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

在这个例子中具体的组件就是一幅画,玻璃和画框都可以看作是画的装饰。
因此,首先我们来定义这幅画的抽象组件接口和具体的组件:

//抽象组件
public interface Component {
    void samp();
}

//具体组件  “一幅画”
public class ConcreteComponent implements Component{
    @Override
    public void samp() {
        System.out.println("i am an picture");
    }
}

然后是抽象装饰器,可以通过继承这个类来为一幅画添加各种装饰:
在这个抽象类中引入了抽象组件对象,可以通过这种方式获得其他的装饰器对象,然后再实现自己的装饰。

//抽象装饰器
class Decorator implements Component{

    private Component component;
    
    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void samp() {
        this.component.samp();
    }
}

具体装饰角色,分别为画加画框和玻璃:

//具体装饰器A
class ConcreteDecoratorA extends Decorator{

    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void samp(){
        super.samp();
        System.out.println("给这个picture加个画框");
    }
}

//具体装饰器B
class ConcreteDecoratorB extends Decorator{

    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void samp(){
        super.samp();
        System.out.println("给这个picture加个玻璃");
    }
}

测试类:先为一幅画添加画框,再为它添加玻璃:

public static void main(String[] args) {
        Component comp=new ConcreteComponent();

        //给这幅画加一个画框
        Component comp1=new ConcreteDecoratorA(comp);
        comp1.samp();

        //再给这幅画加个玻璃
        System.out.println("=============================");
        Component comp2=new ConcreteDecoratorB(comp1);
        comp2.samp();
    }

输出:

在这里插入图片描述
在上述例子中,这幅画是ConcreteComponent类,而画框,玻璃是装饰类,要装饰的是Component类。系统先为画添加了一个画框,又为装了画框的画添了玻璃,从而这幅画被两个装饰装饰好了。当然,还可以为它继续装饰,或者按照其他的装饰顺序进行装饰。

总结

优点:

  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
  • 通过不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出更多不同行为的组合。

缺点:

  • 使用装饰模式会使用更多的类去创造对象,过多的装饰类会使程序变得复杂,可读性差。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每周都想吃火锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值