什么是静态代理
如果说到什么是静态代理,那么首先我们要明白的是什么是代理?在我们日常生活中,听说过最多的代理就是代理律师啦。那么问题来啦,为什么会有代理律师呢?如果到明白啦这点,我认为什么是代理,这个答案也就呼之欲出。我们都知道,我们平常人,除了一些比较常见的法律之外,几乎可以说是不懂法律的,但是如果我们某一天需要打一场官司的话,我们几乎不可能说去学习一些打官司的相关知识再去打官司,所以在社会上就有一种职业出现——律师,代理律师这种职业的出现。有了这个代理律师,我们相当于增强了自己在法律方面的能力。同样,静态代理的设计模式也是一种增强目标类的设计模式。
以上是比较通俗一点的对静态代理的介绍(应该是代理的介绍,至于为什么是静态代理,等到结合动态代理再一起比较说明)。如果比较官方一点的说法就是:
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。————来自百度百科。
如何实现静态代理
我们知道了这个东西之后就得想到我们怎么把这个东西弄出来。
所以:我们根据适合的简单业务需求基础上去实现静态代理。
比如:我们需要将某个类的其中一个方法的返回值变成全大写的形式输出。
首先我们要分析一些需求:
某个类:说明我们得有一个目标类,在这里我们可以说是Target目标类,但是一般我们都要让该类的类实现一个接口
然后将其中的一个方法的返回值以全大写的形式输出,这就说明了Target类至少应该有一个目标方法beToUpper()
package com.csdn.target;
//目标类要实现的接口
public interface ITarget {
//将返回值变成大写的方法
String beToUpper();
//其他方法
void noDoSomething();
}
package com.csdn.target.impl;
import com.csdn.target.ITarget;
//目标类
public class Target implements ITarget {
//要被代理对象增强的目标方法
@Override
public String beToUpper() {
return "abcdef";
//一般我们都会在这里直接这样返回,就可以完成同样的需求
//但是我们不能,为什么呢?
// return "abcdef".toUpperCase();
}
@Override
public void noDoSomething() {
System.out.println("noDoSomething...");
}
}
上面这个我们同样可以实现同样的需求,但是我们不能这样做,为什么呢?
因为,我们在现实的实际编程中,我们可能拿到别人已经写好的接口,我们是不能去修改别人的代码的,所以我们只能在别人写好的基础之上实现功能的增强。
所以下面我们就该实现静态代理类。
在写该静态代理类之前,我们有几点核心要点是需要注意的:
1、首先,静态代理必须实现和目标类一样的接口
2、然后在控制的时候,我们需要通过代理对象来实现目标类要实现的业务需求
3、在代理类的实现中一般同无参构造函数来关联目标对象
package com.csdn.proxy;
import com.csdn.target.ITarget;
import com.csdn.target.impl.Target;
public class StaticProxy implements ITarget{
private ITarget target = null;
//关联要增强的目标类
//注意,在这里,我们也可以同过带参构造函数将目标对象传过来,这样之后一定要记得添加无参构造器
//public StaticProxy(ITarget target){
// this.target = target;
//}
public StaticProxy() {
target = new Target();
}
//在这里增强目标类的目标方法
@Override
public String beToUpper() {
//增强目标方法
return target.beToUpper().toUpperCase();
}
@Override
public void noDoSomething() {
//没有需增强的方法,直接目标类调用即可
target.noDoSomething();
}
}
测试类
package com.csdn.test;
import com.csdn.proxy.StaticProxy;
import com.csdn.target.ITarget;
public class MyTest {
public static void main(String[] args) {
//创建业务接口
// ITarget target = new Target();
//
// //实现业务需求,直接获取到结果之后转换
// String result = target.beToUpper().toUpperCase();
// System.out.println(result);
//
// //其他方法的调用
// target.noDoSomething();
//使用代理模式==============
//这里我们创建的不再是目标对象,而是通过代理对象来控制目标对象
ITarget proxy = new StaticProxy();
System.out.println(proxy.beToUpper());
proxy.noDoSomething();
}
}
测试结果:
ABCDEF
noDoSomething...
为什么要通过静态代理来实现这样的业务需求
我们上面实现静态代理设计模式之后,我要知道为什么要这样做,因为,我们明显知道这样做之后代码的实现逻辑明显复杂了许多。
所以下面我们就来讲讲为什么要这样做:(注:这个只是我一家之言,个人观点)
首先,上面我们已经有讲到这一点,那就是,在我们的编程过程中,有许多东西,我们都不是从零开始去写,我们需要借助前辈写的好的代码,然后在前辈代码的基础之上,实现对部分功能的增强。
然后,就是在我们编程的过程中,几乎所有的人都是力求简单快捷高效开发,所以到了我们在后面的开发过程中都会大量使用到别人写好的开源框架,如果掌握了一些基础的设计模式之后,有助于我们学习别人的代码,来提高自己。