码云地址地址: design_patterns
装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
来看看装饰器模式的具体应用
首先定义手机接口
public interface Phone {
void call();
}
手机接口实现类
public class IPhoneX implements Phone{
@Override
public void call() {
System.out.println("张三来电...");
}
}
public static void main(String[] args) {
Phone phone = new IPhoneX();
phone.call();
}
执行结果
张三来电...
这是常见的手机来电提示需求,假如用户要求来电前手机要有彩铃, 改如何实现?
聪明的你肯定瞬间就想到了答案, 给IPhoneX 添加一个子类对象, 重写来电方法即可代码片段如下
public class IphoneXX extends IPhoneX{
public void playMusic(){
System.out.println("一段优美的音乐响起~");
}
@Override
public void call() {
playMusic();
super.call();
}
}
public static void main(String[] args) {
Phone phone = new IphoneXX();
phone.call();
}
输出结果
一段优美的音乐响起~
张三来电...
大功告成。但是现在又来了新的需求, 要求来点时不但有铃声, 还有震动。这个时候再来一层继承, 子子孙孙无穷尽也。这个时候今天的主角装饰器模式闪亮登场。
装饰器核心抽象类
public abstract class PhoneDecorator implements Phone{
private final Phone phone;
PhoneDecorator(Phone phone){
this.phone = phone;
}
@Override
public void call() {
phone.call();
}
}
装饰器的实现类, 继承装饰器抽象类, 扩展phone的方法
public class IphoneXWrap extends PhoneDecorator{
IphoneXWrap(Phone phone) {
super(phone);
}
@Override
public void call() {
System.out.println(">>>手机开始震动<<<");
super.call();
}
}
public static void main(String[] args) {
Phone phoneX = new IPhoneX();
phoneX.call();
System.out.println("----------");
Phone phoneXx = new IphoneXX();
phoneXx.call();
System.out.println("----------");
Phone iphoneXWrap = new IphoneXWrap(phoneXx);
iphoneXWrap.call();
}
输出结果
张三来电...
----------
一段优美的音乐响起~
张三来电...
----------
>>>手机开始震动<<<
一段优美的音乐响起~
张三来电...
所谓装饰器模式, 即抽象类持有目标对象的引用, 使抽象子类可以动态扩展目标对象的行为。装饰器模式只有在运行时进行需求扩充即可, 符合开闭原则。避免继承带来的类冗余问题。说到这里, 小伙伴们肯定想起了另一种设计模式-代理模式,接下来我们简单的介绍一下静态代理。
代理模式
为其他对象提供一种代理以便控制对这个对象的访问。
从图中可以看出,代理接口(Subject)、代理类(ProxySubject)、委托类(RealSubject)形成一个“品”字结构。
首先继承iphone接口, 实现代理类
public class PhoneProxy implements Phone{
PhoneProxy(){
this.phoneX = new IPhoneX();;
}
private final IPhoneX phoneX;
public void playMusic(){
System.out.println("一段优美的音乐响起~");
}
@Override
public void call() {
System.out.println(">>>手机开始震动<<<");
phoneX.call();
playMusic();
}
public static void main(String[] args) {
PhoneProxy phoneProxy = new PhoneProxy();
phoneProxy.call();
}
}
结果
>>>手机开始震动<<<
张三来电...
一段优美的音乐响起~
看到这里眼尖的小伙伴不禁脱口而出你这不是玩我吗?这就叫静态代理?emmm…没错, 这就是静态代理。之所以要放到一起就是因为这两个模式实在是太像太像,引用网友总结两者的区别(原文地址)。
装饰器模式强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你,只不过能力更强了而已;代理模式强调要让别人帮你去做一些本身与你业务没有太多关系的职责(记录日志、设置缓存)。代理模式是为了实现对象的控制,因为被代理的对象往往难以直接获得或者是其内部不想暴露出来。
装饰模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案;代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用;
装饰模式是为装饰的对象增强功能;而代理模式对代理的对象施加控制,但不对对象本身的功能进行增强;
本文部分定义参考了网上博文和网上信息…