`
zhangweieye
  • 浏览: 9977 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

设计模式学习笔记(三:装饰模式)

 
阅读更多

1.1概述

    在许多设计中,可能需要改进类的某个对象的功能,而不是该类创建的全部对象,在这样的情况下,就可以使用装饰模式。

    例如,麻雀类的实例(麻雀)能够连续飞行100米,如果用麻雀类创建了5只麻雀,那么这5只麻雀都能连续飞行100米。假如想让其中一只麻雀能够连续飞行150米,那应当怎样做呢?一种比较好的办法就是给麻雀装上智能电子翅膀,智能电子翅膀可以使得麻雀不使用自己的翅膀就能飞行50米。

    装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。在装饰模式中,“具体组件”类和“具体装饰”类是该模式中最重要的两个角色。“具体组件”类的实例称作“被装饰者”,“具体装饰”类的实例称为“装饰者”。“具体装饰”类需要包含有“具体组件”类的一个实例的引用,以便装饰“被装饰者”。例如,前面所述的麻雀类就是“具体组件”类,而一只麻雀就是“具体组件”类的一个实例,即是一个“被装饰者”,而安装了电子翅膀的麻雀就是“具体装饰”类的一个实例,即安装了电子翅膀的麻雀就是麻雀的“装饰者”。

 

1.2模式的结构

    装饰模式的结构中包括以下四种角色:

(1)抽象组件(Component):抽象组件是一个抽象类。抽象组件定义了“被装饰者”需要进行“装饰“的方法。

(2)具体组件(ConcreteComponent):具体组件是抽象组件的一个子类,具体组件的实例称为“被装饰者“。

(3)装饰(Decorator):装饰也是抽象组件的一个子类,但装饰还包含一个抽象组件声明的变量以保存“被装饰者“的引用。装饰可以是一个抽象类也可以是一个非抽象类,如果是非抽象类,该类的实例称为”装饰者“。

(4)具体装饰(ConcreteDecorator):具体装饰是装饰的一个非抽象子类,具体装饰的实例称为“装饰者“。

    装饰模式结构的类图如下所示:

 

 

 

1.3装饰模式的优点

(1)被装饰者和装饰者是松耦合关系。由于装饰仅仅依赖于抽象组件,因此具体装饰只知道它要装饰的对象是抽象组件某一个子类的实例,但不需要知道是哪一个具体子类。

(2)装饰模式满足“开-闭原则“。不必修改具体组件,就可以增加新的针对该具体组件的具体装饰。

(3)可以使用多个具体装饰来装饰具体组件组件的实例。

 

1.4适合使用装饰模式的情景

(1)程序希望动态地增强类的某个对象的功能,而又不影响到该类的其他对象。

(2)采用继承来增强对象功能不利于系统的扩展和维护。

 

 

1.5装饰模式的使用

  下面通过一个简单的实例,实现1.1概述中简单例子:假设系统中有一个Bird抽象类以及Bird类的一个子类SparrowSparrow类实现了Birdfly方法,使得Sparrow类创建的对象(麻雀)调用fly()方法能连续飞行100米。

  现在,用户需要两只鸟,无论是那种鸟都可以,但必须分别能连续飞行150米和200米。显然,现有的系统无法向用户提供这样的Bird对象,所以需要修改现有的系统。此处,使用装饰者模式,即可实现不必修改系统的代码,只需在系统中添加“装饰”,该系统将可以创建出用户需要的鸟。具体如下:

 首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图3所示:

 

图3  具体编写类及接口与类图对应关系

(1)抽象组件

本问题中,抽象组件Bird规定了具体组件需要实现方法,Bird类的代码如下:

package com.liuzhen.three_decorator;

public abstract class Bird {
    public abstract int fly();
}

 

(2)具体组件

对于本问题,具体组件是Sparrow类,该类在实现fly()方法时,将该方法的返回值设置为100Sparrow类的代码如下:

复制代码
package com.liuzhen.three_decorator;

public class Sparrow extends Bird{
    public final int DISTANCE = 100;
    public int fly(){
        return DISTANCE;
    }
}
复制代码

 

(3)装饰

本问题中,装饰类是一个抽象类,该类包含有一个Bird声明的变量以保存“被装饰者”的引用。代码如下:

复制代码
package com.liuzhen.three_decorator;

public abstract class Decorator extends Bird {
    protected Bird bird;
    public Decorator(){
        
    }
    public Decorator(Bird bird){
        this.bird = bird;
    }
}
复制代码

 

(4)具体装饰

根据具体的问题,具体装饰经常委托“被装饰者”调用相应的方法。本问题中具体装饰类是SparrowDecorator类,该类的代码如下:

复制代码
package com.liuzhen.three_decorator;

public class SparrowDecorator extends Decorator{
    public final int DISTANCE = 50;  //eleFly方法能飞50米
    SparrowDecorator(Bird bird){
        super(bird);                 //表示调用父类(Decorator)的构造函数
    }
    public int fly(){
        int distance = 0;
        distance = bird.fly() + eleFly();   //委托被装饰者bird调用fly(),然后再调用eleFly()
        return distance;
    }
    /*
     * eleFly()方法访问权限设置为private,其目的是使得客户程序只有调用fly方法才可以使用eleFly方法
     */
    private int eleFly(){             //装饰者新添加的方法
        return DISTANCE;
    }
}
复制代码

 

(5)具体使用

    通过ThreeApllication类来具体实现上述相关类和接口,来实现适配器模式的运用,其代码如下:

复制代码
package com.liuzhen.three_decorator;

public class ThreeApplication {
    public void needBird(Bird bird){
        int flyDistance = bird.fly();
        System.out.println("这只鸟能飞行"+flyDistance+"米");
    }
    public static void main(String[] args) {
        ThreeApplication client = new ThreeApplication();
        Bird sparrow = new Sparrow();          //sparrow只能飞行100米
        Bird sparrowDecorator1 = new SparrowDecorator(sparrow);   //sparrowDecorator1能飞行150米
        Bird sparrowDecorator2 = new SparrowDecorator(sparrowDecorator1); //sparrowDecorator2能飞行200米
        client.needBird(sparrowDecorator1);
        client.needBird(sparrowDecorator2);
    }
}
复制代码

 

运行结果如下:

这只鸟能飞行150米
这只鸟能飞行200米

 

分享到:
评论

相关推荐

    设计模式学习笔记总结

    这里我们聚焦于C#语言中的设计模式学习笔记,涵盖了多种经典的设计模式,如合成模式、桥梁模式、装饰模式、享元模式、门面模式、命令模式、工厂方法、策略模式、代理模式以及状态模式。下面将对这些模式逐一进行详细...

    设计模式学习笔记大全

    以上就是压缩包中的设计模式学习笔记涉及到的主要内容。通过对这些模式的理解和应用,开发者可以更好地解决软件设计中的问题,提升软件的质量和可维护性。每种模式都有其适用场景,理解其背后的意图和应用场景是关键...

    HeadFirst 设计模式学习笔记3--装饰模式 Demo

    在“HeadFirst 设计模式学习笔记3--装饰模式 Demo”中,作者通过实例讲解了装饰模式的基本概念、结构和应用场景。这篇文章可能是从CSDN博客平台上的一个链接访问的,遗憾的是,由于我们当前无法直接访问该链接,所以...

    HeadFirst设计模式学习笔记

    《HeadFirst设计模式学习笔记》是一份详尽的资料,旨在帮助读者深入理解并掌握设计模式这一编程领域的核心概念。设计模式是软件工程中的一种最佳实践,它在解决常见问题时提供了一种标准的解决方案,使得代码更易于...

    23种设计模式学习笔记

    这个“23种设计模式学习笔记”文档将引导你深入理解这些模式,并帮助你在实际编程中有效地应用它们。以下是对23种设计模式的详细解读: 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。它常用于控制...

    C#设计模式学习笔记

    以下是对“C#设计模式学习笔记”中涉及的一些关键知识点的详细解释。 1. **设计模式的基本概念**: 设计模式是一种在特定上下文中已被证明有效的解决方案模板,它描述了如何在软件设计中解决常见问题。设计模式...

    23种设计模式学习笔记及源码

    这个压缩包文件包含了23种设计模式的学习笔记和源码,旨在帮助开发者深入理解并熟练运用这些模式。以下是对每种设计模式的详细解释,以及它们在Java编程中的应用。 1. **单例模式**:确保一个类只有一个实例,并...

    设计模式学习笔记

    Java中的23种设计模式被广泛接受并应用于各种项目中,它们分为三类:创建型、结构型和行为型模式。 创建型模式关注对象的创建过程,它们包括: 1. 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问...

    尚硅谷设计模式源码笔记课件.zip

    结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、...

    GoF 23种设计模式学习笔记

    "GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...

    Head.First 设计模式学习笔记.pdf

    ### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...

    java设计模式学习笔记,以及各种模式的代码实现

    Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决问题的经验总结,可以提高代码的可读性、可维护性和可复用性。这些模式是面向对象编程中的一种最佳实践,通过标准化的方式处理常见的设计问题。下面...

    设计模式之美—学习笔记

    在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...

    图解java设计模式_学习笔记_java开发

    这份"图解java设计模式_学习笔记"是针对Java开发者深入理解和应用设计模式的重要资源。在这里,我们将深入探讨Java设计模式的核心概念、分类以及它们在实际开发中的应用。 设计模式分为三大类:创建型、结构型和...

    根据《JAVA与设计模式》整理的笔记及示例代码

    6. 装饰模式:动态地给一个对象添加一些额外的职责。 7. 享元模式:运用共享技术有效地支持大量细粒度的对象。 四、行为型模式 1. 责任链模式:避免将请求的发送者和接收者耦合在一起,使得多个对象都有可能处理...

    图解设计模式 ,结城浩著 学习笔记

    根据给定的信息“图解设计模式,结城浩著学习笔记”,我们可以推断出这份文档主要涉及了设计模式的学习和理解。《图解设计模式》是一本由日本著名程序员结城浩撰写的书籍,该书以图形化的方式深入浅出地讲解了软件...

    300Java设计模式部分学习笔记

    以下是一些在尚学堂300Java设计模式部分学习笔记中涉及的设计模式的知识点: 创建型模式: 创建型模式主要解决对象创建的问题,确保系统的灵活性和封装创建细节。学习笔记中提到了5种创建型模式: 1. 单例模式...

Global site tag (gtag.js) - Google Analytics