首页 / 设计模式 / 设计模式:装饰者模式
设计模式:装饰者模式
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了设计模式:装饰者模式,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3485字,纯文字阅读大概需要5分钟。
内容图文
![设计模式:装饰者模式](/upload/InfoBanner/zyjiaocheng/1306/f5f99e630be449a38c2e329137a6e9d7.jpg)
我们都知道,可以使用两种方式给一个类或者对象添加行为。
一是使用继承。继承是给一个类添加行为的比较有效的途径。通过使用继承,可以使得子类在拥有自身方法的同时,还可以拥有父类的方法。但是使用继承是静态的,在编译的时候就已经决定了子类的行为,我们不便于控制增加行为的方式和时机。
二是使用关联。组合即将一个对象嵌入到另一个对象中,由另一个对象来决定是否引用该对象来扩展自己的行为。这是一种动态的方式,我们可以在应用程序中动态的控制。
与继承相比,关联关系的优势就在于不会破坏类的封装性,且具有较好的松耦合性,可以使系统更加容易维护。但是它的缺点就在于要创建比继承更多的对象。
一、基本定义
装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。
<h1;">二、模式结构装饰者模式UML结构图。
Component: 抽象构件。是定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent:具体构件。是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator: 抽象装饰类。是装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator存在的。
ConcreteDecorator:具体装饰类,起到给Component添加职责的功能。
三、实现装饰者模式
结构图如下:
装饰者模式提供了一个比较好的解决方案 。
编码实现:
public abstract class Beverage {
protected String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
四个组件:HouseBlend.java
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
DarkRoast.java
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "DarkRoast";
}
@Override
public double cost() {
return 1.05;
}
}
Espresso.java
public class DarkRoast extends Beverage {
public DarkRoast(){
description = "DarkRoast";
}
@Override
public double cost() {
return 1.05;
}
}
CondimentDecorator.java
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
Milk.java
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " , Milk";
}
@Override
public double cost() {
return beverage.cost() + 0.3;
}
}
Mocha.java
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " , Mocha";
}
@Override
public double cost() {
return beverage.cost() + 0.20;
}
}
Soy.java
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + " , Soy";
}
@Override
public double cost() {
return beverage.cost() + 0.10;
}
}
测试程序
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage = new HouseBlend();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Soy(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
}
}
测试结果
HouseBlend $0.89 DarkRoast , Mocha , Mocha , Soy $1.55
四、模式的优缺点
优
1、装饰者模式可以提供比继承更多的灵活性
2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
缺点
1、会产生很多的小对象,增加了系统的复杂性
2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
五、模式的适用场景
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
六、总结
1、 组合和委托可以在运行时动态的添加新的行为,而继承是静态的,在系统编译时就已经决定了对象的行为。
2、装饰者模式意味着一群装饰者类,这些类用来包装具体组件
3、装饰者可以在被装饰者的行为前面或者后面加上自己的行为,甚至可以将被装饰者的行为整个取代掉,从而达到特定的目的。
4、可以用多个装饰者包装一个组件。
5、装饰者一般对于组件的客户是透明的,除非客户程序依赖于组件的具体类型。
6、装饰者会导致设计中出现许多的小对象,如果过度的使用,会让系统变得更加复杂。
7、装饰者和被装饰者对象有相同的超类型。
内容总结
以上是互联网集市为您收集整理的设计模式:装饰者模式全部内容,希望文章能够帮你解决设计模式:装饰者模式所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。