這裏介紹一個設計模式: Code Shape。
若是你沒有據說的,沒問題。這個名字是我剛剛起的。html
在應用軟件開發中,咱們常常會採用多層架構。在每一層中,不一樣的方法每每呈現相同的代碼結構。
這裏咱們稱之爲:Code Shape。
好比:在數據訪問層,寫方法均可能有下面這些代碼:java
除此以外,有時,架構師但願增長一些架構功能,好比:數據庫
這時,設計模式 Code Shape 經過使用Lambda表達式,實現了上面的需求。
提供了一種靈活的方式,管理每層方法的代碼結構。express
本位提供了一個代碼示例,完成下面功能:設計模式
關於 Java 8 Lambda 表達式,請參考 這裏。架構
Java 提供了 java.util.function.Consumer
和 java.util.function.Function
,方便咱們去使用Lambda表達式。oracle
Consumer
被用於沒有返回值的方法,Function
被用於有返回值的方法。
不幸的是,這兩個接口只支持一個輸入參數。
若是須要,咱們須要寫一些接口,來支持多個輸入參數。
這是,提供了支持兩個輸入參數的例子:app
@FunctionalInterface public interface ConsumerTwo<T, T2> { public void accept(T t, T2 t2); }
@FunctionalInterface public interface FunctionTwo<T, T2, R> { public R apply(T t, T2 t2); }
Annotation FunctionalInterface
標示這個接口是一個function interface,內部只定義了一個方法。性能
這個Main類調用了三個例子:
第一個例子:調用了一個沒有返回值的業務邏輯方法。
第二個例子:調用了一個沒有返回值的業務邏輯方法,實際上,會拋出異常。
第三個例子:調用了一個有返回值的業務邏輯方法。
代碼:設計
public class Main { public static void main(String[] args) { pattern.CodeShapeSample br = new pattern.CodeShapeSample(); // call business rule one br.businessRuleOne("Jack", "is man"); // call business rule two, will get an exception try { br.businessRuleTwoThrowException("Tom", "is woman"); } catch (Exception e) {} // call business rule three which has a return. String value = br.businessRuleThree("Mary", "is woman"); } }
package pattern; import java.text.MessageFormat; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; public class CodeShapeSample { /* * This is a consumer sample */ public void businessRuleOne(final String name, final String value) { CodeShapePattern.consumerShape.accept((o) -> { // here is business rule logical System.out.println("here is business rule logical 1."); }, Arrays.asList(name, value)); } /* * This is a consumer with exception sample */ public void businessRuleTwoThrowException(final String name, final String value) { CodeShapePattern.consumerShape.accept((o) -> { // here is business rule logical System.out.println("here is business rule logical 2."); throw new RuntimeException("failure!"); }, Arrays.asList(name, value)); } /* * This is a function sample */ public String businessRuleThree(final String name, final String value) { return CodeShapePattern.<String>getFunctionShape().apply((o) -> { // here is business rule logical System.out.println("here is business rule logical 3."); return name + " " + value; }, Arrays.asList(name, value)); } }
package pattern; import java.text.MessageFormat; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; public class CodeShapePattern { public static ConsumerTwo<Consumer<Object>, List<Object>> consumerShape = (body, params) -> { StackTraceElement caller = new Exception().getStackTrace()[2]; String method = caller.getClassName() + "#" + caller.getMethodName(); try { System.out.println(""); System.out.println("========"); System.out.println(MessageFormat.format("start method ''{0}''", method)); if (params != null) { for(Object param : params) { System.out.println(MessageFormat.format("parameter : ''{0}''", param.toString())); } } System.out.println("---- start body ----"); body.accept(null); System.out.println("---- end body ----"); } catch (Exception e) { System.out.println(MessageFormat.format("error method ''{0}'': {1}", method, e.getMessage())); throw e; } finally { System.out.println(MessageFormat.format("end method ''{0}''", method)); } }; public static <R> FunctionTwo<Function<Object, R>, List<Object>, R> getFunctionShape() { FunctionTwo<Function<Object, R>, List<Object>, R> function = (body, params) -> { R ret = null; StackTraceElement caller = new Exception().getStackTrace()[2]; String method = caller.getClassName() + "#" + caller.getMethodName(); try { System.out.println(""); System.out.println("========"); System.out.println(MessageFormat.format("start method ''{0}''", method)); if (params != null) { for(Object param : params) { System.out.println(MessageFormat.format("parameter : ''{0}''", param.toString())); } } System.out.println("---- start body ----"); ret = body.apply(null); System.out.println("---- end body ----"); } catch (Exception e) { System.out.println(MessageFormat.format("error method ''{0}'': {1}", method, e.getMessage())); throw e; } finally { System.out.println(MessageFormat.format("end method ''{0}'', return ''{1}''", method, ret.toString())); } return ret; }; return function; } }
好了,這裏已經提供了全部的代碼。如今,讓咱們逐一解釋。
CodeShapePattern.consumerShape
。/* * This is a consumer sample */ public void businessRuleOne(final String name, final String value) { CodeShapePattern.consumerShape.accept((o) -> { // here is business rule logical System.out.println("here is business rule logical 1."); }, Arrays.asList(name, value)); }
Consumer
。Consumer
是業務規則邏輯, 在業務規則邏輯,你想怎麼寫,就怎麼寫。Consumer
的輸入參數是沒用的,咱們能夠定義一個 ConsumerZero 接口來簡化代碼。public static ConsumerTwo<Consumer<Object>, List<Object>> consumerShape = (body, params) -> { StackTraceElement caller = new Exception().getStackTrace()[2]; String method = caller.getClassName() + "#" + caller.getMethodName(); try { System.out.println(""); System.out.println("========"); System.out.println(MessageFormat.format("start method ''{0}''", method)); if (params != null) { for(Object param : params) { System.out.println(MessageFormat.format("parameter : ''{0}''", param.toString())); } } System.out.println("---- start body ----"); body.accept(null); System.out.println("---- end body ----"); } catch (Exception e) { System.out.println(MessageFormat.format("error method ''{0}'': {1}", method, e.getMessage())); throw e; } finally { System.out.println(MessageFormat.format("end method ''{0}''", method)); } };
簡化版:
public static ConsumerTwo<Consumer<Object>, List<Object>> consumerShape = (body, params) -> { try { body.accept(null); } catch (Exception e) { throw e; } finally { } };
好了,這裏已經提供了全部的代碼。如今,讓咱們逐一解釋。
CodeShapePattern.<R>getFunctionShape()
。/* * This is a function sample */ public String businessRuleThree(final String name, final String value) { return CodeShapePattern.<String>getFunctionShape().apply((o) -> { // here is business rule logical System.out.println("here is business rule logical 3."); return name + " " + value; }, Arrays.asList(name, value)); }
Function
。Function
是業務規則邏輯, 在業務規則邏輯,你想怎麼寫,就怎麼寫。Function
的輸入參數是沒用的,咱們能夠定義一個 FunctionZero 接口來簡化代碼。public static <R> FunctionTwo<Function<Object, R>, List<Object>, R> getFunctionShape() { FunctionTwo<Function<Object, R>, List<Object>, R> function = (body, params) -> { R ret = null; StackTraceElement caller = new Exception().getStackTrace()[2]; String method = caller.getClassName() + "#" + caller.getMethodName(); try { System.out.println(""); System.out.println("========"); System.out.println(MessageFormat.format("start method ''{0}''", method)); if (params != null) { for(Object param : params) { System.out.println(MessageFormat.format("parameter : ''{0}''", param.toString())); } } System.out.println("---- start body ----"); ret = body.apply(null); System.out.println("---- end body ----"); } catch (Exception e) { System.out.println(MessageFormat.format("error method ''{0}'': {1}", method, e.getMessage())); throw e; } finally { System.out.println(MessageFormat.format("end method ''{0}'', return ''{1}''", method, ret.toString())); } return ret; }; return function; }
簡化版:
public static <R> FunctionTwo<Function<Object, R>, List<Object>, R> getFunctionShape() { FunctionTwo<Function<Object, R>, List<Object>, R> function = (body, params) -> { R ret = null; try { ret = body.apply(null); } catch (Exception e) { throw e; } finally { } return ret; }; return function; }
========
start method 'pattern.CodeShapeSample#businessRuleOne'
parameter : 'Jack'
parameter : 'is man'
---- start body ----
here is business rule logical 1.
---- end body ----
end method 'pattern.CodeShapeSample#businessRuleOne'
========
start method 'pattern.CodeShapeSample#businessRuleTwoThrowException'
parameter : 'Tom'
parameter : 'is woman'
---- start body ----
here is business rule logical 2.
error method 'pattern.CodeShapeSample#businessRuleTwoThrowException': failure!
end method 'pattern.CodeShapeSample#businessRuleTwoThrowException'
======== start method 'pattern.CodeShapeSample#businessRuleThree' parameter : 'Mary' parameter : 'is woman' ---- start body ---- here is business rule logical 3. ---- end body ---- end method 'pattern.CodeShapeSample#businessRuleThree', return 'Mary is woman' ```