装饰者模式

来源:互联网 发布:centos 7 dracut 编辑:程序博客网 时间:2024/06/08 02:16

介绍

意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

何时使用:在不想增加很多子类的情况下扩展类。

如何解决:将具体功能职责划分,同时继承装饰者模式。

关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

//定义被装饰者public interface Human {     public void wearClothes();     public void walkToWhere();}
//定义被装饰者public class Decorator implements Human {    private Human human;    public Decorator(Human human) {        this.human = human;    }    @Override    public void wearClothes() {        human.wearClothes();    }    @Override    public void walkToWhere() {        human.walkToWhere();    }}
//下面定义三种装饰,这是第一个、第二个、第三个功能依次细化,即装饰者的功能越来越多public class Decorator_zero extends Decorator {    public Decorator_zero(Human human){        super(human);    }    public void goHome(){        System.out.println("进房子。。。");    }    public void findMap(){        System.out.println("书房找找地图...");    }    @Override    public void wearClothes(){        super.wearClothes();        goHome();    }    @Override    public void walkToWhere(){        super.walkToWhere();        findMap();    }}
public class Decorator_first extends Decorator{    public Decorator_first(Human human){        super(human);    }    public void goClothespress(){        System.out.println("去衣柜找找看。。。");    }    public void findPlaceOnMap(){        System.out.println("在地图上找找地点...");    }    @Override    public void wearClothes(){        super.wearClothes();        goClothespress();    }    @Override    public void walkToWhere(){        super.walkToWhere();        findPlaceOnMap();    }}
public class Decorator_second extends Decorator {    public Decorator_second(Human human) {        super(human);    }    public void findClothes(){        System.out.println("找到一件上衣。。。");    }    public void findTheTarget(){        System.out.println("在地图上找到城堡...");    }    @Override    public void wearClothes(){        super.wearClothes();        findClothes();    }    @Override    public void walkToWhere(){        super.walkToWhere();        findTheTarget();    }}
//定义被装饰者,被装饰者初始状态有些自己的装饰public class Person implements Human {    @Override    public void wearClothes() {        System.out.println("穿什么呢。。");    }    @Override    public void walkToWhere() {        System.out.println("去哪里呢。。");    }}
public class Test {    public static void main(String[] args){        Human person = new Person();        Decorator decorator = new Decorator_second(                new Decorator_first(                new Decorator_zero(person)        ));        decorator.wearClothes();        decorator.walkToWhere();    }}

其实就是进房子找衣服,然后找地图这样一个过程,通过装饰者的三层装饰,把细节变得丰富。

关键点:

1、Decorator 抽象类中,持有Human接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。

2、Decorator抽象类的子类(具体装饰者),里面都有一个构造方法调用super(human),这一句就体现了抽象依赖于子类实现即抽象依赖于实现的原则。因为构造里面参数都是Human接口,只要是该Human的实现类都可以传递进去,即表现出Decorator dt = new Decorator_second(new Decorator_first(new Decorator_zero(human)));这种结构的样子。所以当调用dt.wearClothes(); dt.walkToWearClothes和super.walkToWhere()方法,而该super已经由构造传递并指向了具体的某个装饰者类,那么调用的即为装饰者的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。

3、具体被装饰者,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。

4、装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现的我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对别装饰者进行包装。所以:扩展体现在继承、修改体现在子类中,而不是具体的抽象类,这充分体现了依赖倒置原则,这是自己理解的装饰者模式。

原创粉丝点击