装饰模式
装饰模式,在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
使用场景
-
需要扩展一个类的功能,或给一个类添加附加职责。
-
需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
-
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
-
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
装饰模式
允许向一个现有的对象添加新的功能,同时又不改变其结构。
被装饰类
//被装饰类的抽象类
public abstract class AbstractCake { //被装饰类和装饰类的最终父类
abstract String detail(); //蛋糕的描述
abstract int money(); //蛋糕的价钱
}
-----------------------------------------
//实现类
public class Cake extends AbstractCake { //被装饰类的具体实现类
@Override
String detail() {
return new String("普通蛋糕");
}
@Override
int money() {
return 8;
}
}
装饰类
//装饰类的抽象类
public class AbstractBigCake extends AbstractCake { //继承自抽象被装饰类
AbstractCake cake; //保存被装饰的类
public AbstractBigCake(AbstractCake cake) {
this.cake = cake;
}
@Override
String detail() {
return cake.detail();
}
@Override
int money() {
return cake.money();
}
}
-------------------------------------------
//装饰类实现类
public class ChocolateCake extends AbstractBigCake { //继承抽象装饰类
public ChocolateCake(AbstractCake cake) {
super(cake); //将被装饰类注入进其父类抽象装饰类中
}
@Override
String detail() {
return super.detail()+"加一份巧克力"; //增加描述
}
@Override
int money() {
return super.money()+4; //增加价钱
}
}
--------------------------------------------
//装饰类实现类
public class FruitCake extends AbstractBigCake { //继承抽象装饰类
public FruitCake(AbstractCake cake) {
super(cake); //将被装饰类注入进其父类抽象装饰类中
}
@Override
String detail() {
return super.detail()+"加一份水果"; //增加描述
}
@Override
int money() {
return super.money()+2; //增加价钱
}
}
通过保存基本被装饰类的引用,并在调用方法时将基本装饰类的调用与新加的功能组合来实现装饰功能。
测试类
//测试类
class Test {
public static void main(String[] args) {
AbstractCake cake=new Cake(); //创建一个基本的蛋糕
cake=new ChocolateCake(cake); //为蛋糕加一份巧克力
cake=new FruitCake(cake); //为蛋糕加一份水果
System.out.println(cake.detail()); //普通蛋糕加一份巧克力加一份水果
System.out.println(cake.money()); //14
}
}
.println(cake.detail()); //普通蛋糕加一份巧克力加一份水果
System.out.println(cake.money()); //14
}
}
每次装饰只需要将其装入装饰类即可。