Java实现装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许我们动态地将行为添加到某个对象中,而不是通过继承来实现。它是在保持类方法签名不变的情况下增加功能,实现类的功能扩展。
角色介绍
- Component:抽象组件,定义装饰者和被装饰者的最基本的接口和规范。
- ConcreteComponent:具体组件,也是被装饰器装饰的基本对象,实现抽象组件中的方法。
- Decorator:抽象装饰器,实现了Component接口,并且持有一个被装饰者的引用。旨在为后续的具体装饰器提供代理或者委托相应的行为扩展。
- ConcreteDecorator:具体装饰器,继承Decorator,重写接口中的方法,完成相应的装饰逻辑。
示例1:文字消息发送功能
我们需要设计一个具有文字消息发送能力的聊天应用,但是仅仅有文字消息发送的聊天,显然这个应用并不太好用。所以,我们需要实现添加表情和图片消息的功能。
我们可以将文字消息发送功能抽象为一个Component类,即AbstractMessageSender类,然后定义三个装饰器:EmoticonMessageSender、PictureMessageSender和RedPacketMessageSender,分别用于装饰Component类,实现添加表情、图片和红包消息的功能。
public abstract class AbstractMessageSender {
public abstract void sendMessage();
}
public class TextMessageSender extends AbstractMessageSender {
@Override
public void sendMessage() {
System.out.println("发送了一条文字消息");
}
}
public abstract class MessageSenderDecorator extends AbstractMessageSender {
protected AbstractMessageSender messageSender;
public MessageSenderDecorator(AbstractMessageSender messageSender) {
this.messageSender = messageSender;
}
public void sendMessage() {
messageSender.sendMessage();
}
}
public class EmoticonMessageSender extends MessageSenderDecorator {
public EmoticonMessageSender(AbstractMessageSender messageSender) {
super(messageSender);
}
@Override
public void sendMessage() {
super.sendMessage();
System.out.println("带有表情的消息");
}
}
public class PictureMessageSender extends MessageSenderDecorator {
public PictureMessageSender(AbstractMessageSender messageSender) {
super(messageSender);
}
@Override
public void sendMessage() {
super.sendMessage();
System.out.println("带有图片的消息");
}
}
public class RedPacketMessageSender extends MessageSenderDecorator {
public RedPacketMessageSender(AbstractMessageSender messageSender) {
super(messageSender);
}
@Override
public void sendMessage() {
super.sendMessage();
System.out.println("带有红包的消息");
}
}
使用示例代码:
AbstractMessageSender textMessageSender = new TextMessageSender();
textMessageSender = new EmoticonMessageSender(textMessageSender);
textMessageSender = new PictureMessageSender(textMessageSender);
textMessageSender = new RedPacketMessageSender(textMessageSender);
textMessageSender.sendMessage();
运行结果为:
发送了一条文字消息
带有表情的消息
带有图片的消息
带有红包的消息
示例2:饮料点单系统
我们现在要实现一个简单的点单系统,基础饮料有红茶、绿茶和奶茶,但是用户可以选择加入椰果、芋头、珍珠等等不同口味的配料。这些配料是新增的,我们不希望因为新的加入而修改原本的代码,更好的方法是采用装饰器模式。
我们定义一个抽象类Beverage,表示基础饮料。具体的基础饮料类RedTea、GreenTea和MilkTea实现Beverage接口,然后配料类可以继承或实现Beverage接口,形成装饰器类Milk、Pearl、Coconut等。
public abstract class Beverage {
protected String name;
public String getName() {
return name;
}
public abstract double cost();
}
public class RedTea extends Beverage {
public RedTea() {
super.name = "红茶";
}
public double cost() {
return 10;
}
}
public class GreenTea extends Beverage {
public GreenTea() {
super.name = "绿茶";
}
public double cost() {
return 8;
}
}
public class MilkTea extends Beverage {
public MilkTea() {
super.name = "奶茶";
}
public double cost() {
return 12;
}
}
public abstract class CondimentDecorator extends Beverage {
protected Beverage beverage;
public abstract String getName();
public CondimentDecorator(Beverage beverage) {
this.beverage = beverage;
}
}
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
super(beverage);
}
public String getName() {
return beverage.getName() + " 加牛奶";
}
public double cost() {
return 2.5 + beverage.cost();
}
}
public class Pearl extends CondimentDecorator {
public Pearl(Beverage beverage) {
super(beverage);
}
public String getName() {
return beverage.getName() + " 加珍珠";
}
public double cost() {
return 3.5 + beverage.cost();
}
}
public class Coconut extends CondimentDecorator {
public Coconut(Beverage beverage) {
super(beverage);
}
public String getName() {
return beverage.getName() + " 加椰果";
}
public double cost() {
return 3 + beverage.cost();
}
}
使用示例代码:
Beverage redTea = new RedTea();
System.out.println(redTea.getName() + ",价格:" + redTea.cost());
Beverage milkWithGreenTea = new Milk(new GreenTea());
System.out.println(milkWithGreenTea.getName() + ",价格:" + milkWithGreenTea.cost());
Beverage pearlWithMilkTea = new Pearl(new MilkTea());
System.out.println(pearlWithMilkTea.getName() + ",价格:" + pearlWithMilkTea.cost());
Beverage coconutWithGreenWithMilkTea = new Coconut(new Milk(new GreenTea()));
System.out.println(coconutWithGreenWithMilkTea.getName() + ",价格:" + coconutWithGreenWithMilkTea.cost());
运行结果为:
红茶,价格:10.0
绿茶 加牛奶,价格:10.5
奶茶 加珍珠 加牛奶,价格:18.5
绿茶 加牛奶 加椰果,价格:13.5
总结
装饰器模式通过组合的方式,动态地实现增加属性和功能,同时也保证了被装饰器装饰的原对象不会被修改,这种方式增强扩展性更好。但是如果装饰器的嵌套层数过深,可能会影响代码阅读的效率。在设计模式的选择上,应根据具体的需求和情况来进行考虑。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java实现装饰器模式(Decorator Pattern) - Python技术站