1. 程式人生 > >動態改變執行方法

動態改變執行方法

題目:有一個介面Processor,分別被ServiceA和ServiceB實現。

interface Processor {
    void process();
}

class ServiceA implements Processor {
    @Override
    public void process() {
        System.out.println("run ServiceA...");
    }
}

class ServiceB implements Processor {
    @Override
    public void process()
{ System.out.println("run ServiceB..."); } }

要求前10次由ServiceA執行,超過10次後自動切換成ServiceB執行。

程式碼如下:

interface Processor {
    void process();
}

class ServiceA implements Processor {
    @Override
    public void process() {
        System.out.println("run ServiceA...");
    }
}

class ServiceB
implements Processor { @Override public void process() { System.out.println("run ServiceB..."); } } public class DynamicRun { static class ProcessRunner implements Processor { private DelegateProcess target; private int runCount; private ServiceA defaultProcessor =
new ServiceA(); @Override public void process() { int count = ++this.runCount; System.out.println("預設執行次數:" + count); if (count >= 10) { System.out.println("預設執行次數到達10次,切換為ServiceB執行"); // 將真正processor改為ServiceB this.target.setDelegate(new ServiceB()); } defaultProcessor.process(); } public void setTarget(DelegateProcess target) { this.target = target; } } static class DelegateProcess implements Processor { private Processor delegate; private DelegateProcess(Processor delegate) { this.delegate = delegate; } @Override public void process() { delegate.process(); } public void setDelegate(Processor delegate) { this.delegate = delegate; } } public static void main(String[] args) { // 拿到這個processor,可在其它地方執行,不受約束 Processor processor = buildProcessor(); for (int i = 0; i < 15; i++) { processor.process(); } } private static Processor buildProcessor() { ProcessRunner processRunner = new ProcessRunner(); DelegateProcess delegateProcess = new DelegateProcess(processRunner); processRunner.setTarget(delegateProcess); return delegateProcess; } }

此方式在JDK中也有出現,可以參考sun.reflect.ReflectionFactory.newMethodAccessor()方法。該方法在使用Method.invoke()時用到。程式碼片段如下:

NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);
DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);
var2.setParent(var3);