目录
一、基本概念
二、结构
1.图示
三、案例演示
被装饰对象的基类 一个接口 有cost()和description()两个抽象方法
具体被装饰的对象 实现上面这个接口
装饰者抽象类 (基类) 实现drink接口
具体的装饰者类 ------ 糖
具体装饰者类 ---- 黑豆
测试
结果:
四、设计原则
总结
一、基本概念
装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
运用场景
装饰者模式的应用场景:在不改变原有类结构的基础上,新增,限制,或者改造功能。
动态地将功能附加到对象身上。扩展功能,装饰者提供了比继承更有弹性的替代方案,可以防止类爆炸。
二、结构
1.图示
这是一张很经典的图:
Component:被装饰对象的基类
定义对象的接口,可以给这些对象动态的添加职责。
ConcreteComponent:具体被装饰的对象
定义具体的对象,Decorator可以给它增加额外的功能
Decorator:装饰者抽象类
维护指向Component实例的引用,定义Component一致的接口
ConcreteDecorator 具体装饰者
具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责
三、案例演示
被装饰对象的基类 一个接口 有cost()和description()两个抽象方法
public interface Drink {
float cost();//价格
String description();// 描述
}
具体被装饰的对象 实现上面这个接口
package com.example.lib4;
/**
* 被装饰的类
* 豆浆
* @author lzy
* @deprecated
* */
public class SoyaBeanMilk implements Drink{
@Override
public float cost() {
return 10f;
}
@Override
public String description() {
return "纯豆浆";
}
}
装饰者抽象类 (基类) 实现drink接口
public abstract class Decorator implements Drink {
private Drink drink;
public Decorator(Drink drink){
this.drink = drink;
}
@Override
public float cost() {
return drink.cost();
}
@Override
public String description() {
return drink.description();
}
}
具体的装饰者类 ------ 糖
public class SugarDecorator extends Decorator{
public SugarDecorator(Drink drink) {
super(drink);
}
@Override
public float cost() {
return super.cost()+1.0f;
}
@Override
public String description() {
return super.description()+"糖";
}
}
具体装饰者类 ---- 黑豆
public class BlacbeanDecorator extends Decorator{
public BlacbeanDecorator(Drink drink) {
super(drink);
}
@Override
public float cost() {
return super.cost()+2.0f;
}
@Override
public String description() {
return super.description()+"黑豆";
}
}
测试
public class test {
public static void main(String[] args) {
Drink drink = new SoyaBeanMilk(); //纯豆浆(被装饰) cost() 10f description 纯豆浆
SugarDecorator sugar = new SugarDecorator(drink); //装饰者 继承Decorator cost() +1.f description 糖
BlacbeanDecorator blackbean = new BlacbeanDecorator(sugar);//装饰者
System.out.println("你点的豆浆是"+blackbean.description());
System.out.println("花了"+blackbean.cost());
/**
* Decorator 装饰者抽象类 传入drink对象 然后重写cost() description()方法
*
* 对类理解的不是很继承 抽象类 理解不是很好
* */
}
}
结果:
这个案例的背景是 豆浆有很多口味的豆浆 ,有加糖的,加黑豆的 ,纯豆浆,又加糖又加黑豆的,等等 ,如果采用继承来添加这些功能,那可能子类太多了,类爆炸,不利于开发。所以采用设计者模式来代替类的继承。
再加一个小例子
File file = new File("D:\\io\\lzy1.txt");
OutputStream out = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(out);
DataOutputStream dos = new DataOutputStream(bos);
是不是很熟悉,其实已经在不知不觉已经使用过装饰者设计模式了。
四、设计原则
要使用装饰者模式,需要满足以下设计原则:
(1)封装变化多
(2)用组合,少用继承
(3).针对接口编程,不针对实现编程
(4)开放-关闭原则:类应该对扩展开放,对修改关闭
(5)为交互对象之间的松耦合设计而努力
总结
优点:
(1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性
(2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点:
用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难
tip:这个例子来源于Java之io的学习整理