題目:有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13...求出這個數列的前20項之和。
阿新 • • 發佈:2021-01-17
技術標籤:設計模式
在很多框架中,代理模式使用的比較多,在學習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.
意思是返回指定介面的代理類例項,該介面將方法呼叫排程到指定的呼叫處理程式。