装饰模式的理解

目前有这么个场景:三个继承关系Father,Son,GrandSon三个类,我要再Son类上增强一些功能怎么办?我想项目过程中,如果你是后来者,那么你免不了修改别人的代码。如果初期你对那些代码不知所云,但目前又急需修改功能,难道你真决定在Son类上大动手脚,我想你没那么牛叉,至少我对那些功能点的修改就有点畏首畏尾,毕竟前期代码不是我写,稍微修改,意想不到的错误无法预料。不允许,对了,为什么呢?你增强的功能是修改Son类中的方法吗?增加方法吗 ?对GrandSon的影响哪?如果GrandSon有多个的情况,你怎么办?这个评估的工作量就是够你受的,所以这个是不允许的,那还是要解决问题的呀,怎么办?这里就可以用着装饰模式了。

装饰模式主要用于对已有功能动态地添加功能的一种方式。通过对对象进行包装,使得装饰对象的实现和对象进行分离,从而装饰对象只需要关心自己的功能,而不需要关心如何添加到对象链中。这样做就是为了有效地把类的核心职责和装饰功能区分开来,但要注意地是,装饰模式的顺序非常重要。下面就用代码对上面场景进行模拟:

Father

/**

 * @author lw 父亲类方法有a b c三种方法,其中c是抽象方法。

 */

public abstract class Father {

    public void a() {

       System.out.println("Father a函数!");

    };

    public void b() {

       System.out.println("Father b函数!");

    };

    public abstract void c();

}

Father

/**

 * @author lw

 * 儿子继承父亲,重写父亲的抽象方法c

 */

public class Son1 extends Father {

 

    @Override

    public void c() {

       System.out.println("Son1 C函数重写!");

    }

 

    @Override

    public void b() {   //需要对b的方法进行扩展

       System.out.println("override Son1's b function()");

    }

}

在这里GrandSon1的代码就不做模拟,假设Son1b方法进行修改,将影响到其子类的功能实现。此时需要对Son1b方法功能进行扩展,其中扩展的功能代码是核心代码,所以我把它先拿到外面搁置起来,并对其进行装饰。

装饰类Decorator

public abstract class Decorator extends Father{

 

    private Father father;

   

    protected Decorator(Father father){

       this.father=father;

    }

   

    public void b(){

       if(father!=null){

           father.b();

       }

    }

   

    @Override

    public void c() {

       System.out.println("重写C函数");

    }

}

Decorator1Impl

public  class Decorator1Impl extends Decorator{

    public Decorator1Impl(Father father){

       super(father);

    }

    public void b(){

       super.b();

       System.out.println("装饰模式下的b 1方法");

    }

}

Decorator2Impl

public  class Decorator2Impl extends Decorator{

    public Decorator2Impl(Father father){

       super(father);

    }

   

    public void b(){

       super.b();

       System.out.println("装饰模式下的b 2方法");

    }

}

调用类:

public class Client {

    public static void main(String[] args) {

       Father f;

       f = new Son1();

       Father f1=new Decorator1Impl(f);

       Father f2=new Decorator2Impl(f1);

       f2.b();

    }

}

运行的结果为:

override Son1's b function()

装饰模式下的b 1方法

装饰模式下的b 2方法

 

如果某一天,你觉得这个调用顺序需要更改,到时只需要更改装饰模式下的接口实现就能完成程序的扩展。或者某天你需要继续对该功能进行扩充,到时只需要继续写接口实现类即可。但是对于装饰模式千万要注意其顺序。



 

装饰模式是对继承的有力补充。在项目开发实施过程中,将要考虑系统的易维护、易扩展、易复用等情况,但继承是静态地给类增加功能,如果用继承解决的话,将会增加很多类,灵活性也会变差。而装饰模式有非常好的优点,扩展性比较好。在系统开发过程中,需求的变更我想这是永远也改变不了的现实,装饰模式可以提供很好的帮助。通过重新封装一个类,而不是通过继承去实现,这样对原程序没有变更,但通过扩充很好地完成了功能的增强。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值