装饰器模式
在学装饰器模式的时候,我想到了责任链模式中的级别这个概念,为什么这么说,在一个OA系统中我们会有不同级别(或者说权限范围不同)的管理员,首先我们要明确不同级别的管理员它也是管理员,我们那如何在管理员这个实体的基础上动态的去设置他们的权限范围呢?我们把权限当作一种挂饰,这种挂饰放在不同的管理员身上就代表他们是什么管理员,那么这种挂饰如何放到管理员身上呢?这就需要装饰七模式了,而装饰器模式也就是实现了这样一个功能(我的理解)。看一下概念:
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
如上面的例子所说,我们如何使用装饰器模式来实现这样的一个功能呢?一步一步的来看:
首先定义一个管理员接口,实现这个接口证明你就是一个管理员:
//定义一个组件/管理员
interface Component {
void identity();
}
有了这个接口以后,那就要写一个真正意义管理员了
//定义一个基础类/基础管理员
class Administrator implements Component {
@Override
public void identity() {
System.out.println("我是管理员,我现在只有身份没有权限");
}
}
到这里我们就有了现有的对象管理员了,那么如何动态的去扩展它的权限呢?这就需要我们去写一个装饰器了,他负责把权限装饰到这个现有的管理员身上。如何做这个装饰器?我们首先要明确,这个装饰器是吧权限挂到管理员身上,那么他肯定要有这个管理员的实例(对象),不然谁知道你要挂在谁身上,所以这个装饰器的构造器中我们要传入一个管理员,其次如果想不破坏管理员的原有结构功能,那么我们肯定要实现管理员这个接口,放入传入具体管理员实例的方法,这样才能保证结构和功能(如果你实现接口,那么传入的管理员功能你岂不是想实现就实现,不想实现就不实现了)具体的代码如下:
//定义装饰器/负责权限装饰
class Decorator implements Component {
protected Component component;
//这里传入基础的管理员,才会保证原有结构
public Decorator(Component component) {
this.component = component;
}
@Override
public void identity() {
//这里是执行原有的功能
component.identity();
}
}
既然讲清楚了装饰器,那么我们就要通过装饰器,把权限这个挂饰挂在管理员身上,以此来形成负责不同模块的管理员工。这里我们来实现两个挂饰:写挂饰我们要注意,挂饰通过装饰器去挂,那么我们肯定要继承这个装饰器,在重写它的方法中动态的增加权限。
class DeA extends Decorator {
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();
}
}
效果:
public static void main(String[] args) {
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、动态增加功能,动态撤销。
更多文章请关注公众号:每天学Java。想获得更多最新面试提醒请进入小程序:每天学Java
公众号二维码: 小程序二维码: