23种设计模式_MODE04代理模式_手写代码实现

在这里插入图片描述

1.ProxyTest 代理模式

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();

    }

}

2.代理类工厂

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;

/**
 * <p>代理类工厂</p>
 *
 * @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);
	}

}

3.动态代理类 == 程序运行时,代理类才知道被代理的对象是哪个

package com.zhaoshuangjian.mode04_代理模式.mode04.DP动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * <p>动态代理类 == 程序运行时,代理类才知道被代理的对象是哪个</p>
 *
 * @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;
	}

}

4.用户自己去超市取商品

package com.zhaoshuangjian.mode04_代理模式.mode04.NP非代理;

import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;

/**
 * <p>用户自己去超市取商品 </p>
 *
 * @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("买完商品,回家");
	}

}

5.商品接口

package com.zhaoshuangjian.mode04_代理模式.mode04.service;

/**
 * <p>商品接口</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public interface CommodityService {

	/**
	 * 获取指定商品
	 */
	void getCommodity(String name);

}

6.宠物狗实现商品接口 == 获取狗粮

package com.zhaoshuangjian.mode04_代理模式.mode04.service.impl;

import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;

/**
 * <p>宠物狗实现商品接口 == 获取狗粮</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class DogImpl implements CommodityService{

	@Override
	public void getCommodity(String name) {
		System.out.println("宠物狗获得商品:"+name);
	}

}

7.用户实现商品类 == 获取吃的

package com.zhaoshuangjian.mode04_代理模式.mode04.service.impl;

import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;

/**
 * <p>用户实现商品类 == 获取吃的</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class UserImpl implements CommodityService{

	@Override
	public void getCommodity(String name) {
		System.out.println("用户获得商品:"+name);
	}

}

8.宠物狗代理类 == 静态代理模式

package com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理;

import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.DogImpl;

/**
 * <p>宠物狗代理类 == 静态代理模式</p>
 *
 * @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("商品已成功交给狗狗,期待狗狗的主人好评");
	}

}

9.用户代理类 == 静态代理模式,被代理的对象在编译时就知道了

package com.zhaoshuangjian.mode04_代理模式.mode04.SP静态代理;

import com.zhaoshuangjian.mode04_代理模式.mode04.service.CommodityService;
import com.zhaoshuangjian.mode04_代理模式.mode04.service.impl.UserImpl;

/**
 * <p>用户代理类 == 静态代理模式,被代理的对象在编译时就知道了</p>
 *
 * @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("商品已成功交给用户,期待用户好评");
	}

}

10.领导 == 实现签订接口

package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>领导 == 实现签订接口</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class Leader implements Signable{

	{
		System.out.println("各位久等了,我来了!");
	}
	
	/**
	 * 合同列表
	 */
	private List<String> deals;
	
	public Leader() {
		deals = new  LinkedList<>();
	}

	public List<String> getDeals() {
		return deals;
	}

	public void setDeals(List<String> deals) {
		this.deals = deals;
	}

	public void addDeal(String deal){
		this.deals.add(deal);
	}
	
	public void addDeals(List<String> deals){
		this.deals.addAll(deals);
	}

	@Override
	public void sign() {
		Collections.sort(this.deals);
		for (String deal : deals) {
			System.out.println("领导签订了合同:"+deal);
		}
		System.out.println();
	}

}

11.领导身边的秘书 == 将领导作为被代理的对象,但是会延缓被代理对象的创建时间,最后实现签订接口

package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理;

import java.util.LinkedList;
import java.util.List;

/**
 * <p>领导身边的秘书 == 将领导作为被代理的对象,但是会延缓被代理对象的创建时间,最后实现签订接口</p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public class Secretary implements Signable{

	/**
	 * 合同列表 == 当领导在的时候,这个合同列表会递交给老板,反之,则先放在秘书这里
	 */
	private List<String> 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();
	}

}

12.签订接口

package com.zhaoshuangjian.mode04_代理模式.mode04.VP虚拟代理;

/**
 * <p>签订接口 </p>
 *
 * @Author zhaoshuangjian  2023-03-23 下午10:39
 */
public interface Signable {
	/**
	 * 定义签订方法
	 */
	void sign();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhaoshuangjian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值