大话设计模式本章内容摘录语句:
装饰这词真好,无论衣服、鞋子、领带、披风其实都可以理解为对人的装饰。
一旦使用装饰模式,不仅要
实例化组件,还要
把此组件包装进装饰者中。
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以使ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么久没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
Person具体组件类(装饰对象或装饰源)
package cn;
public class Person {
private String name;
public Person(){
}
public Person(String name) {
super();
this.name = name;
}
//Operation
public void show(){
System.out.print(name+"\t");
}
}
Decorator装饰基类
package cn.impl;
import cn.Person;
public class Decorator extends Person{
public Decorator(){
//这个用来new的无参构造,方便生成对象后使用方法装饰
}
//通过构造函数装饰
public Decorator(Person person){
this.person=person;
}
protected Person person;
//通过方法装饰
public void decorate(Person person) {
this.person=person;
}
@Override
/**
* 这是关键!
* 继承的子类,必须要运行super.show();来确保能装饰到。
* 这相当于对原来的person进行了装饰。
*/
public void show() {
person.show();
}
}
Glove护手装饰类
package cn.impl;
import cn.Person;
public class Glove extends Decorator{
public Glove(){
}
public Glove(Person person){
super(person);
}
@Override
public void show(){
super.show();//此句必加,否则无法装饰其他装饰者或具体装饰对象
newBehavior();
System.out.print("野蛮角斗士的鬼纹手套 ");
}
//新的方法
private void newBehavior(){
System.out.print("");
}
}
Helmet护帽装饰类
package cn.impl;
import cn.Person;
public class Helmet extends Decorator {
public Helmet(){
}
public Helmet(Person person){
super(person);
}
@Override
public void show() {
super.show();
System.out.println("野蛮角斗士的鬼纹软帽 ");
}
}
Robe长袍装饰类
package cn.impl;
import cn.Person;
public class Robe extends Decorator {
public Robe(){
}
public Robe(Person person){
super(person);
}
@Override
public void show() {
super.show();
System.out.print("野蛮角斗士的鬼纹长袍 ");
}
}
ShinPad护腿装饰类
package cn.impl;
import cn.Person;
public class ShinPad extends Decorator {
public ShinPad(){
}
public ShinPad(Person person){
super(person);
}
@Override
public void show() {
super.show();
System.out.print("野蛮角斗士的鬼纹护腿 ");
}
}
ShoulderPad护肩装饰类
package cn.impl;
import cn.Person;
public class ShoulderPad extends Decorator{
//可增加的属性
private String newInfo="老鼠咬过的";
public ShoulderPad(){
}
public ShoulderPad(Person person){
super(person);
}
@Override
public void show() {
super.show();
System.out.print(newInfo+"野蛮角斗士的鬼纹护肩 ");
}
}
Test_Decorator测试类
package junit.test;
import org.junit.Test;
import cn.Person;
import cn.impl.Decorator;
import cn.impl.Glove;
import cn.impl.Helmet;
import cn.impl.Robe;
import cn.impl.ShinPad;
import cn.impl.ShoulderPad;
public class Test_Decorator {
//通过方法产生
@Test public void test(){
Person person = new Person("Tom");//具体装饰对象
Decorator d1 = new Glove(); //装饰者1
d1.decorate(person); //把装饰对象包装入装饰者1
Decorator d2 = new Robe(); //装饰者2
d2.decorate(d1); //把包装者1包装入包装者2(递归包装)
d1 = new Helmet(); //合理再利用装饰者1
d1.decorate(d2);
d1.show(); //包装
System.out.println();
}
//通过带参构造函数
@Test public void test1(){
Person person = new Person("Jerry");//具体装饰对象
//写法1
Decorator d1 = new ShinPad(person); //通过构造函数来把装饰对象装入装饰者1
d1 = new Glove(d1); //...............装饰者1装入装饰者2
d1.show();
System.out.println();
//写法2
Decorator d2 = new ShoulderPad(new Robe(person));
d2.show();
System.out.println();
}
/**
* 注:两种方式都是 先实例化装饰对象(Person),再把该装饰对象包装进装饰者中,接着再在装饰者中层层嵌套的
*/
}