记一次简单装饰模式尝试

今天学习了装饰模式,但是对于最后的输出结果一直都不是很明白,直到和同事讨论了许久,才大概理清了思路,所以做一下简单的记录

首先们创建一个接口类,定义一个方法,代码如下:

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”,这就是最后的输出来源。下面有张图可以帮助理解这一个过程

原文地址:https://www.cnblogs.com/aierben/p/14490302.html