Android装饰者模式学习笔记(2)

来源:互联网 发布:杭州云计算产业园 编辑:程序博客网 时间:2024/05/23 05:08

Android装饰者模式学习笔记(2)

Android装饰者模式学习笔记(1)

1接着上一篇来,先说疑问1
我们这么做只能实现AXXX模式,假如我想实现XXXX模式怎么做,例如DCBA?A类一定要作为最后收尾的类吗,如果不是,该怎么改?

其实我们上一篇说必须用A来收尾,是因为A是无参构造函数,而BCD都需要一个参数,所以如果想改成输出DCBA,我们需要把A加一个带参构造函数,这个没问题(加构造函数没问题,但是代码逻辑会出问题,因为A没继承Decorate类)
但是,我们还需要把BCD加一个无参构造函数,但因为BCD的父类Decorate是带参构造函数,所以BCD无法添加无参构造函数
而如果我们把Decorate的带参构造函数拿掉,。。。。那代码就乱了,也就不是装饰者模式了吧

所以我个人认为:在这个情景里,装饰者模式只能做到AXXX模式而无法做到XXXX模式,即A类一定要作为收尾的类(如有不同意见欢迎回复)

疑问2
A类是不是被装饰者,如果不是,到底谁是被装饰者?

我个人认为A类是被装饰者,因为像我考虑疑问1一样,A不是Decorate的子类,无法通过写带参构造函数的方式来让A像BCD一样可以接受同类型的变量,A只能用来收尾,所以A是被装饰者

疑问3
装饰者类BCD,如果不重写output方法,代码也不会报错,因为他们的父类已经重写过了,那执行结果会是什么呢,为什么呢?
先看我们最初的写法

Decorate decorate = new D(new C(new B(new A())));System.out.println(decorate.outPut());

结果是ABCD
现在我把B类的output方法屏蔽掉

public class B extends Decorate {//这里通过继承Decorate类,而Decorate类实现I接口来间接完成B实现I接口    public B(I i) {//因为父类构造函数带参,所以这里也得写        super(i);    }//    @Override//    public String outPut() {//这个如果不重写,会有什么影响,代码的执行情况是什么样的,后续研究//        return i.outPut() + "B";//    }}

结果是ACD
为什么是ADC呢,我们还是看Decorate decorate = new D(new C(new B(new A())));
(1)肯定是先执行A的output,输出一个A
(2)然后执行B的output,但是B没重写,所以肯定执行的是父类的output方法,
父类的output方法写的是return i.outPut();
这个i是谁,我觉得就应该是B的参数,B的参数是A,也就是A.output,
所以又输出了一遍A(这里是又输出了一遍而不是又输出了一个,所以到目前为止还是A,而不是AA,这里我想了略长时间)(这里有点只可意会不可言传的感觉,但我已经尽量描述的准确了)
(3)然后执行C的output,也就是之前的A + C
(4)D也同理

所以结论就是如果不重写扩展方法,那么就会在执行一遍 被装饰者的方法(如有不同意见欢迎回复)

疑问4
可不可以不创建装饰者父类,仅依靠BCD实现I接口能不能完成扩展呢?
能完成扩展,但是应该就不符合装饰者模式了,先看改变后的代码,BCD还是之前的三个类,我把代码放到一个代码块里了

public class B implements I {    I i;    public B(I i) {        this.i = i;    }    @Override    public String outPut() {        return i.outPut() + "B";    }}public class C implements I {    I i;    public C(I i) {        this.i = i;    }    @Override    public String outPut() {        return i.outPut() + "C";    }}public class D implements I{    I i;    public D(I i) {        this.i = i;    }    @Override    public String outPut() {        return i.outPut() + "D";    }}
public class Test {    public static void main(String[] args) {        I decorate = new D(new C(new B(new A())));//只是这里把之前的Decorate类换成了I类型        System.out.println(decorate.outPut());    }}

输出结果依然是ABCD, 但是没了装饰者父类之后,出现了几个问题
1代码重复了,每个子类都要定义一个I i,变得麻烦了
2如果我在想扩展新功能,比如输出“1234”,由于没有父类,扩展起来相对麻烦,而且也犯了1的错误
3不符合装饰者模式
所以还是写一个装饰者父类比较好,这就是关于上一篇博客留下的疑问的思考,全是个人理解,如有不对,欢迎在评论里讨论。

原创粉丝点击