设计模式之装饰模式

来源:互联网 发布:淘宝信誉等级表 编辑:程序博客网 时间:2024/06/01 09:44
  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来说就是一个真实对象。

装饰模式对于刚刚接触的人来讲,是一个不容易想明白的设计模式,想的也比较烦,但是这些东西你早晚会遇见的,不要轻言放弃。

0 0
原创粉丝点击