概念
上班族大多都有睡懒觉的习惯,每天早上上班时间都很紧张,于是很多人为了多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等,都是装饰器模式。
在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。
装饰器的定义与特点
装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
优缺点:
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
- 装饰器模式完全遵守开闭原则
其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
要点: 装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为
模式结构
装饰器模式主要包含以下角色。
- 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
//被装饰者,汽车类
public abstract class Car {
protected String name;
public String getName() {
return name;
}
public abstract Long speed();
}
//被装饰的初始状态
public class SportsCar extends Car {
public SportsCar() {
name="跑车";
}
@Override
public Long speed() {
return 100L;
}
}
//改装车间表
public abstract class Refit extends Car {
public abstract String getName();
}
//装饰层
public class Turbine extends Refit {
Car car;
public Turbine(Car car) {
this.car = car;
}
@Override
public String getName() {
return car.getName()+"增加涡轮发动机";
}
@Override
public Long speed() {
return car.speed()+50L;
}
}
运行方法
public class Main {
public static void main(String[] args) {
Car car = new SportsCar();
System.out.println(car.getName()+"时速"+car.speed());
Turbine turbine = new Turbine(car);
System.out.println(turbine.getName()+"时速"+turbine.speed());
}
}
运行结果
装饰者模式和代理模式的区别
装饰器模式:能动态的新增或组合对象的行为。
代理模式:为其他对象提供一种代理以控制对这个对象的访问.(换句话说,可以不执行某功能)
装饰模式是“新增行为”,而代理模式是“控制访问”。
装饰模式是在原有基础之上增加额外的功能,而代理模式有两种情况可以使用第一种是延迟代理对象,对于大文件或者目前还未加载完的对象,使用比较合适。第二种为权限判断,在调用功能前判断当前用户是否有此权限。