今天学习了装饰模式,但是对于最后的输出结果一直都不是很明白,直到和同事讨论了许久,才大概理清了思路,所以做一下简单的记录
首先们创建一个接口类,定义一个方法,代码如下:
package zhaungshi; public interface Phone { void call(); }
新建一个一实现类,实现该方法
package zhaungshi; public class basePhone implements Phone { @Override public void call() { System.out.println("打电话base"); } }
现在我们就可以拿到装饰类需要装饰的对象
package zhaungshi; public abstract class SmartPhone implements Phone { Phone p = null; public SmartPhone() { // TODO Auto-generated constructor stub } public SmartPhone(Phone phone) { this.p = phone; } public Phone getp() { return p; } @Override public void call() { p.call(); } }
SmartPhone 中存在一个Phone 对象,并且调用的Call方法都是调用的 Phone 的 call 方法。
然后我们新建两个加强的装饰类,向call方法添加功能,分别如下:
package zhaungshi; //加强的装饰类1 public class zhuangshiPhone extends SmartPhone { public zhuangshiPhone(Phone p) { super(p); } public Phone getp() { return super.p; } public void call() { super.call(); changeColor(); } public void changeColor() { System.out.println("red"); } } //加强的装饰类2 package zhaungshi; public class zhuangshiPhone2 extends SmartPhone { public zhuangshiPhone2(Phone p) { super(p); } public Phone getp() { return super.p; } public void call() { super.call(); changeSize(); } public void changeSize() { System.out.println("size"); } }
此时我们就创建完成了所有的类与接口对象,下面我们进行测试,首先执行下面这行
package zhaungshi; public class zhuangshiTest { public static void main(String[] args) { Phone p = new basePhone(); p.call(); SmartPhone zs1 = new zhuangshiPhone(p); zs1.call(); } } //输出结果是 打电话base 打电话base red
这个过程大家应该都能看得明白,并且此时的 call 方法已经是增强的 call 方法,然后我们执行下面这个例子
package zhaungshi; public class zhuangshiTest { public static void main(String[] args) { Phone p = new basePhone(); p.call(); SmartPhone sp = new zhuangshiPhone2(new zhuangshiPhone(p)); sp.call(); // } } //输出结果 打电话base 打电话base red size
第一次输出的打电话nase是 p.call的调用结果。而第二次的输出是 sp.call 的调用结果。我的疑问也是来自于这里,为什么打电话base只调用了一次,后来经过分析发现,第二次输出的 打电话base 是 newzhuangshi Phone(p)这个对象调用产生的,我们可以看一下zhaungshiPhone2 的 call方法,在这个方法里面,他调用的是父类,也就是SmartPhone的 call 方法,而父类的方法调用的 父类构造函数传入参数的 call 方法,也就是说,此时 new zhuangshiPhone2 调用的是参数对象的 call 方法,而该对象的参数恰好是 new zhuangshiPhone(p)这个对象,这个对象的 call 也是增强的 call ,然后重复上一次过程,输出“打电话base”和“red” ,该过程结束后 zhuangshiPhone2 这个对象继续调用自己的 call 方法的剩余部分 ,然后输出“size”,这就是最后的输出来源。下面有张图可以帮助理解这一个过程