设计模式学习笔记——装饰(Decorator)模式

来源:互联网 发布:怎么用网络连接打印机 编辑:程序博客网 时间:2024/05/06 06:57

设计模式学习笔记——装饰(Decorator)模式

@(设计模式)[设计模式, 装饰模式, decorator]

  • 设计模式学习笔记装饰Decorator模式
    • 基本介绍
    • 装饰案例
      • 类图
      • 实现代码
        • Display抽象类
        • StringDisplay类
        • Border抽象类
        • SideBorder类
        • FullBorder类
        • 测试类
        • 运行结果
    • 装饰模式中的角色
        • Component
        • ConcreteComponent
        • Decorator装饰物
        • ConcreteDecorator具体的装饰物
      • 类图

基本介绍

装饰模式主要是通过委托机制,继承被装饰者的父类或者实现其接口,来做到不断的为被装饰者添加装饰。

java中的io包就是使用装饰者模式的很好的案例。

装饰案例

类图

装饰案例类图

实现代码

Display抽象类

package com.pc.decorator.example;/** * 显示抽象类 * Created by Switch on 2017-02-21. */public abstract class Display {    /**     * 获取每行的字符数     *     * @return 每行的字符数     */    public abstract int getColumns();    /**     * 获取行数     *     * @return 行数     */    public abstract int getRows();    /**     * 获取指定行的文本     *     * @param row 行数     * @return 文本     */    public abstract String getRowText(int row);    /**     * 全部显示     */    public final void show() {        for (int i = 0; i < this.getRows(); i++) {            System.out.println(getRowText(i));        }    }}

StringDisplay类

package com.pc.decorator.example;/** * 字符串显示类 * Created by Switch on 2017-02-21. */public class StringDisplay extends Display {    /**     * 带显示的字符串     */    private String string;    /**     * 构造方法,传入字符串     *     * @param string 字符串     */    public StringDisplay(String string) {        this.string = string;    }    @Override    public int getColumns() {        return this.string.getBytes().length;    }    @Override    public int getRows() {        return 1;    }    @Override    public String getRowText(int row) {        if (row == 0) {            return this.string;        }        return null;    }}

Border抽象类

package com.pc.decorator.example;/** * 边框装饰抽象类 * Created by Switch on 2017-02-21. */public abstract class Border extends Display {    /**     * 待装饰的对象     */    protected Display display;    /**     * 构造方法,传入待装饰的显示类对象     *     * @param display 显示类对象     */    public Border(Display display) {        this.display = display;    }}

SideBorder类

package com.pc.decorator.example;/** * 侧面边框装饰类 * Created by Switch on 2017-02-21. */public class SideBorder extends Border {    /**     * 装饰字符     */    private char decorateChar;    /**     * 构造方法,传入待装饰的显示类对象     *     * @param display 显示类对象     */    public SideBorder(Display display, char decorateChar) {        super(display);        this.decorateChar = decorateChar;    }    @Override    public int getColumns() {        return this.display.getColumns() + 2;    }    @Override    public int getRows() {        return this.display.getRows();    }    @Override    public String getRowText(int row) {        // 在两边加上装饰字符        return this.decorateChar + display.getRowText(row) + this.decorateChar;    }}

FullBorder类

package com.pc.decorator.example;/** * 完全边框装饰类 * Created by Switch on 2017-02-21. */public class FullBorder extends Border {    /**     * 构造方法,传入待装饰的显示类对象     *     * @param display 显示类对象     */    public FullBorder(Display display) {        super(display);    }    @Override    public int getColumns() {        return display.getColumns() + 2;    }    @Override    public int getRows() {        return display.getRows() + 2;    }    @Override    public String getRowText(int row) {        if (row == 0) { // 上边框            return "+" + makeLine('-', display.getColumns()) + "+";        } else if (row == display.getRows() + 1) {  // 下边框            return "+" + makeLine('-', display.getColumns()) + "+";        } else { // 内容            return "|" + this.display.getRowText(row - 1) + "|";        }    }    /**     * 生成一个重复的count次的ch字符串     *     * @param c     字符     * @param count 次数     * @return 重复的count次的ch字符串     */    private String makeLine(char c, int count) {        StringBuilder builder = new StringBuilder();        for (int i = 0; i < count; i++) {            builder.append(c);        }        return builder.toString();    }}

测试类

package com.pc.decorator.example.test;import com.pc.decorator.example.Display;import com.pc.decorator.example.FullBorder;import com.pc.decorator.example.SideBorder;import com.pc.decorator.example.StringDisplay;import org.junit.Test;/** * Display Tester. * * @author Switch * @version 1.0 */public class DisplayTest {    /**     * 测试装饰模式     */    @Test    public void testDisplay() {        Display display1 = new StringDisplay("Hello World!");        Display display2 = new SideBorder(display1, '#');        Display display3 = new FullBorder(display2);        display1.show();        display2.show();        display3.show();        System.out.println();        Display display4 = new FullBorder(new SideBorder(new FullBorder(new StringDisplay("Hello")), '#'));        display4.show();    }}

运行结果

Hello World!#Hello World!#+--------------+|#Hello World!#|+--------------++---------+|#+-----+#||#|Hello|#||#+-----+#|+---------+

装饰模式中的角色

Component

增加功能时的核心角色。Component角色只是定义了接口(API)。在案例中,由Display 类扮演此角色。

ConcreteComponent

该角色实现了Component角色所定义的接口(API) 。在案例中,由StringDisplay类扮演此角色。

Decorator(装饰物)

该角色具有与Component角色相同的接口(API)。在它内部保存了被装饰对象——Component角色。Decorator角色知道自己要装饰的对象。在案例中,由Border类扮演此角色。

ConcreteDecorator(具体的装饰物)

该角色是具体的Decorator角色。在案例中,由SideBorder类和FullBorder类扮演此角色。

类图

装饰模式类图

GitHub:DesignPatternStudy

——————参考《图解设计模式》

0 0