设计模式_03 装饰模式

  1. 什么是设计模式?有啥用?
     设计模式一套代码设计的经验总结,通俗点来说就像是个语文考试中的作文模板,能够轻松解决一类问题。很多时候在项目中运用设计模式,能够轻松地解决很多问题。

  2. 使用装饰模式的目的是什么?
     使用装饰模式的目的是在不改变原类文件代码和使用继承的情况下,动态地扩展一个对象的功能。通过创建一个包装对象,我们称之为装饰,用来包裹真实的对象。

  3. 装饰模式存在的意义?
     但凡是初学者都知道,如果想要增加一个对象的功能,可以通过继承来增加该对象的功能。
    但是如果我们想要增加的对象已经继承了呢?Java是不直接支持多继承的,在这种情况下,我们我们还有什么选择?
     在这种情况下,我们还能选择让该对象实现接口,以此来增加对象的功能。因为java是支持多实现的。但是如果我们不想改变源文件的代码,想要动态地给对象增删功能呢?

 这时候我们只能通过装饰模式来完成这个目的。
4 . 装饰模式的步骤
 1. 装饰对象和真实对象必须要有相同的接口或者继承同一个父类。
 2. 装饰对象必须持有(包含)一个真实对象的引用。
 3. 装饰对象重写方法,进行功能,然后将请求转发给真实对象。这样确保了在运行时,不用修改给真实对象的结构,就可以在外部增强附加的功能。

5 . 为什么装饰对象和真实对象(也即被装饰对象)必须要有相同的接口?
 因为装饰对象要保证持有一个能用的真实对象的引用,而这个接口必须是要有你准备进行功能增强的核心代码所在的类。这样才能保证修饰对象能够通过以下代码接收到所继承的接口的类型。

public void Decorator (Component component){
    this.component = component;
}

因为真实对象是继承该接口的,这样能够通过向上转型,直接用真实对象的来当component参数,达到调用真实对象本来的基本功能的目的。

6 .装饰模式实例。

  • 真实对象和装饰对象要实现的接口
public interface Component{
    //定义一个接口,里面有一个方法
    public void codeAttack();
}
  • 真实对象实现接口代码
public class RealObject implements Component{
    @Override
    public void codeAttack(){
        System.out.println("对方拒绝和您说话,并向您扔了个JAVA的BUG!!!");
    }
}
  • 装饰对象实现接口的代码
//这个地方也可以直接将装饰对象具体化
public class Decorator implements Component{

    private Component component;

    public Decorator(Component component){
        this.component = component;
    }

    @Override
    public void codeAttack() {
        component.codeAttack();
    }

}
  • 具体的装饰对象通过继承装饰对象来达到实现和真实对象拥有相同接口的目的。
public class DecoratorObject1 extends Decorator{

    public DecoratorObject1(Component component) {
        super(component);
    }

    @Override
    public void codeAttack() {
        super.codeAttack();
        doAnotherThing();
    }

    private void doAnotherThing() {
        System.out.println("对方拒绝和您说话,并向您扔了个Phython的BUG!!!");
    }

}

public class DecoratorObject2 extends Decorator{

    public DecoratorObject2(Component component) {
        super(component);
    }

    @Override
    public void codeAttack() {
        super.codeAttack();
        doAnotherThing();
    }

    private void doAnotherThing() {
        System.out.println("吃枣药丸,感觉身体被掏空!!!");
    }

}
  • 测试修饰类的代码
public class Client {

    public static void main(String[] args) {
        Component component = new RealObject();
        Component component1 = new DecoratorObject1(component);
        component1.codeAttack();

        System.out.println("===========================================");

        Component component2 = new DecoratorObject2(component1);
        component2.codeAttack();
    }
}
  • 得到的结果:
对方拒绝和您说话,并向您扔了个JAVA的BUG!!!
对方拒绝和您说话,并向您扔了个Phython的BUG!!!
===========================================
对方拒绝和您说话,并向您扔了个JAVA的BUG!!!
对方拒绝和您说话,并向您扔了个Phython的BUG!!!
吃枣药丸,感觉身体被掏空!!!

7 .关于真实对象和装饰对象的注意地方
 关于真实对象和装饰对象不是固定的,一个类不一定就是固定充当真实对象,也不一定充当装饰对象,他们是相对的,比如上面的例子来说,component1相对于component来说就是一个就是一个装饰对象;而component1相对于component2来说就是一个真实对象。

 
8 .装饰模式的优点
 装饰模式的主要作用其实就是为了修饰某个类,改变其逻辑。我们都知道改变一个方法的途径有三种:<1>继承,重写父类方法。 <2>使用代理模式,改变父类的方法。 <3>使用装饰模式,来修饰父类方法。 
 我们之所以不在父类方法中直接添加字段改变逻辑就是为了减少父类的复杂度。因为这些被修饰的代码就是在特定环境下才执行的特殊行为。我们使用装饰模式,把每个要装饰的功能放在单独的类中,并让这个类包装所有装饰的对象。因此,当我们需要执行特殊行为的时候,我们就可以在代码逻辑中根据需要,有选择地、按顺序地使用装饰功能包装对象。
   装饰模式的本质就是利用了java的多态思想。
装饰模式对于刚刚接触的人来讲,是一个不容易想明白的设计模式,想的也比较烦,但是这些东西你早晚会遇见的,不要轻言放弃。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值