做电商怎么入门,百度关键词怎么优化,网站建设需要什么流程,企业服务公司经营范围是什么装饰器模式
装饰器模式#xff08;Decorator Pattern#xff09;允许向一个现有的对象添加新的功能#xff0c;同时又不改变其结构。这种类型的设计模式属于结构型模式#xff0c;它是作为现有的类的一个包装。
装饰器模式通过将对象包装在装饰器类中#xff0c;以便动态…装饰器模式
装饰器模式Decorator Pattern允许向一个现有的对象添加新的功能同时又不改变其结构。这种类型的设计模式属于结构型模式它是作为现有的类的一个包装。
装饰器模式通过将对象包装在装饰器类中以便动态地修改其行为。
这种模式创建了一个装饰类用来包装原有的类并在保持类方法签名完整性的前提下提供了额外的功能。
我们通过下面的实例来演示装饰器模式的用法。其中我们将把一个形状装饰上不同的颜色同时又不改变形状类。
优缺点
优点
不改动原有代码动态增加功能。对象间不会相互依赖、松耦合。符合开闭原则扩展性好便于维护。
缺点
装饰器环节过多的话导致装饰器类膨胀。装饰器层层嵌套比较复杂可能导致排查问题流程繁琐。
装饰器模式的结构
通常情况下扩展一个类的功能会使用继承方式来实现。但继承具有静态特征耦合度高并且随着扩展功能的增多子类会很膨胀。如果使用组合关系来创建一个包装对象即装饰对象来包裹真实对象并在保持真实对象的类结构不变的前提下为其提供额外的功能这就是装饰器模式的目标。下面来分析其基本结构和实现方法。
模式的结构
装饰器模式主要包含以下角色。
抽象构件Component角色定义一个抽象接口以规范准备接收附加责任的对象。具体构件ConcreteComponent角色实现抽象构件通过装饰角色为其添加一些职责。抽象装饰Decorator角色继承抽象构件并包含具体构件的实例可以通过其子类扩展具体构件的功能。具体装饰ConcreteDecorator角色实现抽象装饰的相关方法并给具体构件对象添加附加的责任。
装饰器模式的结构图如图所示。 装饰器模式实例
实例——图画
不论一幅画有没有画框都可以挂在墙上但是通常都是有画框的并且实际上是画框被挂在墙上。在挂在墙上之前画可以被蒙上玻璃装到框子里这时画、玻璃和画框形成了一个物体。
代码如下
画(Painting接口)
public interface Painting {public void show();
}
唐宫仕女图(TangGong类)
public class TangGong implements Painting {Overridepublic void show(){System.out.println(这是一副唐宫仕女图);}
}
装饰器类
public class Decorator implements Painting {private Painting painting;public Decorator(Painting monaLisa){this.painting monaLisa;}Overridepublic void show() {System.out.println(先加上相框);painting.show();System.out.println(再扣上玻璃);}
}
测试类
public class DecoratorTest {public static void main(String[] args) {Painting painting new TangGong();Painting monaLisa new Decorator(painting);TangGong.show();}
}
实现方式 ——蜜雪冰城奶茶
秋天到了女朋友非要喝秋天的第一杯奶茶到了“蜜雪冰城”奶茶店后给女朋友点了一杯奶茶加了珍珠、芒果等配料给自己点了一杯加冰柠檬水加了冰块、柠檬片等配料这时候就可以使用装饰器模式。
奶茶抽象构件 珍珠芒果奶茶、柠檬水具体构件 配料装饰角色 珍珠、芒果、柠檬具体装饰角色 代码实现
抽象构件(Component)角色奶茶
public interface IMilktea {void addDosing();
}
具体构件(ConcreteComponent)角色珍珠奶茶
public class PearlMilktea implements IMilktea{Overridepublic void addDosing() {System.out.println(开始制作珍珠奶茶);}
}
柠檬水
public class LemonMilktea implements IMilktea{Overridepublic void addDosing() {System.out.println(开始制作柠檬水);}
}
装饰Decorator角色配料
public abstract class Dosing implements IMilktea{IMilktea iMilktea;public Dosing(IMilktea iMilktea){this.iMilktea iMilktea;}Overridepublic void addDosing() {this.iMilktea.addDosing();}
}
具体装饰ConcreteDecorator角色
加珍珠
public class Pearl extends Dosing {public Pearl(IMilktea iMilktea) {super(iMilktea);}Overridepublic void addDosing() {super.addDosing();System.out.println(制作中加珍珠);}
}
加芒果
public class Mango extends Dosing {public Mango(IMilktea iMilktea) {super(iMilktea);}Overridepublic void addDosing() {super.addDosing();System.out.println(制作中加芒果);}
}
加柠檬
public class Lemon extends Dosing {public Lemon(IMilktea iMilktea) {super(iMilktea);}Overridepublic void addDosing() {super.addDosing();System.out.println(制作中加柠檬);}
}
加冰
public class Ice extends Dosing {public Ice(IMilktea iMilktea) {super(iMilktea);}Overridepublic void addDosing() {super.addDosing();System.out.println(制作中加冰);}
}客户端
public class Client {public static void main(String[] args) {System.out.println(服务员你好需要点什么呀);System.out.println(我: 一杯加芒果、加珍珠的珍珠奶茶一杯加柠檬、加冰的柠檬水);System.out.println(服务员好的。);PearlMilktea pearlMilktea new PearlMilktea();Pearl pearl new Pearl(pearlMilktea);Mango mango new Mango(pearl);Ice ice new Ice(mango);ice.addDosing();System.out.println(第一杯制作完成);LemonMilktea lemonMilktea new LemonMilktea();Lemon lemon new Lemon(lemonMilktea);Ice ice1 new Ice(lemon);ice1.addDosing();System.out.println(第二杯制作完成);System.out.println(我珍珠奶茶怎么加冰了);System.out.println(服务员对不起珍珠奶茶做错了重新给您做。);mango.addDosing();System.out.println(不加冰的珍珠奶茶制作完成);System.out.println(我好的谢谢);}
}
输出结果
服务员你好需要点什么呀
我: 一杯加芒果、加珍珠的珍珠奶茶一杯加柠檬、加冰的柠檬水
服务员好的。
开始制作珍珠奶茶
制作中加珍珠
制作中加芒果
制作中加冰
第一杯制作完成
开始制作柠檬水
制作中加柠檬
制作中加冰
第二杯制作完成
我珍珠奶茶怎么加冰了
服务员对不起珍珠奶茶做错了重新给您做。
开始制作珍珠奶茶
制作中加珍珠
制作中加芒果
不加冰的珍珠奶茶制作完成
我好的谢谢
到此女朋友喝到了秋天的第一杯奶茶。
应用场景
动态的增加对象的功能不能以派生子类的方式来扩展功能限制对象的执行条件参数控制和检查等