1. 程式人生 > 其它 >題目:有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13...求出這個數列的前20項之和。

題目:有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13...求出這個數列的前20項之和。

技術標籤:設計模式

在很多框架中,代理模式使用的比較多,在學習mybatis原始碼過程中大量用到代理模式。今天覆習一下幾種代理模式:靜態代理動態代理
代理模式就相當於一箇中介,比如房產中介,婚慶公司,它本身並沒有實現房產,但是他代理了房產。
優點:
1.具有高擴充套件性(因為中間插入了中間層,可以對原有功能進行擴充套件)
2.職責清晰。
缺點:由於增加了中間層,可能導致處理效率變慢

第一種情況:靜態代理

package com.study.mybatis;

public class ProxyDemo {
    public static void main(String[] args)
{ Proxy proxy = new Proxy(); proxy.say(); } } //需要實現的功能 interface Function{ public void say(); } //被代理的物件 class ReallyClass implements Function{ public void say(){ System.out.println("我是被代理的類"); } } //代理類 class Proxy implements Function{ private ReallyClass reallyClass;
public void say(){ if(reallyClass==null){ reallyClass = new ReallyClass(); } System.out.println("Proxy:"); //在目標的業務程式碼前後可以任意插入別的業務 /* * 類似於,房東讓中介代理房子,中介隨便進行標價並且插入很多不相關的費用 * */ reallyClass.say(); } //也可以在原有功能上對功能進行進一步擴充套件
public void call(){ System.out.println("我要打電話"); } }

第二種情況:動態代理
常見的動態代理用到的主要是:JDK動態代理和CGLib動態代理
這裡主要對JDK動態代理進行解析。
JDK動態代理主要是通過Java反射機制動態建立代理物件。java.lang.reflect包,最好自己看一下API或者原始碼理清楚。
測試案例

package com.study.mybatis;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 不知道Proxy.newProxyInstance()方法的引數,自己點進去看一下原始碼,原始碼是這樣的
* public static Object newProxyInstance(ClassLoader loader,
* 										//這是一個介面的.class陣列
                                          Class<?>[] interfaces,
                                          //引用處理
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);

        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
*/
public class JDKProxyDemo {
    public static void main(String[] args) {
        JDKProxy jdkProxy = new JDKProxy(new Phone());
        Service o = (Service) Proxy.newProxyInstance(Service.class.getClassLoader(), new Class[]{Service.class}, jdkProxy);
        o.msg("1111");
        o.call();
    }
}
//實現的功能介面
interface Service{
    //傳送資訊
    void msg(String str);
    //打電話
    void call();
}
//委託類
class Phone implements Service{
    @Override
    public void msg(String str) {
        System.out.println("傳送資訊"+str);
    }

    @Override
    public void call() {
        System.out.println("打電話!");
    }
}
//代理類
class JDKProxy implements InvocationHandler {
    private Object target;

    public JDKProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("操作前,先去洗澡!");
        Object invoke = method.invoke(target, args);
        System.out.println("操作後,執行業務");
        return invoke;
    }
}

至於為什麼需要呼叫 newProxyInstance,看一下原始碼註釋,原始碼中是這樣描述的 :Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.
意思是返回指定介面的代理類例項,該介面將方法呼叫排程到指定的呼叫處理程式。