装饰模式(decorator pattern)。
依照Num模型。讨论职业/IProfession类层次。
IProfession定义了方法say(String),事实上现类教师/ Teacher、医生、律师……依照其职业习惯给出say(String)的实现,这些实现类相当于Num模型中的Zero。
而才艺/Talent类层次(相当于NextOne),能够装饰基本对象,say(String)实现中,在必要的时候会说english、在必要的时候会唱几句……package closure.decorator;public interface IProfession { abstract public void say(String s);}package closure.decorator;import static yqj2065.util.Print.pln;public class Teacher implements IProfession{ @Override public void say(String s){ pln(teach(s)) ; } public String teach(String s){ String myStyle="解说["+s+"]"; return myStyle; }}package closure.decorator;public abstract class Talent implements IProfession { protected IProfession base; public Talent(IProfession base) { this.base = base; }} package closure.decorator;public class TSong extends Talent{ public TSong(IProfession base) { super(base); } @Override public void say(String s){ s = this.song(s); base.say(s); // } public String song(String s){ String strengthen="旋律("+s+")"; return strengthen; }}// TEnglish略
1.模板方法
抽象装饰类型Talent,只定义了其类层次的结构——作为类型闭包。没有提供say(String s)的默认实现,由于提供例如以下默认实现
@Override public final void say(String s) {
base.say(s);
}
尽管暗示其子类型应该调用base.say(),但不具有强制性。Talent能够编写模板方法,使得详细装饰类不再须要改写say()并调用base.say(),而只关注编写增强say()功能的代码。
package closure.decorator;public abstract class Talent implements IProfession { protected IProfession base; public Talent(IProfession base) { this.base = base; } @Override public final void say(String s) { //模板方法 s = strengthen(s); base.say(s); } public abstract String strengthen(String s);}package closure.decorator;public class TEnglish extends Talent {public TEnglish(IProfession base) { super(base); }public String english(String s) { String strengthen ="E文(" + s + ")"; return strengthen; } @Override public String strengthen(String s) { return this.english(s); }}//Test IProfession p = (IProfession) God.create("Profession-decorator");// p.say("类层次"); p = new TEnglish(new TSong(new TEnglish(p))); p.say("LSP"); p = new TSong(p); p.say("继承"); p= p.removeSong(); p.say("继承");
測试代码的输出为:
解说[类层次]
解说[E文(旋律(E文(LSP)))]
解说[E文(旋律(E文(旋律(继承))))]装饰模式比較典型的标志:Person b = new T2(newT2(newT1(newLawyer())));
2.装饰模式与桥接模式
装饰模式与桥接模式非常相似。桥接模式将2次以上的策略选择逐一地串接起来。如例程3-5中定义的模板方法。
public default void lecture(String s) {
String myStyle = say(s);
next.say(myStyle);
}
桥接模式所串接的,是两种不同的类层次。而装饰模式则将Talent和它的父类型IProfession进行逐一的串接。能够说,装饰模式是桥接模式的特例。