前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式(六)装饰器模式

Java设计模式(六)装饰器模式

作者头像
每天学Java
发布2020-06-01 18:02:53
4060
发布2020-06-01 18:02:53
举报
文章被收录于专栏:每天学Java每天学Java

在学装饰器模式的时候,我想到了责任链模式中的级别这个概念,为什么这么说,在一个OA系统中我们会有不同级别(或者说权限范围不同)的管理员,首先我们要明确不同级别的管理员它也是管理员,我们那如何在管理员这个实体的基础上动态的去设置他们的权限范围呢?我们把权限当作一种挂饰,这种挂饰放在不同的管理员身上就代表他们是什么管理员,那么这种挂饰如何放到管理员身上呢?这就需要装饰七模式了,而装饰器模式也就是实现了这样一个功能(我的理解)。看一下概念:

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

如上面的例子所说,我们如何使用装饰器模式来实现这样的一个功能呢?一步一步的来看:

首先定义一个管理员接口,实现这个接口证明你就是一个管理员:

代码语言:javascript
复制
//定义一个组件/管理员
代码语言:javascript
复制
interface Component {
    void identity();
}

有了这个接口以后,那就要写一个真正意义管理员了

代码语言:javascript
复制
//定义一个基础类/基础管理员
代码语言:javascript
复制
class Administrator implements Component {

    @Override
    public void identity() {
        System.out.println("我是管理员,我现在只有身份没有权限");
    }
}

到这里我们就有了现有的对象管理员了,那么如何动态的去扩展它的权限呢?这就需要我们去写一个装饰器了,他负责把权限装饰到这个现有的管理员身上。如何做这个装饰器?我们首先要明确,这个装饰器是吧权限挂到管理员身上,那么他肯定要有这个管理员的实例(对象),不然谁知道你要挂在谁身上,所以这个装饰器的构造器中我们要传入一个管理员,其次如果想不破坏管理员的原有结构功能,那么我们肯定要实现管理员这个接口,放入传入具体管理员实例的方法,这样才能保证结构和功能(如果你实现接口,那么传入的管理员功能你岂不是想实现就实现,不想实现就不实现了)具体的代码如下:

代码语言:javascript
复制
//定义装饰器/负责权限装饰
代码语言:javascript
复制
class Decorator implements Component {
    protected Component component;
    //这里传入基础的管理员,才会保证原有结构
    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void identity() {
    //这里是执行原有的功能
        component.identity();
    }
}

既然讲清楚了装饰器,那么我们就要通过装饰器,把权限这个挂饰挂在管理员身上,以此来形成负责不同模块的管理员工。这里我们来实现两个挂饰:写挂饰我们要注意,挂饰通过装饰器去挂,那么我们肯定要继承这个装饰器,在重写它的方法中动态的增加权限。

代码语言:javascript
复制
class DeA extends Decorator {
代码语言:javascript
复制

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

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

    public void  personnelFile() {
        System.out.println("我负责人事");
    }


}

class DeB extends Decorator {

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

    public void administration() {
        System.out.println("我负责行政");
    }
    @Override
    public void identity() {
        this.component.identity();
        administration();
    }

}

效果:

代码语言:javascript
复制
 public static void main(String[] args) {
代码语言:javascript
复制
        Component component = new DeA(new Administrator());
        component.identity();
        Component component1 = new DeB(new Administrator());
        component1.identity();
        Decorator decorator = new Decorator(new Administrator());
    }

结果:
Connected to the target VM, address: '127.0.0.1:49391', transport: 'socket'
我是管理员
我负责人事
我是管理员
我负责行政
Disconnected from the target VM, address: '127.0.0.1:49391', transport: 'socket'

Process finished with exit code 0

说到这里就算是把这个结构型设计模式大致理解了一下,我的开发经理告诉,设计模式最好还是要实际运用才能真正意义上理解,但是我觉得如果你不学,等实际运用的机会是不可能。只是你学了,然后在工作中尽量去用,或者前辈跟你说他哪里哪里用了什么模式,你才会理解的更加容易。

下面说一下这个模式的优缺点:

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

缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。


小程序今天没有更新题库,因为构思如何对小程序进行一个整理升级,现有的功能还是有点low的。大家可以看看知识库哦

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档