一個靜態類或者非靜態類,多個方法依賴一個函數,如何實現?
每個方法(方法數量很多)的開始都要調用一個許可權判斷函數,每一個方法的結尾都要調用一個日誌記錄方法,如何編寫能夠一次性把所有的依賴關係都聲明?這種設計模式叫做什麼模式?有點像sigslot.,希望大神幫忙。
AOP(面向切面編程)
下面是一個JDK動態代理的例子,代理還有很多其他實現方式。用Cglib的話就不要求被代理對象有介面(你直接使用SpringAOP算了)import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
Demo demo = new DemoImpl();
demo.foo();
demo.bar();
System.out.println("======");
demo = (Demo) Proxy.newProxyInstance(demo.getClass().getClassLoader(),
demo.getClass().getInterfaces(),
new MyInvocationHandler(demo));
demo.foo();
demo.bar();
}
private static class MyInvocationHandler implements InvocationHandler {
private Demo demo;
public MyInvocationHandler(Demo demo) {
this.demo = demo;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("foo")) {
System.out.println("before invoke");
method.invoke(demo, args);
System.out.println("after invoke");
} else {
System.out.println("before invoke");
System.out.println("cant invode: need login");
System.out.println("after invoke");
}
return null;
}
}
public static interface Demo {
void foo();
void bar();
}
public static class DemoImpl implements Demo {
public void foo() {
System.out.println("foo()");
}
public void bar() {
System.out.println("bar()");
}
}
}
AOP or Proxy Pattern
這個不是OO領域的問題,所以在那本書是找不到所謂的模式的,說的我又想吐槽那本書了,哎,算了。
從這個需求來說,一般來說實現方式是InvokeProxy
即方法調用代理,即不直接調用方法,而使用一個代理去調用,.Net Remoting的透明代理,WCF自動構建的客戶端代理乃至MVC的ActionInvoker都是這個思想的實現。大體上就是這樣。不嫌麻煩用代理嫌麻煩用依賴注入框架 Method Injection不動腦子簡單寫就用wrapper class
有好些辦法可以實現。
用function A(), function B(), function C()...function Z()表示題主所說的很多個方法,假設有這麼26個。那麼 @winter的函數調用可以,但是如果是靜態調用,你得用額外的26個方法來包裝,比較吃力。如果是動態調用,比如採用函數對象這種辦法,可參考策略模式,可以實現。
class Wrapper {
abstract class Function {
abstract void do();
};
Function function;
void do(){
checkPermission();
function.do();
doLog();
}
}
但實際編程時,肯定不可能這26個方法都是函數對象,所以不科學。
那麼 @趙劼的裝飾者模式也可以。class Wrapper extends Original{
private Original obj;
public Wrapper(Original obj) {
this.obj = obj;
}
public void do(){
checkPermission();
obj.do();
doLog();
}
}
裝飾者模式比策略模式好,因為把攔截抽象到了對象。也就是26個方法如果只屬於4個類,則只需要寫4個Wrapper就行了。但如果這26個方法都分別屬於26個類,那就蛋疼了。
解決這種問題的最佳實踐,我認為肯定是AOP。假如題主是在Java語言下編程,這個問題就so easy。首先將這26個方法全部加上@annotation。然後對所有annotation表示的方法使用AOP。以下是用spring aop搞定題主問題的示例public Object AroundDbExecution(final ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {
checkPermission();
Object obj = pjp.proceed();
doLog();
return obj;
}
看,真的是一下搞定所有麻煩,以後再有點什麼監控,事務什麼的處理,直接在這個方法里添加邏輯就行了。
如果是靜態類的話,只是一系列的靜態方法調用,談不上什麼設計模式。
非靜態類的話,Decorator(裝飾者模式)可以用來解決這種問題。
public interface ISomething
{
void DoSomething();
}
public class ConcreteSomething : ISomething
{
public virtual void DoSomething()
{
}
}
public class CheckPermissionSomething : ISomething
{
private readonly ISomething something;
public CheckPermissionSomething(ISomething something)
{
this.something = something;
}
public override void DoSomething()
{
CheckPermission();
something.DoSomething();
PostAction();
}
}
#define DEF_FUN(decl, body)decl {checkPermission();bodyexitFun();}
如果有相應的語言特性,就用語言特性。
如果你用的語言可以將一個函數轉化為對象的話。
Invoker模式也是一個選擇。Invoke(function) { Do some things function() Do some things}我怎麼覺得你要求的這種可以使用 裝飾者模式實現呢
其實用 Promise 比較好辦啦. 現在自己的應用後台 API 就是用的這種形式.
function specificAPI() {
// do some fancy jobs and return a promise.
}
function checkPermission() {
// check permission and return a promise.
}
// common logic.
checkPermission()
.then(specificAPI)
.then(function (result) {
// do something with the result, e.g. write to response stream.
});
推薦閱讀:
※C++模版類如何動態獲取類型?
※c++中如何正確實現克隆(原型)模式?
※實現同一介面的不同類使用組合實現了多態,但是這破壞了DRY嗎?
※設計模式在實際開發中用的多嗎?
※設計模式之組合模式
TAG:設計模式 |