Decorator Design Pattern(装饰器模式)

装饰器模式常常用来动态的为已存在的类增加功能或者改变功能,而不用对原有类进行任何修改以造成对现有代码的影响。

比如,我们现在有一个订票功能OrderTicket。但是我们打算给他增加一些功能,比如订票之后发短信通知,或者发邮件通知。

听起来,似乎使用继承就能实现这个目标了。比如我们增加两个子类分别是SendMsgAfterOrderTicket(订票之后发短信),和SendEmailAfterOrderTicket(订票之后发邮件)。

这样我们调用相应的子类,覆盖父类的订票方法,在订票之后发送短信或者邮件。

但是如果我们需要既发送短信又发送邮件呢?如果在增加一个自动推送手机APP消息呢?如果希望只是选择性的选择其中的一种或者两种或者全部的通知呢?

继承的方式势必会造成混乱。如果通知方式更多,则更不用说了。

这就是装饰器模式显示作用的地方了:

请看代码:


package dp.decorator;

public interface OrderTicket{
	public void placeOrder();
}
package dp.decorator;

public class OrderTicketImpl implements OrderTicket {

	@Override
	public void placeOrder() {
		System.out.println("订了一张票");
	}

}
package dp.decorator;

public class SendEmailAfterOrderTicket implements OrderTicket {

	protected OrderTicket orderTicket;

	public SendEmailAfterOrderTicket(OrderTicket orderTicket) {
		this.orderTicket = orderTicket;
	}

	@Override
	public void placeOrder() {
		orderTicket.placeOrder();
		System.out.println("发送电子邮件");
	}

}
package dp.decorator;

public class SendMsgAfterOrderTicket implements OrderTicket {

	protected OrderTicket orderTicket;

	public SendMsgAfterOrderTicket(OrderTicket orderTicket) {
		this.orderTicket = orderTicket;
	}

	@Override
	public void placeOrder() {
		orderTicket.placeOrder();
		System.out.println("发送消息");
	}

}
package dp.decorator;

public class SendNotificationAfterOrderTicket implements OrderTicket {

	protected OrderTicket orderTicket;

	public SendNotificationAfterOrderTicket(OrderTicket orderTicket) {
		this.orderTicket = orderTicket;
	}

	@Override
	public void placeOrder() {
		orderTicket.placeOrder();
		System.out.println("推送通知");
	}

}
package dp.decorator;

public class Main {
	public static void main(String args[]) {
		OrderTicket orderTicket = new OrderTicketImpl();
		System.out.println("------");
		orderTicket.placeOrder();

		OrderTicket sendEmailAfterOrderTicket = new SendEmailAfterOrderTicket(
				orderTicket);
		System.out.println("------");
		sendEmailAfterOrderTicket.placeOrder();

		OrderTicket sendMsgAfterOrderTicket = new SendMsgAfterOrderTicket(
				orderTicket);
		System.out.println("------");
		sendMsgAfterOrderTicket.placeOrder();

		OrderTicket sendNotificationAfterOrderTicket = new SendNotificationAfterOrderTicket(
				orderTicket);
		System.out.println("------");
		sendNotificationAfterOrderTicket.placeOrder();

		OrderTicket sendEmailThenNotificationAfterOrderTicket = new SendNotificationAfterOrderTicket(
				new SendEmailAfterOrderTicket(orderTicket));
		System.out.println("------");
		sendEmailThenNotificationAfterOrderTicket.placeOrder();

		OrderTicket sendEmailThenNotificationThenMsgAfterOrderTicket = new SendMsgAfterOrderTicket(
				new SendNotificationAfterOrderTicket(
						new SendEmailAfterOrderTicket(orderTicket)));
		System.out.println("------");
		sendEmailThenNotificationThenMsgAfterOrderTicket.placeOrder();
	}
}



运行结果:

------
订了一张票
------
订了一张票
发送电子邮件
------
订了一张票
发送消息
------
订了一张票
推送通知
------
订了一张票
发送电子邮件
推送通知
------
订了一张票
发送电子邮件
推送通知
发送消息



从代码和结果我们可以看出,我们可以在不对原来的类进行任何改变的前提下,增加新的功能,然后还可以根据需要选择所增加的新功能,以及选择新功能的执行顺序,让代码之间的耦合降到最低。

转载于:https://my.oschina.net/nox/blog/489111

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值