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

    xiaoxiao2021-03-27  30

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

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

    设计模式学习笔记装饰Decorator模式 基本介绍装饰案例 类图实现代码 Display抽象类StringDisplay类Border抽象类SideBorder类FullBorder类测试类运行结果 装饰模式中的角色 ComponentConcreteComponentDecorator装饰物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

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

    转载请注明原文地址: https://ju.6miu.com/read-664547.html

    最新回复(0)