JAVA设计模式:装饰模式

前面我们学习了代理模式:

代理模式主要使用了java的多态,干活的是被代理类,代理类主要是接活,你让我干活,好,我交给幕后的类去干,你满意就成,那怎么知道被代理类能不能干呢?同根就成,大家知根知底,你能做啥,我能做啥都清楚得很,同样一个接口。

本次我们学习下装饰模式:

装饰模式又称为包装模式,装饰模式以对客户端透明的方式扩展对象功能,相对于代理而言,代理是不让客户端知道真实对象的信息,装饰模式是基层关系的一个替代方案。

装饰模式是采用对客户端透明的方式动态的给一个对象添加了更多职责,对于原来被装饰的对象而言在装饰前和后并没有什么不同。装饰模式可以在不使用创造更多子类的情况下扩展对象的功能。

类图如下:

Component:组件对象的接口,规范那些准备添加附加功能类的对象。

ConcreateComponent:具体的组件对象,实现组件对象接口,通常就是被装饰的原始对象,也就是可以给这个对象添加附加的功能。

Decorator:所有装饰器的抽象父类,需要定义一个与组件对象一致的接口,并且持有一个Component对象,其实就是原始对象,被装饰的对象。

ConcreateDecorator:实际的装饰对象,实现具体要像被装饰对象添加的功能。

抽象的接口:

package com.njupt.study.designmodle.decorator;

public interface Component {
    public void operation();
}

原始对象,即需要被装饰的对象:

package com.njupt.study.designmodle.decorator;

public class ConcreateComponent implements Component{

    public ConcreateComponent(){};
    @Override
    public void operation()
    {
        System.out.println("开车");
    }

}

所有装饰对象的父类:

package com.njupt.study.designmodle.decorator;

public abstract class Decorator implements Component {

    private Component component;

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

    public void operation()
    {
        this.component.operation();
    }
}

实际装饰对象A:

package com.njupt.study.designmodle.decorator;

public class ConCreateDecoratorA extends Decorator {

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

    public void addedOperation()
    {
           System.out.println("晚上");
    }

    public void operation()
    {
        addedOperation();
        super.operation();
    }
}

实际装饰对象B:

package com.njupt.study.designmodle.decorator;

public class ConCreateDecoratorB extends Decorator {

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

    public void addedOperation()
    {
           System.out.println("兜风");
    }

    public void operation()
    {
        super.operation();
        addedOperation();
    }
}

客户端:

package com.njupt.study.designmodle.decorator;

public class Client
{
    public static void main(String[] args) {
         Component component = new ConcreateComponent();

         Decorator decorator = new ConCreateDecoratorB(new ConCreateDecoratorA(component));
         decorator.operation();
    }

}

测试结果:

装饰模式的定义 : 透明的给一个对象添加功能,并能够实现功能的动态组合.

在装饰模式的实现中,为了能够实现和原来使用被装饰对象的代码无缝结合,是通过定义一个抽象类,让这个类实现与被装饰对象相同的接口,然后在具体的实现类中,转调被装饰的对象,在转调的前后添加新的功能,这就实现了给被装饰对象增加功能.

下面举一个实际的例子:

定义一个接口:

package com.njupt.study.designmodle.decorator;

/**
 * 定义被装饰者  和 装饰者 共同的接口
 * @author Pony
 *
 */
public interface Human
{
    public void wearClothes();

    public void walkToWhere();
}

定义原始对象:

package com.njupt.study.designmodle.decorator;

/**
 * 定义被装饰者,被装饰者初始状态有些自己的装饰
 * @author Pony
 *
 */
public class Person implements Human {

    @Override
    public void walkToWhere() {
        System.out.println("穿什么呢。。"); 

    }

    @Override
    public void wearClothes() {
        System.out.println("去哪里呢。。");
    }

}

定义装饰对象:

package com.njupt.study.designmodle.decorator;

public class DecoratorHuman implements Human {

    private Human human;

    public DecoratorHuman(Human human) {
        this.human = human;
    }

    public void wearClothes() {
        human.wearClothes();
    }

    public void walkToWhere() {
        human.walkToWhere();
    }

}

下面定义三种装饰,这是第一个,第二个第三个功能依次细化,即装饰者的功能越来越多

package com.njupt.study.designmodle.decorator;

public class Decorator_zero extends DecoratorHuman {

    public Decorator_zero(Human human) {
        super(human);
        // TODO Auto-generated constructor stub
    }

    public void goHome() {
        System.out.println("进房子。。");
    }

    public void findMap() {
        System.out.println("书房找找Map。。");
    }

    @Override
    public void wearClothes() {
        // TODO Auto-generated method stub
        super.wearClothes();
        goHome();
    }

    @Override
    public void walkToWhere() {
        // TODO Auto-generated method stub
        super.walkToWhere();
        findMap();
    }
}
package com.njupt.study.designmodle.decorator;

public class Decorator_first extends DecoratorHuman {

    public Decorator_first(Human human) {
        super(human);
    }

    public void goClothespress() {
        System.out.println("去衣柜找找看。。");
    }

    public void findPlaceOnMap() {
        System.out.println("在Map上找找。。");
    }

    @Override
    public void wearClothes() {
        // TODO Auto-generated method stub
        super.wearClothes();
        goClothespress();
    }

    @Override
    public void walkToWhere() {
        // TODO Auto-generated method stub
        super.walkToWhere();
        findPlaceOnMap();
    }

}
package com.njupt.study.designmodle.decorator;

public class Decorator_two extends DecoratorHuman {

    public Decorator_two(Human human) {
        super(human);
    }

    public void findClothes() {
        System.out.println("找到一件D&G。。");
    }

    public void findTheTarget() {
        System.out.println("在Map上找到神秘花园和城堡。。");
    }

    @Override
    public void wearClothes() {
        // TODO Auto-generated method stub
        super.wearClothes();
        findClothes();
    }

    @Override
    public void walkToWhere() {
        // TODO Auto-generated method stub
        super.walkToWhere();
        findTheTarget();
    }

}

客户端:

package com.njupt.study.designmodle.decorator;

public class Test {
    public static void main(String[] args) {
        Human person = new Person();
        DecoratorHuman decorator = new Decorator_two(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.walkToWhere()的时候,又因为每个具体装饰者类中,都先调用super.wearClothes和super.walkToWhere()方法,而该super已经由构造传递并指向了具体的某一个装饰者类(这个可以根据需要调换顺序),那么调用的即为装饰类的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。
3、具体被装饰者类,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。
4、装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。所以:扩展体现在继承、修改体现在子类中,而不是具体的抽象类,这充分体现了依赖倒置原则,这是自己理解的装饰者模式。

时间: 2024-10-13 08:20:58

JAVA设计模式:装饰模式的相关文章

Java设计模式----装饰模式

1.概念: (在我看来,模式就像是是一种思想,在这种思想的指引下,对代码和结构的一番加工和整合而已!都是套路!) 装饰模式又称包装(Wrapper)模式,是以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.对客户端透明意味着接口不变. 2.问题: 在OO设计和开发过程中, 经常会遇到下面的情况: 我们需要为已经设计好的类添加新的职责, 通常情况下我们会定义一个新类继承自定义好的类. 由于组合比继承更好(复杂度高,继承深度深等原因, 类图: 3.如何实现装饰: (1):继承形式:(不推

JAVA设计模式之 装饰模式【Decorator Pattern】

一.概述 动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活.装饰模式是一种对象结构型模式.装饰模式是一种用于替代继承的技术,使用对象之间的关联关系取代类之间的继承关系.在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能. 二.适用场景 装饰原有对象.在不改变原有对象的情况下扩展增强新功能/新特征..当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式. 三.UML类图 四

java设计模式(1)-------单例,工厂,值对象,装饰模式

      java设计模式(1) 先简单的介绍下设计模式吧:是一种解决问题的一种行之有效的思想:用于解决特定环境下.重复出现的特定问题的解决方案. 那为什么我们需要学习设计模式呢? 1.设计模式都是一些相对优秀的解决方案,很多问题都是典型的.有代表性的问题,学习设计模式,我们就不用自己从头来解决这些问题,相当于在巨人的肩膀上,复用这些方案即可,站的高看到远,就是要站在巨人的肩膀上把他们踩下去,嘿嘿. 2.设计模式已经成为专业人士的常用词汇,不懂不利于交流,能让你变得很牛逼哦. 3.能让你设计的

菜鸟版JAVA设计模式—适配器模式,装饰模式,代理模式异同

节前把3个设计模式的学习心得分享了一下,分别是适配器模式,装饰模式,代理模式. 但是似乎越写越有些迷糊,这三种模式都有着一些大同小异的地方,总是有些搞不清. 今天再重新学习下,把学习心得分享给大家一下.这次是结合的我工作中的实际项目. 设计模式,其实是一种解决方法,JAVA作为一种面向对象的语言,对于所有的设计模式在实现上,总是少不了对接口的实现,对抽象类的继承,有时候似乎是为了去实现接口而去写接口,所以在这三种模式的说明代码中,我们都定义了接口这些东西,所以才有了现在的混淆. 先不厌其烦的介绍

Java设计模式学习记录-装饰模式

前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一些图形界面构件功能的增强等地方都运用了装饰模式. 装饰模式 定义 装饰模式的定义是:在不改变原类文件以及不使用继承的情况下,动态的扩展一个对象的功能.装饰模式是通过创建一个包装对象来实现的,也就是用装饰来包裹真实的对象. 举例 还是老规矩,举例说明,在给亲朋好友过生日时会买生日蛋糕,然后生日蛋糕又有

Java设计模式之认识阶段

设计模式是什么? 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 其本质就是继承与接口的组合应用. 为什么要用设计模? 使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.提高工作效率. 设计模式的分类: 设计模式按目的可分为三种类型,共23种. 创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式. 结构型模式:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式. 行为型模式:模版

java设计模式演示样例

创建模式 1.工厂方法模式(Factory Method)  将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到详细的子类.大大提高了系统扩展的柔性,接口的抽象化处理给相互依赖的对象创建提供了最好的抽象模式. public class TestFactoryMethod { public static void main(String[] args) { AnimalFactory af=new DogFactory(); Animal1 a=af.getAnima

2015.09.03 Java设计模式

通常,一个设计模式描述了一个被证实可行的方案.这些方案非常普遍,是具有完整定义的最常用的模式.一般模式有4个基本要素:模式名称(pattern name).问题(problem).解决方案(solution).效果(consequences). 常见的Java设计模式有以下23种: 1.抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 2.适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.适配器模式使得

java设计模式------装饰着模式

java设计模式-------装饰者模式 装饰者模式 Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案.主要有组件(components)和装饰器(Decorator)组成.要求components和Decorator实现相同的接口或者抽象类(具体类的局限性太大). 设计原则.模式特点.适用性 - 1. 多用组合,少用继承. 利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果能够利用

java设计模式-创建型

1.设计模式介绍 1.1 设计模式的概念 1.设计模式是一套被反复使用,多数人知晓,经过分类编码目的的优秀代码设计经验的总结. 2.设计模式贯彻的原理:面向接口编程,而不是面向对象实现. 3.设计模式的目标:降低耦合性,增强灵活性. 1.2 设计模式的要素 1.模式名称 2.问题 3.环境与初始环境 4.解决方案 5.效果 6.举例 7.末态环境 8.推理 9.其他有关模式 10.已知的应用 1.3设计模式的分类 1.创建型 1.1  单例模式 1.2  工厂模式 1.3  抽象工厂模式 1.4