装饰者模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
介绍
动态地给一个对象添加额外的职责,同时不改变其结构。装饰器模式提供了一种灵活的替代继承方式来扩展功能。
主要解决的问题
- 避免通过继承引入静态特征,特别是在子类数量急剧膨胀的情况下。
- 允许在运行时动态地添加或修改对象的功能。
使用场景
- 当需要在不增加大量子类的情况下扩展类的功能。
- 当需要动态地添加或撤销对象的功能。
实现方式
- 定义组件接口:创建一个接口,规定可以动态添加职责的对象的标准。
- 创建具体组件:实现该接口的具体类,提供基本功能。
- 创建抽象装饰者:实现同样的接口,持有一个组件接口的引用,可以在任何时候动态地添加功能。
- 创建具体装饰者:扩展抽象装饰者,添加额外的职责。
实现
NotityDataSource:一个组件接口,通知数据源
AccountNotityDataSource:该接口(NotityDataSource)的具体组件
NotifyDataDecorator:抽象类装饰者,实现该接口(NotityDataSource)
SMSNotifyDataDecorator:具体装饰者,继承抽象类装饰者
QQNotifyDataDecorator:具体装饰者,继承抽象类装饰者
WeChatNotifyDataDecorator:具体装饰者,继承抽象类装饰者
类结构图:
NotityDataSource
1 2 3 4 5
| public interface NotifyDataSource { void send(String mes , Map<String ,String> props);
void callBack(); }
|
AccountNotityDataSource
1 2 3 4 5 6 7 8 9 10 11 12
| public class AccountNotifyDataSource implements NotifyDataSource { @Override public void send(String mes , Map<String ,String> props) { System.out.println("消息已发送"); }
@Override public void callBack() { System.out.println("消息发送成功"); } }
|
NotifyDataDecorator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public abstract class NotifyDataDecorator implements NotifyDataSource { private NotifyDataSource notifyDataSource;
public NotifyDataDecorator(NotifyDataSource notifyDataSource) { this.notifyDataSource = notifyDataSource; }
@Override public void send(String mes, Map<String, String> props) { notifyDataSource.send(mes ,props); }
@Override public void callBack() { notifyDataSource.callBack(); } }
|
SMSNotifyDataDecorator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class SmsNotifyDataDecorator extends NotifyDataDecorator { public SmsNotifyDataDecorator(NotifyDataSource notifyDataSource) { super(notifyDataSource); }
@Override public void send(String mes, Map<String, String> props) { String deviceId = props.get("deviceId"); System.out.printf("设备ID:%s SMS消息发送成功\n" ,deviceId); super.send(mes, props); }
@Override public void callBack() { System.out.println("SMS消息发送成功"); } }
|
使用方式
demo示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package decorator.my;
import java.util.HashMap; import java.util.Map;
public class Demo { public static void main(String[] args) { Map<String ,String> props = new HashMap<>(); props.put("qq" ,"14645701009"); props.put("wx" ,"123456"); props.put("deviceId" ,"1234567890");
NotifyDataDecorator ways = new QQNotifyDataDecorator(new WechatNotifyDataDecorator(new SmsNotifyDataDecorator(new AccountNotifyDataSource())));
ways.send("你好啊" ,props); } }
|
demo结果
1 2 3 4 5 6
| qq: 14645701009 发送成功 qq消息发送成功 wx: 123456 消息发送成功 wx消息发送成功 设备ID:1234567890 SMS消息发送成功 消息已发送
|