以一個裝飾器模式實現數學運算的例子爲例。html
安裝 Intellj Ultimate , lience server: http://xdouble.cn:8888/java
在類上右鍵點擊 class diagram :
數組
在獲得的類的框框上 「雙指單擊」或右鍵 , 選擇 show Implementations :
app
獲得的實現類列表上, Ctrl + A 全選
函數
Enter 獲得類圖結果,上面有 導出圖片功能。
佈局
能夠查看接口及實現類的覆寫方法
測試
調整佈局
this
添加額外的類
若是發現還有點單獨的接口有關聯可是不在上述繼承體系裏, 能夠添加額外的 class diagram 並按上如法炮製。3d
導出圖片保存code
Function.java 函數接口, sources 是被裝飾的內層函數運算。
package zzz.study.patterns.decorator.func; public abstract class Function { protected Function[] sources; public Function(Function[] sources) { this.sources = sources; } public Function(Function f) { this(new Function[] {f}); } public abstract double f(double t); public String toString() { String name = this.getClass().toString(); StringBuffer buf = new StringBuffer(name); if (sources.length > 0) { buf.append('('); for (int i=0; i < sources.length; i++) { if (i > 0) buf.append(","); buf.append(sources[i]); } buf.append(')'); } return buf.toString(); } }
Constant.java :常量函數
package zzz.study.patterns.decorator.func; public class Constant extends Function { private double constant; public Constant() { super(new Function[] {}); } public Constant(double constant) { super(new Function[]{}); this.constant = constant; } public double f(double t) { return constant; } public String toString() { return Double.toString(constant); } }
T.java : 線性函數
package zzz.study.patterns.decorator.func; public class T extends Function { public T() { super(new Function[] {}); } public double f(double t) { return t; } public String toString() { return "t"; } }
Square.java :平方函數
package zzz.study.patterns.decorator.func; public class Square extends Function { public Square() { super(new Function[] {}); } public Square(Function f) { super(new Function[] {f}); } public double f(double t) { return Math.pow(sources[0].f(t),2); } public String toString() { StringBuffer buf = new StringBuffer(""); if (sources.length > 0) { buf.append('('); buf.append(sources[0]); buf.append('^'); buf.append(2); buf.append(')'); } return buf.toString(); } }
ExpDouble.java :指數函數
package zzz.study.patterns.decorator.func; public class ExpDouble extends Function { private double expDouble; // 指數的底數 public ExpDouble() { super(new Function[] {}); } public ExpDouble(double expDouble, Function f) { super(new Function[] {f}); this.expDouble = expDouble; } public double f(double t) { return Math.pow(expDouble, sources[0].f(t)); } public String toString() { StringBuffer buf = new StringBuffer(""); if (sources.length > 0) { buf.append('('); buf.append('('); buf.append(expDouble); buf.append(')'); buf.append('^'); buf.append(sources[0]); buf.append(')'); } return buf.toString(); } }
Pow.java :冪函數
package zzz.study.patterns.decorator.func; public class Pow extends Function { private double pow; // 冪函數的指數 public Pow() { super(new Function[] {}); } public Pow(Function f, double pow) { super(new Function[] {f}); this.pow = pow; } public double f(double t) { return Math.pow(sources[0].f(t), pow); } public String toString() { StringBuffer buf = new StringBuffer(""); if (sources.length > 0) { buf.append('('); buf.append(sources[0]); buf.append('^'); buf.append('('); buf.append(pow); buf.append(')'); buf.append(')'); } return buf.toString(); } }
Arithmetic.java :四則運算
package zzz.study.patterns.decorator.func; public class Arithmetic extends Function { protected char op; public Arithmetic(char op, Function f1, Function f2) { super(new Function[] {f1, f2}); this.op = op; } public double f(double t) { switch(op) { case '+': return sources[0].f(t) + sources[1].f(t); case '-': return sources[0].f(t) - sources[1].f(t); case '*': return sources[0].f(t) * sources[1].f(t); case '/': return sources[0].f(t) / sources[1].f(t); default: return 0; } } public String toString() { StringBuffer buf = new StringBuffer(""); if (sources.length > 0) { buf.append('('); buf.append(sources[0]); buf.append(Character.toString(op)); buf.append(sources[1]); buf.append(')'); } return buf.toString(); } }
Sin.java , Cos.java 請讀者自行完成。
測試:
package zzz.study.patterns.decorator; import zzz.study.patterns.decorator.func.Arithmetic; import zzz.study.patterns.decorator.func.Cos; import zzz.study.patterns.decorator.func.Function; import zzz.study.patterns.decorator.func.Sin; import zzz.study.patterns.decorator.func.Square; import zzz.study.patterns.decorator.func.T; public class ShowFunction { public static void main(String[] args) { Function complexFunc = new Arithmetic('+', new Square(new Sin(new T())), new Square(new Cos(new T()))); System.out.println(complexFunc + " = " + complexFunc.f(100.0)); } }
在 《Java函數接口實現函數組合及裝飾器模式》 一文中,使用 Function 接口有更簡潔的裝飾器模式實現。