Java设计模式之装饰者模式详解
什么是装饰者模式?
装饰者模式又叫包装模式,它是一种结构型设计模式。装饰者模式可以在运行时给对象动态添加一些额外的职责,而不影响该对象的行为。其实我们在生活中也经常使用到装饰者模式,比如将一个普通房间粉刷成卧室或客厅,这样就给房间添加了额外的功能,而且不会影响原有房间的结构和功能。
装饰者模式的角色和实现方式
装饰者模式有如下角色:
抽象构件(Component):定义一个抽象接口,用于规范具体构件和装饰对象的行为。
public interface Component {
void operation();
}
具体构件(ConcreteComponent):实现抽象构件接口的类,也可以称作被装饰器装饰的对象。
public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("执行ConcreteComponent的操作");
}
}
装饰者(Decorator):实现抽象构件(Component)接口的类,并持有一个抽象构件(Component)的引用,用于装饰具体构件的功能。
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
具体装饰者(ConcreteDecorator):实现装饰者(Decorator)接口,具体实现装饰者需要扩展Component功能的方法,同时还包含被装饰对象ConcreteComponent。
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
addBehavior();
}
private void addBehavior() {
System.out.println("装饰添加的行为");
}
}
装饰者模式的示例
示例1:给文本添加加粗和颜色功能
现在我们需要在文本中添加加粗和颜色的功能,我们可以使用装饰者模式,具体步骤如下:
- 首先定义抽象构件:文本Component。
public interface TextComponent {
void draw();
}
- 定义具体构件:普通文本ConcreteText。
public class ConcreteText implements TextComponent {
private String text;
public ConcreteText(String text) {
this.text = text;
}
@Override
public void draw() {
System.out.print(text);
}
}
- 定义装饰者Decorator:所有装饰器的父类,和Component相同的接口。
public abstract class Decorator implements TextComponent {
private TextComponent component;
public Decorator(TextComponent component) {
this.component = component;
}
@Override
public void draw() {
component.draw();
}
}
- 定义具体装饰者ConcreteDecorator:实现具体装饰效果。
public class BoldDecorator extends Decorator {
public BoldDecorator(TextComponent component) {
super(component);
}
@Override
public void draw() {
System.out.print("<b>");
super.draw();
System.out.print("</b>");
}
}
public class ColorDecorator extends Decorator {
private String color;
public ColorDecorator(TextComponent component, String color) {
super(component);
this.color = color;
}
@Override
public void draw() {
System.out.print("<font color=\"" + color + "\">");
super.draw();
System.out.print("</font>");
}
}
- 最后使用装饰者来给文本添加加粗和颜色的功能。
TextComponent text = new ConcreteText("Hello World!");
TextComponent boldText = new BoldDecorator(text);
TextComponent boldRedText = new ColorDecorator(boldText, "red");
boldRedText.draw();
上述代码会输出:
<b><font color="red">Hello World!</font></b>
示例2:给订单添加促销折扣功能
假设我们有一个订单,现在需要为订单添加促销折扣的功能,我们仍然可以使用装饰者模式,具体步骤如下:
- 定义抽象构件:订单Component。
public interface OrderComponent {
double calcCost(); //计算订单费用
}
- 定义具体构件:普通订单ConcreteOrder。
public class ConcreteOrder implements OrderComponent {
private double cost;
public ConcreteOrder(double cost) {
this.cost = cost;
}
@Override
public double calcCost() {
return cost;
}
}
- 定义装饰者Decorator:所有装饰器的父类,和Component相同的接口。
public abstract class Decorator implements OrderComponent{
private OrderComponent order;
public Decorator(OrderComponent order) {
this.order = order;
}
@Override
public double calcCost() {
return order.calcCost();
}
}
- 定义具体装饰者ConcreteDecorator:实现具体装饰效果。
public class DiscountDecorator extends Decorator {
private double discount;
public DiscountDecorator(OrderComponent order, double discount) {
super(order);
this.discount = discount;
}
@Override
public double calcCost() {
return super.calcCost() * discount;
}
public void setDiscount(double discount) {
this.discount = discount;
}
}
public class GiftDecorator extends Decorator {
private String giftName;
public GiftDecorator(OrderComponent order, String giftName) {
super(order);
this.giftName = giftName;
}
@Override
public double calcCost() {
double cost = super.calcCost();
System.out.println("送一份" + giftName);
return cost;
}
}
- 最后使用装饰者来给订单添加促销折扣的功能。
OrderComponent order = new ConcreteOrder(100);
OrderComponent discountOrder = new DiscountDecorator(order, 0.8);
OrderComponent giftOrder = new GiftDecorator(discountOrder, "优惠券");
double cost = giftOrder.calcCost();
System.out.println("订单总费用:" + cost);
上述代码会输出:
送一份优惠券
订单总费用:80.0
总结
在需求变化较多或需要动态添加额外功能的情况下,装饰者模式是一种很好的设计模式。但是,由于装饰者模式增加了很多小对象,过度使用也会导致程序变得复杂。在实践中,我们应该根据具体的情况来决定是否使用装饰者模式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之java装饰者模式详解 - Python技术站