[Java] Design Pattern:Code Shape - manage your code shape
[Java] Design Pattern:Code Shape - manage your code shape
Code Shape Design Pattern
Here I will introduce a design pattern: Code Shape。
It's fine that you never heard that, I just created it.
Usage
In the enterprise application development, in most cases, we adopt multiple layers architectures.
Methods in each layer tend to present the same code structure. Here we name it as code shape.
For example, in the database access layer, writing methods would have following code:
- Get the database connection.
- Begin a transaction.
- Write database.
- Commit the transaction.
- When there is an exception, rollback the transaction.
Beside, some times, architects hope to add some infrastructure functions, e.g.
- Unified processing authority authentication.
- Unified handling exceptions.
- Logging.
- Profiling for performance.
- Logging method parameters.
So, the design pattern code shape implements the above requirements by using Java lambda expressions
Provide a flexible way to manage every method shape in a layer.
Code Demonstrate
This article presents a code demonstrate to implement following features:
- Before calling a method, write a log
- Log method parameters
- After calling the method, write a log
- If applicable, log the return value
- When there is an exception, log the exception
Prerequisites
About Java 8 Lambda Expressions, please see here.
Java provides java.util.function.Consumer and java.util.function.Function, to benefit us a convenience way to use lambda expressions.
Consumer can be used by non-return methods, and Function can be used by methods which have return.
Unfortunately, they only support one argument.
Therefore, if need, we have to write interfaces to support multiple arguments.
Here are samples to support tow input arguments:
- ConsumerTwo
@FunctionalInterface
public interface ConsumerTwo<T, T2> {
public void accept(T t, T2 t2);
}
- FunctionTwo
@FunctionalInterface
public interface FunctionTwo<T, T2, R> {
public R apply(T t, T2 t2);
}
Annotation FunctionalInterface indicates this is a function interface, only one method is defined inside.
Main class code
The main class calls 3 samples:
The first sample: it is a method without return.
The second sample: it is a method without return, but always throw an exception.
The third sample: it is a method with return.
Code:
- Main.java
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");
}
}
Code Shape Design Pattern Code
- CodeShapeSample
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));
}
}
- CodeShapePattern
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;
}
}
Explanation 1:using Consumer
OK. All code is presented, let's explain them.
- Business Rule Code
As this business rule method does not return any thing, so I useCodeShapePattern.consumerShape.
There are 2 input parameters.: business rule logical and the method's parameter values.
/*
* 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));
}
- Code Shape Design Pattern Code - Consumer
We can see it, the consumerShape is a static variable that implements unified functions.
This consumerShape uses a nestedConsumer.
TheConsumerinside is the business rule logical., In business rule methods, you can write any code what you want.
BTW, the input parameter is useless, we may define a ConsumerZero interface to simplify the code.
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));
}
};
Less code version:
public static ConsumerTwo<Consumer<Object>, List<Object>> consumerShape = (body, params) ->
{
try {
body.accept(null);
}
catch (Exception e) {
throw e;
}
finally {
}
};
Explanation 2: Using Function
- Business Rule Layer method
As this business rule layer method has return, we useCodeShapePattern.<R>getFunctionShape()inside.
getFunctionShape() is a generic method, the generic type is the return type of the business rule method.
There are 2 parameters:
The first: business rule logical, with return.
The second: parameters of the business rule method, for internal use.
/*
* 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));
}
- Code Shape Design Pattern - Function
Different as the consumerShape, getFunctionShape is a static generic method that implements unified functions.
This getFunctionShape uses a nestedFunction.
TheFunctioninside is the business rule logical., In business rule methods, you can write any code what you want.
BTW, the input parameter is useless, we may define a FunctionZero interface to simplify the code.
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;
}
Less code version:
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;
}
Output result
========
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'
[Java] Design Pattern:Code Shape - manage your code shape的更多相关文章
- java design pattern - adapter pattern
场景 适配器模式 总结 参考资料 场景 在编程中我们经常会遇到驴头不对马嘴的情况,比如以前是继承A的接口的对象,现在外部调用的时候需要该对象已B接口的形式来调用 ,这个时候我们可以让对象同时集成A和B ...
- Java Design Pattern(Factory,Singleton,Prototype,Proxy)
一.Factory 设计模式: the most common pattern,create a new object ,eg. A a=new A();工厂模式的好处:工厂模式可以做到把创建对象单独 ...
- JAVA DESIGN PATTERN
工厂模式(factory) 简单工厂模式的概念 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承 ...
- Java并发编程:Concurrent锁机制解析
Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...
- java设计模式大全 Design pattern samples in Java(最经典最全的资料)
java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...
- Scalaz(10)- Monad:就是一种函数式编程模式-a design pattern
Monad typeclass不是一种类型,而是一种程序设计模式(design pattern),是泛函编程中最重要的编程概念,因而很多行内人把FP又称为Monadic Programming.这其中 ...
- design principle:java 回调与委派/委托机制
博客 design principle:模拟 android Button 控件点击事件 主要说了一下模拟 android 的 Listener 模式,其实这就是一种委派与回调机制的体现. 委派,也可 ...
- Template Method Design Pattern in Java
Template Method is a behavioral design pattern and it’s used to create a method stub and deferring s ...
- State Design Pattern
注: 转载自 https://www.geeksforgeeks.org/state-design-pattern/ [以便查阅,非原创] State Design Pattern State pa ...
随机推荐
- APUE 4.8 umask函数
- 【Alpha】事后诸葛亮
一. 项目的预期计划 / 项目的现实进展 详见Alpha冲刺博客第一篇 二. 完成项目过程中的体会 详见Alpha冲刺博客第十二篇 三. 团队成员的分工及在Alpha阶段的工作量比例 成员 职务 博客 ...
- REDIS线上问题
这周终于解决了Redis访问经常超时的问题,终于可以踏实睡觉了.从上周就开始纠结在这个问题上,可以用寝食难安来形容,感觉这个问题就像个定时炸弹一样,虽然根据手搜的访问量,极少的Timeout Erro ...
- BZOJ2281:[SDOI2011]黑白棋(博弈论,组合数学,DP)
Description 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 ...
- 1191. [HNOI2006]超级英雄【二分图】
Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的 多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目,只有当选手正确 ...
- CVE-2017-8046 复现与分析
环境搭建 使用的项目为https://github.com/spring-guides/gs-accessing-data-rest.git里面的complete,直接用IDEA导入,并修改pom.x ...
- jmeter验证WEB页面的href链接请求
1. 第一步: 创建Samper_HTTP请求,打开测试页面 2. 第二步: 创建后置处理器_正则表达式(也有其他方式,这里仅介绍正则) 如图 3. 第三步 创建逻辑控制器_ForEach控制器,配置 ...
- vs未能正确加载XXX包,编译时停止工作问题
出现这个问题的原因可能是配置更改或安装了另一个扩展,幸好之前用的不多,重新进行用户配置代价也不高,打开Visual Studio Tools: 选择VS2013 开发人员命令提示: 输入deven ...
- java crm 进销存 springmvc SSM 项目 源码 系统
系统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3 SSM ...
- Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量
在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...