2024年java实战,轻松理解魔法般的代理模式_java代理模式实战,网易云的朋友给我这份339页的大数据开发面经

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

*/
public class Worker {
/**
* 打工人的名字
*/
private final String name;

public Worker(String name) {
	this.name = name;
	System.out.println(MessageFormat.format("打工人[{0}],为了得到自己想要的东西拼命赚钱。", name));
}

public void buy(INotebookSeller seller, int quantity) {
	System.out.println(MessageFormat.format("打工人[{0}]要买[{1}]个笔记本。", name, quantity));
	seller.sell(quantity);
}

private static void newDays() {
	System.out.println();
	System.out.println("有一天:");
}

public static void main(String[] args) {
	// 打工人的故事开始了
	newDays();
	INotebookSeller seller = new NotebookFactory("大当家的");
	Worker worker = new Worker("小明");
	worker.buy(seller, 5);
}

}


为了减少一个类,我就直接把main方法写在客户端角色了。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210718214924531.png)


一般情况下,这样就已经圆满了。但是好景不长,因为工厂都开在比较偏僻的地方,大家买笔记本太不方便了。于是需求出现了,机会也出现了,然而工厂和打工人都不愿意因此做出改变,那样代价太大了。




---


## 静态代理的出现


代理角色作为客户端角色和真实主题角色的中介。


例子中,我们用商店作为代理角色。



package com.secondgod.proxy;

import java.text.MessageFormat;

/**
* 商店(代理主题)
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class Store implements INotebookSeller {
/**
* 名称
*/
private final String name;
/**
* 供应商品的工厂
*/
private final NotebookFactory notebookFactory;
/**
* 合同约定按照固定量的倍数采购
*/
private final int purchaseQuantity;
/**
* 库存
*/
private int stockBalance;

public Store(String name, NotebookFactory notebookFactory, int purchaseQuantity) {
	this.name = name;
	this.notebookFactory = notebookFactory;
	this.purchaseQuantity = purchaseQuantity;
	System.out.println(MessageFormat.format("[{0}]的笔记本商店开业了,请笔记本工厂做了自己的供应商,他们约定每次按照[{1}]个的倍数采购。", name, purchaseQuantity));
}


@Override
public void sell(int quantity) {
	if (quantity > stockBalance) {
		int needPurchaseQuantity = ((quantity - stockBalance) + (purchaseQuantity - 1)) / purchaseQuantity \* purchaseQuantity;
		System.out.println(MessageFormat.format("商店笔记本库存不足,于是向供应商采购了[{0}]个。", needPurchaseQuantity));
		notebookFactory.sell(needPurchaseQuantity);
		stockBalance += needPurchaseQuantity;
	}
	stockBalance -= quantity;
	System.out.println(MessageFormat.format("商店卖出了[{0}]个笔记本,库存余[{1}]个。", quantity, stockBalance));
}

}


我们还需要对main方法做一点修改来引入代理角色。需要注意的是,我们的客户端角色,抽象主题角色和真实主题角色都不需要做修改。



package com.secondgod.proxy;

import java.text.MessageFormat;

/**
* 打工人
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class Worker {
/**
* 打工人的名字
*/
private final String name;

public Worker(String name) {
	this.name = name;
	System.out.println(MessageFormat.format("打工人[{0}],为了得到自己想要的东西拼命赚钱。", name));
}

public void buy(INotebookSeller seller, int quantity) {
	System.out.println(MessageFormat.format("打工人[{0}]要买[{1}]个笔记本。", name, quantity));
	seller.sell(quantity);
}

private static void newDays() {
	System.out.println();
	System.out.println("有一天:");
}

public static void main(String[] args) {
	// 打工人的故事开始了
	newDays();
	NotebookFactory notebookFactory = new NotebookFactory("大当家的");
	INotebookSeller seller = new Store("二当家的", notebookFactory, 10);
	Worker worker = new Worker("小明");
	worker.buy(seller, 15);
}

}


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210718220004684.png)


商店作为代理,做了库存储备,这样打工人只需要在自己家楼下就能很快买到笔记本了。


但是当抽象主题,真实主题增加时,静态代理就显得不太合理了,因为它要跟着一起改变。


比如,很快又有了钢笔的卖家,和钢笔厂,商店想要代理,就需要做出改变,之后每次要代理卖新的东西,商店都要做出调整,商店不开心了。




---


## 动态代理的出现


商店做大做强后,发现其实各种卖家和工厂都有着一些共性,而客户端也有着相似的需求,所以商店决定成立一个平台,想办法统一流程。


引入新的抽象主题,钢笔卖家。



package com.secondgod.proxy;

/**
* 钢笔卖家(抽象主题角色)
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public interface IPenSeller {

/\*\*

* 卖钢笔
*
* @param quantity
*/
void sell(int quantity);
}


引入新的真实主题,钢笔工厂。



package com.secondgod.proxy;

import java.text.MessageFormat;

/**
* 钢笔工厂(真实主题)
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class PenFactory implements IPenSeller {
/**
* 厂长名
*/
private final String name;

public PenFactory(String name) {
	this.name = name;
	System.out.println(MessageFormat.format("[{0}]的钢笔工厂开业了。", name));
}

@Override
public void sell(int quantity) {
	System.out.println(MessageFormat.format("[{0}]卖掉[{1}]个钢笔。", name, quantity));
}

}


引入新的代理,电商平台,很快我们就可以看到动态代理相对于静态代理的优势。



package com.secondgod.proxy;

import java.lang.reflect.Proxy;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
* 平台
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class Platform {
/**
*
*/
private final String name;
/**
* 平台下的卖家
*/
private final Map<Class<?>, Object> storeMap = new HashMap<>();

public Platform(String name) {
    this.name = name;
    System.out.println(MessageFormat.format("[{0}]的电商平台开业了。", name));
}

/\*\*

* 供普通卖家注册为平台卖家
*
* @return
*/
public void registerStore(String name, Class clazz, T factory, int purchaseQuantity) {
T seller = (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[]{clazz}, new PlatformStore(name, this, factory, purchaseQuantity));
storeMap.put(clazz, seller);
}

/\*\*

* 供用户查找
*
* @return
*/
public T findStore(Class clazz) {
return (T) storeMap.get(clazz);
}
}


平台化以后,商店也要有所改变。



package com.secondgod.proxy;

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

/**
* 平台店
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class PlatformStore implements InvocationHandler {
/**
* 商品名
*/
private final String name;
/**
* 平台
*/
private final Platform platform;
/**
* 背后是真实卖家
*/
private final Object factory;
/**
* 合同约定按照固定量的倍数采购
*/
private final int purchaseQuantity;
/**
* 库存
*/
private int stockBalance;

public PlatformStore(String name, Platform platform, Object factory, int purchaseQuantity) {
    this.name = name;
    this.platform = platform;
    this.factory = factory;
    this.purchaseQuantity = purchaseQuantity;
    System.out.println(MessageFormat.format("平台的[{0}]商店开业了,请[{1}]工厂做了自己的供应商,他们约定每次按照[{2}]个的倍数采购。", name, name, purchaseQuantity));
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    int quantity = (int) args[0];
    if (quantity > stockBalance) {
        int needPurchaseQuantity = ((quantity - stockBalance) + (purchaseQuantity - 1)) / purchaseQuantity \* purchaseQuantity;
        System.out.println(MessageFormat.format("平台[{0}]库存不足,于是向供应商采购了[{1}]个。", name, needPurchaseQuantity));
        args[0] = needPurchaseQuantity;
        method.invoke(factory, args);
        stockBalance += needPurchaseQuantity;
    }
    stockBalance -= quantity;
    System.out.println(MessageFormat.format("平台卖出了[{0}]个[{1}],库存余[{2}]个。", quantity, name, stockBalance));
    return null;
}

}


接下来就是我们的买方,他除了想要买笔记本,也想要买钢笔了。main方法将描绘一个新的故事。



package com.secondgod.proxy;

import java.text.MessageFormat;

/**
* 打工人
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class Worker {
/**
* 打工人的名字
*/
private final String name;

public Worker(String name) {
    this.name = name;
    System.out.println(MessageFormat.format("打工人[{0}],为了得到自己想要的东西拼命赚钱。", name));
}

public void buy(INotebookSeller seller, int quantity) {
    System.out.println(MessageFormat.format("打工人[{0}]要买[{1}]个笔记本。", name, quantity));
    seller.sell(quantity);
}

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

, name, quantity));
seller.sell(quantity);
}

[外链图片转存中…(img-pfJC49gK-1715574743920)]
[外链图片转存中…(img-5AP6B4HF-1715574743920)]
[外链图片转存中…(img-4G2wkoQx-1715574743921)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值