设计模式学习笔记——装饰(Decorator)模式
@(设计模式)[设计模式, 装饰模式, decorator]
基本介绍
装饰模式主要是通过委托机制,继承被装饰者的父类或者实现其接口,来做到不断的为被装饰者添加装饰。
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
——————参考《图解设计模式》