我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择自己喜欢的车,然后付钱就可以了
基本定义
代理模式就是给一个对象提供一个代理,并由代理对象控制对原对象的引用。 在代理模式中,“第三者”代理主要是起到一个中介的作用,它连接客户端和目标对象。
我们有多种不同的方式来实现代理。如果按照代理创建的时期来进行分类的话, 可以分为两种:静态代理、动态代理。
静态代理 是由程序员创建或特定工具自动生成源代码,在对其编译。在程序员运行之前,代理类.class文件就已经被创建了。 优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
动态代理 是在程序运行时通过反射机制动态创建的 相对于静态代理,动态代理大大减少了我们的开发任务,同时减少了对 业务接口的依赖,降低了耦合度。但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。
优缺点
优点 1、 代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
2、 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的
缺点 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、 实现代理模式需要额外的工作,有些代理模式的实现非常复杂
静态代理
package design.proxy;
//抽象角色
public interface BuyHouse {
void byHouse();
}
package design.proxy;
// 真实的具体角色。 只关心最终想要达到的效果,不关心中间的任何流程。
public class BuyHouseImpl implements BuyHouse{
@Override
public void byHouse() {
System.out.println("我要买房子。");
}
}
package design.proxy;
//代理类。1.也是继承自抽象对象,与真实的角色互为兄弟类;2, 通过关联关系,将真是的兄弟角色关联进了该类
public class BuyHouseProxy implements BuyHouse{
//这个类写完之后,如果程序运行,需要将该类进行编译,编译成我们的.class文件。
//简而言之,在程序运行之前,该代理类就被编译了。
BuyHouse buyHouse;
public BuyHouseProxy(BuyHouse buyHouse) {
this.buyHouse = buyHouse;
}
@Override
public void byHouse() {
buyHouse.byHouse();
System.out.println("选择房源");
System.out.println("谈价钱");
System.out.println("最终敲定购买");
}
}
public class testStatic {
public static void main(String[] args) {
System.out.println("====没有使用代理之前===");
BuyHouse b = new BuyHouseImpl();
b.byHouse();
System.out.println("====使用静态代理之后===");
BuyHouseProxy bproxy = new BuyHouseProxy(b);
bproxy.byHouse();
}
}
动态代理
package design.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import design.proxy.BuyHouse;
//动态代理类与静态代理类的不同之处在于 实现的接口不一样。但是达到的效果是一样的。
//静态代理类实现了BuyHouse接口,动态代理类实现了InvocationHandler接口。由于InvocationHandler出自反射包,通过客户端的
//调用,能够将我们的InvocationHandler反射成为我们的BuyHouse接口。
//动态代理类,通过反射进行的代理类的创建,客户端什么时候调用,什么时候创建,也就是说,动态的代理类是在程序运行过程中动态创建的。
//动态代理类,关联了object。这就能够说明我们的动态代理类能够代理多种类型的类、
public class DynamicHouseProxy implements InvocationHandler{
//代理类需要关联我们的真实角色类, buyhouse 只能算是个父亲,这里边为了兼容所有的真实角色
//不仅限于 buyhouse系列,这时候,请出祖宗级别的对象
Object object;
public DynamicHouseProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//调用了 byhouse方法。
//method 是为了引入我们的buyHouse里的方法。
Object result = method.invoke(object, args);
System.out.println("选择房源");
System.out.println("谈价钱");
System.out.println("最终敲定购买");
return result;
}
}
package design.proxy.dynamic;
import java.lang.reflect.Proxy;
import design.proxy.BuyHouse;
import design.proxy.BuyHouseImpl;
public class testDynamic {
public static void main(String[] args) {
BuyHouse b = new BuyHouseImpl(); //真实角色
BuyHouse proxy = (BuyHouse)Proxy.newProxyInstance(BuyHouse.class.getClassLoader(),
new Class[]{BuyHouse.class},
new DynamicHouseProxy(b));
proxy.byHouse();
}
}
总结
1、代理模式是通过使用引用代理对象来访问真实对象,在这里代理对象充当用于连接客户端和真实对象的中介者。
2、代理模式主要用于远程代理、虚拟代理和保护代理。其中保护代理可以进行访问权限控制。