All design without business is bullshit! In the project, we will make multi-business logic judgment on multiple interfaces. The project is limited at the beginning, so we will focus on realizing functions first. Recently, we plan to optimize the code at the beginning
public void checkProjectAdd(List<OrderDetail> list) { if (! CollectionUtils.isEmpty(list)) { orderService.check(list); stockService.check(list); orderAddress.check(list); userScoreService.check(list); activityService.check(list); this.check(); } excute(); }Copy the code
Although the method of checking the class is simply encapsulated, there are many places where duplicate decisions can exist, such as order submission, adding to shopping cart, etc. Redundant code is ubiquitous and not easy to extend. In this case, without further discussion, we are ready to start work and analyze the business first, because the processing principle of each inspection interface is to ensure the sequence, and during the inspection process, the content of the list parameter may be dynamically changed according to the commodity submission parameters, for example, one inventory when two are sold. User membership level determines whether to enjoy discounts based on the actual number of goods, etc., so the check or manual processing value of each level is required to check the execution order of class code. After thinking about it, I remember that when I read mybatis source code, I felt that the plugins mode designed by mybatis was suitable for such scenarios. So I decided to use the Chain of Responsibility model to optimize the code this time.
First of all, let’s briefly introduce what is the chain of responsibility. When it comes to chains, we can think of linked lists. Here we only say the simplest linked list (one-way linked list).
A unidirectional list is an object that stores the reference address of the next object. The concept of responsibility chain pattern is also described:
The Chain of Responsibility Pattern creates a Chain of recipient objects for a request. This pattern decouples the sender and receiver of the request by giving the type of request. This type of design pattern is behavioral. In this pattern, each receiver typically contains a reference to the other receiver. If an object cannot handle the request, it passes the same request to the next recipient, and so on.
** concepts are standards, it is generally difficult to understand what is meant, we take the picture to say **
Each layer is the big brother, it is not easy to overcome the difficulties. We’re going to start wrapping things up. AOP is well known (for sectioning). Since our final submission method is excute, it should be excute. Dynamic proxy: dynamic proxy: dynamic proxy: dynamic proxyJDK dynamic proxy), the advantage of using dynamic proxy is that we can package hundreds of known and future interfaces. For example, my order submission event is called submitOrder and I add addCart. I can package these interfaces through my proxy mode. So we can unify
Through the level by level proxy model, we can finally call the actual implementation of the IOrderService. Without further elaboration, we can start coding
Start by defining our own interceptor class
public interface Interceptor {
Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException;
}
Copy the code
Next agent factory:
public class ProxyFactory implements InvocationHandler { private Object target; private Interceptor interceptor; private ProxyFactory(Object target, Interceptor interceptor) { this.target = target; this.interceptor = interceptor; } public static Object wrap(Object target, Interceptor filter) { ProxyFactory proxyFactory = new ProxyFactory(target, filter); return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyFactory); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Invocation invocation = new Invocation(target, method, args); return interceptor.intercept(invocation); }}Copy the code
The agent factory basically wraps the target object, which may be either the original object or the wrapped proxy object. In short, the submitOrder method in our IOrderService, after being hosted by the JDK dynamic proxy, In order to implement the chain principle of responsibility chain, we will call the wrap method again based on this object to wrap our various interceptors layer by layer, so that the chain relationship between the previous level and the next level is handled.
Next define which interceptors we are specifically in
public class TodoInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
System.out.println(" todo something ");
Object result = invocation.proceed();
System.out.println(" to do end something ");
return result;
}
}
public class LogInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
System.out.println(" do log ");
Object result = invocation.proceed();
System.out.println(" do log ");
return result;
}
}
Copy the code
The two block brothers have been here, next we block brothers into the factory for packaging
@Override
public void checkSubmitOrder() {
IOrderService orderService = new OrderService();
orderService = (IOrderService) ProxyFactory.wrap(orderService, new LogInterceptor());
orderService = (IOrderService) ProxyFactory.wrap(orderService, new TodoInterceptor());
orderService.submitOrder();
}
Copy the code
The code execution looks like this
Example is very simple, mainly is the chain of responsibility can use scene, combined with the the expansion of the chain of responsibility is very much, I put the blocker to unified spring trust, for example, custom annotations on each test, mark need to perform the interceptor, the AOP section scanning business method, to determine whether there is such a chain of responsibility interception annotations, In this way, the business inspection code is unified, and there is no need to write those repeated chek() in each line of code. Because of the length, I will not introduce too much. If you are interested, you can talk about me privately.
Source: www.cnblogs.com/doNetTom/p/…
Welcome to pay attention to the public number [code farming blossom] learn to grow together I will always share Java dry goods, will also share free learning materials courses and interview treasure book reply: [computer] [design mode] [interview] have surprise oh