装饰模式
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
在装饰模式中的角色有:
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
例如:不同的咖啡可以和不同的调料都有不同的费用,如果使用继承方式,则会陷入无以复加的地步。这里会有N多个类。
源码:
- public abstract class 饮料 {
- protected String description = "不知名的饮料";
- public String 描述() {
- return description;
- }
- public abstract String 价格();
- }
三种咖啡
- public class 混合咖啡 extends 饮料 {
- public 猫屎咖啡(){
- description = "混合咖啡";
- }
- @Override
- public String 价格() {
- return "3毛";
- }
- }
- public class 狗屎咖啡 extends 饮料 {
- public 狗屎咖啡(){
- description = "狗屎咖啡";
- }
- @Override
- public String 价格() {
- return "5毛";
- }
- }
- public class 不咋好喝咖啡 extends 饮料 {
- public 不咋好喝咖啡(){
- description = "不咋好喝咖啡";
- }
- @Override
- public double 价格() {
- return "1毛";
- }
- }
- public abstract class 调味装饰 extends 饮料{
- public abstract String 描述();
- }
- public class 牛奶 extends 调味装饰{
- 饮料 yl;
- public 牛奶(饮料 yl){
- this.yl = yl;
- }
- @Override
- public String 描述() {
- return yl.描述() + " , 牛奶,我还是喜欢纯奶";
- }
- @Override
- public String 价格() {
- return yl.价格() + "0.4";
- }
- }
- public class 黑糖 extends 调味装饰 {
- 饮料 yl;
- public Whip(饮料 yl){
- this.yl = yl;
- }
- @Override
- public String 描述() {
- return yl.描述() + " , 黑糖坏牙";
- }
- @Override
- public String 价格() {
- return yl.价格() + "0.20";
- }
- }
- public class 咖啡 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- 饮料 yl = new 狗屎咖啡();
- System.out.println(yl.描述() + " ?" + yl.价格());
- 饮料 yl2 = new 不咋好喝咖啡();
- yl2 = new 黑糖(yl2);
- System.out.println(yl2.描述() + " ?" + yl2.价格());
- }
- }
输出:狗屎咖啡 ? 5毛
不咋好喝咖啡,黑糖 ? 1.20
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。