package com.zhaoshuangjian.mode04_代理模式;
import com.zhaoshuangjian.mode04_代理模式.mode04.NP非代理.UserOwn;
import com.zhaoshuangjian.mode04_代理模式.mode04.ProxyFactory;
import com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理.Secretary;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.DogImpl;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.UserImpl;
/**
* ProxyTest 代理模式
*
* @Auther: zhaoshuangjian 2023-03-23 下午10:39
*/
public class ProxyTest {
public static void main(String[] args) {
String uName = "奥利奥饼干";
String dName = "狗粮";
// 1、不使用代理
noProxy(uName);
// 2、使用静态代理
useStaticProxy(uName,dName);
// 3、使用动态代理
useDynamicProxy(uName, dName);
int second = 5;
// 4、使用虚拟代理
useVirtualProxy(second);
/**
* 不使用代理:没有对比就没有伤害,主要和下面使用了代理模式的对象进行比较
* 静态代理:针对特定对象的访问进行"装饰",虽和装饰者模式很像,但也只是很像,切记搞混淆
* 动态代理:区别静态代理,静态代理模式在程序编译时即确定了被代理的对象
* 而动态代理只有在程序运行时才确定要被代理的对象是谁
* 动态代理主要应用于框架,即反射技术一般用不到,如果用到了,那多半是用于框架级的项目
* 典型代表:Spring框架 -- AOP【面向切面编程】
* 虚拟代理:可延缓被代理对象的创建
* 优点: 程序启动快
* 缺点: 因为被代理的实例不是在第一时间创建的,因此在使用的时候,
* 需要狠小心的判断null值,以防止NullPointException
*
* 还有其他代理模式,就不一一列举了
*/
}
/**
* 不使用代理
* @param uName 用户商品名称
*/
private static void noProxy(String uName) {
// 不使用代理模式,用户自己去超市买商品
UserOwn userOwn = new UserOwn();
userOwn.getCommodity(uName);
System.out.println("===========分割线===========");
}
/**
* 使用静态代理
* @param uName 用户商品名称
* @param dName 宠物狗商品名称
*/
private static void useStaticProxy(String uName,String dName) {
// 使用静态代理模式,通过UU跑腿服务,用户拿到自己要的薯片
ProxyFactory.getUserProxy().getCommodity(uName);
System.out.println("===========分割线===========");
// 使用静态代理模式,通过UU跑腿服务,宠物狗拿到自己要的狗粮
ProxyFactory.getDogProxy().getCommodity(dName);
System.out.println("===========分割线===========");
}
/**
* 使用动态代理
* @param uName 用户商品名称
* @param dName 宠物狗商品名称
*/
private static void useDynamicProxy(String uName, String dName) {
// 使用动态代理模式,通过UU跑腿服务,用户拿到自己要的薯片
CommodityService userProxy =(CommodityService)( ProxyFactory.getDynProxy(new UserImpl()));
userProxy.getCommodity(uName);
System.out.println("===========分割线===========");
// 使用动态代理模式,通过UU跑腿服务,宠物狗拿到自己要的狗粮
CommodityService dogProxy =(CommodityService)( ProxyFactory.getDynProxy(new DogImpl()));
dogProxy.getCommodity(dName);
System.out.println("===========分割线===========");
}
/**
* 使用虚拟代理
* @param second 秒数
*/
private static void useVirtualProxy(int second){
Secretary secretary = new Secretary();
secretary.addDeal("合同1");
secretary.addDeal("合同2");
secretary.sign();
// 期望领导什么时候出现
secretary.initLeader(second);
secretary.addDeal("合同3");
secretary.addDeal("合同4");
secretary.sign();
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04;
import com.zhaoshuangjian.mode04_代理模式.mode04.DP动态代理.DynamicProxy;
import com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理.DogProxy;
import com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理.UserProxy;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* 代理类工厂
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class ProxyFactory {
/**
* 获取一个静态用户代理类对象
*/
public static CommodityService getUserProxy() {
return new UserProxy();
}
/**
* 获取一个静态宠物狗的代理类对象
*/
public static CommodityService getDogProxy() {
return new DogProxy();
}
/**
* 获取动态代理对象
* @param target
* @return
*/
public static Object getDynProxy(Object target) {
InvocationHandler handler = new DynamicProxy(target);
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.DP动态代理;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理类 == 程序运行时,代理类才知道被代理的对象是哪个
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class DynamicProxy implements InvocationHandler {
/**
* 被代理的目标对象
*/
private Object targetObj;
/**
* 暂时不知道被代理的对象是人还是动物或是其它...etc
*/
public DynamicProxy(Object object) {
this.targetObj = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是UU跑腿的工作人员,我去超市帮助客户取商品:"+args[0]);
Object object = method.invoke(targetObj, args);
System.out.println("拿到被代理对象调用的方法名:"+method.getName()+",方法参数个数:"+method.getParameterCount());
System.out.println("商品已成功转交给被代理的对象,期待对象好评");
return object;
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.NP非代理;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
/**
* 用户自己去超市取商品
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class UserOwn implements CommodityService {
@Override
public void getCommodity(String name) {
goSuperMarket();
choose(name);
pay();
System.out.println("用户获得商品:"+name);
goHome();
}
private void goSuperMarket() {
System.out.println("去超市");
}
private void choose(String name) {
System.out.println("选商品: " + name);
}
private void pay() {
System.out.println("付钱");
}
private void goHome() {
System.out.println("买完商品,回家");
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.service;
/**
* 商品接口
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public interface CommodityService {
/**
* 获取指定商品
*/
void getCommodity(String name);
}
package com.zhaoshuangjian.mode04_代理模式.mode04.service.impl;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
/**
* 宠物狗实现商品接口 == 获取狗粮
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class DogImpl implements CommodityService{
@Override
public void getCommodity(String name) {
System.out.println("宠物狗获得商品:"+name);
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.service.impl;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
/**
* 用户实现商品类 == 获取吃的
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class UserImpl implements CommodityService{
@Override
public void getCommodity(String name) {
System.out.println("用户获得商品:"+name);
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.DogImpl;
/**
* 宠物狗代理类 == 静态代理模式
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class DogProxy implements CommodityService{
private DogImpl dog;
public DogProxy(){
// 预先确定代理与被代理者的关系 -- 被代理的对象是宠物狗
dog = new DogImpl();
}
@Override
public void getCommodity(String name) {
System.out.println("我是UU跑腿的工作人员,我去超市帮助狗狗取狗粮:"+name);
dog.getCommodity(name);
System.out.println("商品已成功交给狗狗,期待狗狗的主人好评");
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.UserImpl;
/**
* 用户代理类 == 静态代理模式,被代理的对象在编译时就知道了
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class UserProxy implements CommodityService{
/**
* 区别于装饰者模式,这里的被代理的对象的实例是在代理的类中完成实例化的,不对外暴露
* 虽然代理模式有点类似于装饰者模式,但是本质上还是有区别的
* 1、代理模式主要是控制某个特定对象的访问
* 2、装饰模式主要是给对象添加行为
* 3、不是所有实现了接口的类对象都可以成为被代理的对象【要深刻理解这句话】
* 4、所有实现了接口的类对象都可以成为被装饰的对象
*/
private UserImpl user;
public UserProxy() {
// 预先确定代理与被代理者的关系 -- 被代理的对象是人
user = new UserImpl();
}
@Override
public void getCommodity(String name) {
System.out.println("我是UU跑腿的工作人员,我去超市帮助用户取商品:"+name);
user.getCommodity(name);
System.out.println("商品已成功交给用户,期待用户好评");
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* 领导 == 实现签订接口
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class Leader implements Signable{
{
System.out.println("各位久等了,我来了!");
}
/**
* 合同列表
*/
private List deals;
public Leader() {
deals = new LinkedList<>();
}
public List getDeals() {
return deals;
}
public void setDeals(List deals) {
this.deals = deals;
}
public void addDeal(String deal){
this.deals.add(deal);
}
public void addDeals(List deals){
this.deals.addAll(deals);
}
@Override
public void sign() {
Collections.sort(this.deals);
for (String deal : deals) {
System.out.println("领导签订了合同:"+deal);
}
System.out.println();
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理;
import java.util.LinkedList;
import java.util.List;
/**
* 领导身边的秘书 == 将领导作为被代理的对象,但是会延缓被代理对象的创建时间,最后实现签订接口
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public class Secretary implements Signable{
/**
* 合同列表 == 当领导在的时候,这个合同列表会递交给老板,反之,则先放在秘书这里
*/
private List deals;
private Leader leader;
public Secretary() {
this.deals = new LinkedList<>();
}
/**
* 添加一份合同
*/
public void addDeal(String deal){
// 如果领导不在的话,秘书先揽收
if(leader == null){
this.deals.add(deal);
System.out.println("秘书揽收了合同:"+deal);
}else{
// 否则,直接递交给领导
this.leader.addDeal(deal);
System.out.println("领导亲自揽收了合同:"+deal);
}
}
@Override
public void sign() {
if(leader == null){
System.out.println("领导不在,请稍等");
}else{
// 否者的话,领导将秘书揽收的合同拿过来
this.leader.addDeals(this.deals);
this.leader.sign();
}
}
static class LeaderFactory{
public static Leader getLeader(){
return new Leader();
}
}
public void initLeader(int second){
int n = 0;
do{
System.out.println("等待领导出现:"+(++n)+"秒");
}while(--second>0);
this.leader = LeaderFactory.getLeader();
}
}
package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理;
/**
* 签订接口
*
* @Author zhaoshuangjian 2023-03-23 下午10:39
*/
public interface Signable {
/**
* 定义签订方法
*/
void sign();
}