java设计模式之 装饰器模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java设计模式之 装饰器模式相关的知识,希望对你有一定的参考价值。

java设计模式之 装饰器模式

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。

这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,动态给一个对象添提供了额外的功能。

 

我们通过下面的实例来演示装饰器模式的用法。模拟一个人从想吃饭、找饭店、享受美食、结束吃饭的过程

 

代码展示:

首先创建一个被修饰的接口 Eat

package decorator;
//吃饭接口
public interface Eat {
    //吃饭方法
    void eat();
}

创建一个被修饰者并且有自己的状态

技术分享
package decorator;

public class Person implements Eat {

    @Override
    public void eat() {
        System.out.println("======我饿了======");
    }
}
技术分享

创建一个修饰者的抽象类

技术分享
package decorator;

public abstract class LikeEat implements Eat {
    private Eat eat;
    
    public LikeEat(Eat eat) {
        this.eat=eat;
    }
    
    @Override
    public void eat() {
        eat.eat();
    }

}
技术分享

创建五个修饰类的扩展类(即--扩展修饰),分别拥有自己特定的状态,丰富被修饰的类

技术分享
public class FindInMap extends LikeEat {
    public FindInMap(Eat eat) {
        super(eat);
    }

    public void userMap(){
        System.out.println("打开地图寻找美食");
    }
    
    @Override
    public void eat() {
        super.eat();
        userMap();
    }
}

public class GotoRestaurant extends LikeEat {

    public GotoRestaurant(Eat eat) {
        super(eat);
    }
    public void onWay(){
        System.out.println("去往饭店的路上");
    }
    
    @Override
    public void eat() {
        super.eat();
        onWay();
    }
    
}

public class InRestaurant extends LikeEat {
    public InRestaurant(Eat eat) {
        super(eat);
    }
    
    public void selectFoot(){
        System.out.println("到达饭店选择食物");
    }
    
    @Override
    public void eat() {
        super.eat();
        selectFoot();
    }

}

public class EatFoot extends LikeEat {
    public EatFoot(Eat eat) {
        super(eat);
    }
    
    public void eating(){
        System.out.println("享用美食中");
    }
    @Override
    public void eat() {
        super.eat();
        eating();
    }

}

public class endEat extends LikeEat {

    public endEat(Eat eat) {
        super(eat);
    }
    
    public void afterEat(){
        System.out.println("=====美食结束=====");
    }
    
    @Override
    public void eat() {
        super.eat();
        afterEat();
    }
}
技术分享

创建测试类,测试修饰效果

技术分享
public class EatTest {
    public static void main(String[] args) {
        Eat person = new Person();
        likeEat likeEat = new endEat(
                           new EatFoot(
                           new InRestaurant(
                           new GotoRestaurant(
                           new FindInMap(person))))) ;
        likeEat.eat();
    }
}
技术分享

运行结果:

技术分享

总结:
A、LikeEat抽象类中,持有Eat接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。
B、LikeEat抽象类的子类(具体装饰者),里面都有一个构造方法调用super(eat),这一句就体现了抽象类依赖于子类实现即抽象依赖于实现的原则。因为构造里面参数都是Eat接口,只要是该Eat的实现类都可以传递进去,即表现出

          likeEat likeEat = new endEat(
                    new EatFoot(
                      new InRestaurant(
                        new GotoRestaurant(
                          new FindInMap(person)))))

这种结构的样子。所以当调用likeEat.eat()的时候,又因为每个具体装饰者类中,都先调用super.eat();方法,而该super已经由构造传递并指向了具体的某一个装饰者类(这个可以根据需要调换顺序),那么调用的即为装饰类的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。

C、具体被装饰者,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。
D、装饰者模式的设计原则为:

  对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。

转自:http://www.cnblogs.com/kuoAT/p/6951706.html








以上是关于java设计模式之 装饰器模式的主要内容,如果未能解决你的问题,请参考以下文章

编程模式之Go语言如何实现装饰器

java设计模式之 装饰器模式

java模式之装饰器模式

java模式之装饰器模式

java模式之装饰器模式

java设计模式之 装饰器模式