Aspect Oriented Programming AOP Aspect Oriented Programming
问题 考虑一个POS机的销售处理模块
如何处理权限问题 在处理一个销售的过程中,收银员可以执行启动销售等操作(startSale),如果需要修改销售的内容(changeSale)则需要由管理员执行。 如何处理权限问题? 在每段方法的开头加上权限处理的代码? 或者应该将ProcessSaleHandler分解为两个类?
第一种方法 问题: 在所有的业务代码中都混杂了权限相关代码(Code tangling) 与权限相关的代码分散在各处(Code scattering ) public ISale startSale() { if (securityManager.isFunctionValid4CurrentUser("startSale")) return new SaleMemImpl(); else throw new SecurityViolatedException("startSale"); }
第二种方法 类提供了一种层次化的分类方法,但问题是,他只能提供一个维度的分类方法
Security Aspect的实现(Spring) public class SecurityCheckAspect implements MethodInterceptor { ISecurityManager securityManager; public void setSecurityManager(ISecurityManager securityManager) { this.securityManager = securityManager; } @Override public Object invoke(MethodInvocation invocation) throws Throwable { String funcName = invocation.getMethod().getName(); if (securityManager.isFunctionValid4CurrentUser(invocation.getMethod().getName())) return invocation.proceed(); else throw new SecurityViolatedException(funcName);
Code tangling
Code scattering
N-dimensional concern
Security Aspect的实现(AspectJ) public aspect SecurityAspect { private ISecurityManager securityManager = SecurityManager.getInstance(); pointcut securedAccess(): execution ( * IUsecaseHandler+.*(..) ); //Advice before(): securedAccess(){ String functionName = thisJoinPoint.getSignature().getName(); if(!securityManager.isFunctionValid4CurrentUser(functionName)) throw new SecurityViolatedException(functionName); }
AOP Solution
结果 模块化 简洁
Terminology Cross-cutting – Identify areas of code where common functionality exists Joinpoint – Where one or more aspects can be applied Pointcut – A collection of joinpoints Advice – The code to be injected Aspect – General term for where advice and point-cuts are combined
Terminology Weaving – Integrating applications and aspects (e.g. AspectJ is an “aspect weaver”) Compile-time – Can produce integrated source-code, but typically only produces woven byte-code. Run-time – Aspects are applied “on the fly” (typically when classes are loaded)
Static Cross-cutting Element Type How to implement Comparable/Cloneable/Hashable without modify existing source