设计模式学习笔记——装饰(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|#|
装饰模式中的角色
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