2021年02月22日java基础第二十七课---代理
java基础第二十七课---代理
什么是代理?
代理模式,就是给一个对象提供一种代理对象以控制对该对象的访问。在这个模式中,我们通过创建代理对象作为“替身”替代了原有对象,从而达到我们控制对象的目的。
代理=代替处理。是由一个对象来代替原对象来处理某些逻辑
举个例子:海外代购—》某人为海外某家公司代购
我们在编码的时候也借鉴了实际生活当中的很多例子,就是我们可不可以让别人解决我们代码当中的问题,或者梳理我们的业务。。能够给我们带来很多更好的帮助,提高代码运行的效率,降低维护成本。
说白了就是给我们来一个替身,替我们做一些我们做起来比较麻烦的事情。
代理模式能给我们带来什么?
代理模式能为我们控制访问某个对象的能力,在某些情况之下,一个对象的某些方法想要进行屏蔽或者某种逻辑的控制,则我们可以通过代理的模式进行。在此能力上,引申出来的作用,也是目前开发中经常使用的一个作用那么就是----“在不修改对象代码的基础上,对原对象的功能进行修改或增强。”
解耦
什么是耦合?
耦合本身是一个工业概念,指的是齿轮像上图一样咬合到一起,一个齿轮运转的时候,其他咬死的齿轮也会发生运转。此概念平移到我们开发领域,就是项目中各个模块或者各个组件,当一个发生变动或者调整的时候,其他一些模块或者组件也会跟着发生变化或者调用,产生强烈的的联系。这样的情况就是说两个模块或者组件耦合到一起了
牵一发而动全身
什么是解耦?
大家看这些齿轮,如果在运行中我们发现一个齿轮大小不对,或者要更换位置,那势必会牵一发而动全身。
当模块或者组件的耦合度过高,会带来难以扩展、维护性差、纠错困难等各种问题,所以我们在设计的时候,我们要尽量避免模块耦合度过高。在设计过程中,削减或者消除耦合度的操作就是解耦。
当我们要给某个对象添加一些额外的逻辑时(比如访问权限控制,日志记录等),使用代理模式我们可以不改动源代码,只针对额外的功能进行编码。在整个过程中原对象的逻辑和额外添加的逻辑解耦,互不干扰。
高扩展性
由于模块间是解耦的,我们随时可以添加任意的功能,或者修改之前的功能而不影响元模块的正常执行,相当于我们的代码像钢铁侠的战衣一样可以随时添加各种战斗模块已使用不同的作战环境。这就是高扩展性。
java中的代理模式:
定义:给目标对象提供一个代理对象,并且由代理对象控制对目标对象的引用
目的:
①:通过代理对象的方式间接的访问目标对象,防止直接访问目标对象给系统带来不必要的复杂性
②:通过代理业务对原有业务进行增强
java当中有三种方式来创建代理对象:静态代理,基于jdk(接口)的动态代理,基于CGLLIB(父类)的动态代理。
相关概念:
目标类:原对象,我们需要代理对象控制他的访问,拓展其功能。
代理类:代理模式产生的对象,是原对象“替身”,已经在原有基础上修改逻辑
静态代理:
静态代理:也就是我们会手写代理类的代码,工程中有代理类的源码,代理类会变以后执行。
编写代理类:实现目标的接口或者直接继承目标类,完成逻辑的修改
接口实现方式:
关于接口的方式,我们在实现接口的时候,目标类和代理类都必须实现目标接口当中所实现的方法,从某种意义上代理类就可以帮我们实现目标类当中的方法,并且代理类还可以有自己的扩展方法。
举例子:1
最开始我们想买东西就必须代购,因为只有代购员才知道真实的工厂在哪里
代码实现:
首先定义接口------相当于工厂地址和功能
public interface ByClothes {
void clothes(String size);
}
- 1
- 2
- 3
定义真实对象—制造衣服的工厂
public class ClothesFactory implements ByClothes {
@Override
public void clothes(String size) {
System.out.println("已经为您制作好了一整套size为"+size+"的衣服。。。。。。。。");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
制造代理对象-------代购
public class proxy implements ByClothes {
//被包含的真是对象
public ClothesFactory factory;
public proxy(ClothesFactory factory) {
// TODO Auto-generated constructor stub
this.factory = factory;
}
@Override
public void clothes(String size) {
FrontService();
factory.clothes(size);
endService();
}
//前置服务
public void FrontService() {
System.out.println("根据您的需求进行市场调研");
}
//前置服务
public void endService() {
System.out.println("为您提供一条龙的包办服务");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
制造测试类------买衣服的人
public class Test {
public static void main(String[] args) {
ClothesFactory clothesFactory = new ClothesFactory();
proxy proxy = new proxy(clothesFactory);
proxy.clothes("XXl");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
真实静态代理
细节:我们的真实对象必须实现我们的接口,同时代理对象也必须实现这一接口
静态代理存在哪些问题?
违反了开闭原则:
程序对外扩展开放,对修改关闭,换句话来说,当需求发生变化时,我们可以增加新模块来解决新需求,而不是通过该变原来的代码来解决我们的新需求
动态代理
举例子:2
当发现这是一个商机的时候,聚拢身边的朋友成立公司
公司的优势
java实现:
1.新建接口
public interface ByShoot {
void byShoot(String size);
}
- 1
- 2
- 3
2.新建工厂
public class ShootFactory implements ByShoot{
@Override
public void byShoot(String size) {
System.out.println("已经为您生产出了尺码为"+size+"的鞋子");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
3.新建海外代购公司
public class LisiFactory implements InvocationHandler {
// 被代理的对象
private Object factory ;
public Object getFactory() {
return factory;
}
public void setFactory(Object factory) {
this.factory = factory;
}
//ssm: Spring SpringMVC mybitys
//Spring:AOP IOC +....
//AOP:代理 (面向切面的编程)
// 通过代理对象对方法进行增强
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
FrontService();
Object retObject = method.invoke(factory, args); //这里用了反射的思想,因为我们不知道调用的是那个工厂的那个方法
endService();
return null;
}
// 前置服务
public void FrontService() {
System.out.println("根据您的需求进行市场调研");
}
// 前置服务
public void endService() {
System.out.println("为您提供一条龙的包办服务");
}
//调度员工
/**
* 1 新建一名员工
* 2.告诉员工工厂地址
* this:绑定
* @return
*/
public Object getProxyInstance() {
// TODO Auto-generated method stub
return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
4.新建测试类—买东西的人
public class Test {
public static void main(String[] args) {
ClothesFactory clothesFactory = new ClothesFactory();
ShootFactory shootFactory = new ShootFactory();
LisiFactory lisiFactory = new LisiFactory();
// lisiFactory.setFactory(shootFactory);
// ByShoot yuangong1 = (ByShoot) lisiFactory.getProxyInstance();
// yuangong1.byShoot("42");
lisiFactory.setFactory(clothesFactory);
ByClothes yuangong = (ByClothes) lisiFactory.getProxyInstance();
ByClothes yuangong2 = (ByClothes) lisiFactory.getProxyInstance();
ByClothes yuangong3 = (ByClothes) lisiFactory.getProxyInstance();
yuangong.clothes("XXL");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
有道云笔记更精彩哦
文档:第二十六课—代理.note