7分钟3个例子理解代理模式,面试多加29分

本文通过三个生动的例子,深入浅出地介绍了代理模式的概念及其在实际编程中的应用,包括代购、房屋中介和论坛发帖权限检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代理模式 (Proxy Pattern) 是一种结构性设计模式。通过代理模式,我们可以不免直接访问目标对象,转而通过代理对象来访问目标对象。同时,我们可以通过代理对象来控制访问权限以及增强功能

让我们用 3 个例子来解释清楚什么是代理模式,以及代理模式所带来的好处。

例子1:代购

代购是讲解代理模式中最常见的例子,那么我们也不能免俗地要来讲讲这个例子。

假设我想要购买 A 品牌的洋奶粉,需要通过代购才能够买到这款羊奶粉,那么我们可以这样说:

  • 抽象主题角色 (Subject)
    买家

  • 真实主题角色 (Real Subject)

  • 代理主题角色 (Proxy)
    代购

通过代码来表示:

// 买家
abstract class Buyer {
	abstract void buy(String item);
}

// 我
public class Me extends Buyer {
	public void buy(String item) {
		System.out.println("购买商品: " + item);
	}
}

// 代购
class BuyingAgent extends Buyer {
	// 代替我买
	private Buyer me = new Me();

	public void buy(String item) {
		System.out.println("我是代购,我正在加拿大温哥华商场");
		me.buy(item);
		System.out.println("购买完毕,准备快递寄回委托人手里");
	}
}

运行程序

public static void main(String[] args) {
	Buyer buyingAgent = new BuyingAgent();
	buyingAgent.buy("A品牌奶粉");
}

运行之后得到的输出结果是

我是代购,我正在加拿大温哥华商场
购买商品: A品牌奶粉
购买完毕,准备快递寄回委托人手里

这个例子体现出了代理模式的基本用法。我们会在代理类中包含一个真实对象,并在调用真实对象方法之前或之后,我们还可以调用其他函数或者是运行其他逻辑代码。

例子2:房屋中介

假设Kevin有一套房子需要出售,然而他并不懂得市场行情,也没有时间与买家周旋,于是Kevin请了一位房屋中介帮忙销售这套房子。

房屋中介除了可以帮Kevin卖出房屋之外,还可以直接拒绝心理价位以下的出价,以及帮助Kevin处理后续的交易文件以及手续,我们可以将这理解为功能增强

在这里,房屋中介的职责就是一个代理人,阻止了买家直接与卖家联系,任何事务都必须通过房屋中介处理。

我们可以这样定义:

  • 抽象主题角色 (Subject)
    卖家

  • 真实主题角色 (Real Subject)
    卖家 Kevin

  • 代理主题角色 (Proxy)
    房屋中介

通过代码来表示:

abstract class Seller {
	abstract void sell(String house, int price);
}

class Kevin extends Seller {
	public void sell(String house, int price) {
		System.out.println("售出房产: " + house + ", 售价: " + price + "万");
	}
}

class Agent extends Seller {
	private Seller seller = new Kevin();
	
	// 卖家可接受最低价格
	private int acceptablePrice = 100;

	public void sell(String house, int price) {
		// 控制访问权限,出价过低不出售
		if (!isPriceAcceptable(price)) {
			System.out.println("抱歉," + price + "万出价过低。");
			return;
		}
		System.out.println("接受出价" + price + "万");
		seller.sell(house, price);
		processDocuments();
	}

	private boolean isPriceAcceptable(int price) {
		return price >= acceptablePrice;
	}

	// 功能增强:帮卖家处理交易手续
	private void processDocuments() {
		System.out.println("处理交易手续");
	}
}

运行程序

public static void main(String[] args) {
	Seller agent = new Agent();
	agent.sell("A套房产", 90);
	agent.sell("A套房产", 100);
}

得到输出结果

抱歉,90万出价过低。
接受出价100万
售出房产: A套房产, 售价: 100万
处理交易手续

在这个例子中,我们看到了代理类可以带来访问权限的控制与其他增强功能。

  • 访问权限控制
    报价过低无法访问真实对象
  • 功能增强
    处理交易手续

例子3:实际编程工作中的应用场景

假设我们在一家软件公司里工作,当前正在开发一款论坛产品。A组的开发人员已经开发好了发布帖子的接口了,而我们的任务则是给这个发布帖子的接口加上发帖权限检查,以及发帖日志记录的功能。

然而这里有个限制,由于这个接口是由A组开发的,因此他们不希望我们动他们的源代码,这在软件公司里是很常见的事情,不同组之间尽量不去动对方的代码,那么我们需要怎么做,才能在不动到对方代码的情况下,实现我们的功能呢?

答案就是:代理模式

先让我们来看看A组开发的接口:

public interface PostService {
	void makePost(String content, int userId);
}

public class PostServiceImpl implements PostService{
	public void makePost(String content, int userId) {
		// 发布帖子的逻辑
		System.out.println("用户" + userId + "发布帖子成功");
	}
}

那么我们可以使用代理模式,创建一个代理类,通过代理类我们会在调用真实对象发布帖子的函数之前先进行权限检查,并在调用真实对象发布帖子的函数之后再调用打日志的函数。

public class PostServiceProxy implements PostService {
	private PostService postService = new PostServiceImpl();

	public void makePost(String content, int userId) {
	
		// 先进性权限检查
		validateAuthentication(userId);
		
		// 再实际调用发帖函数
		postService.makePost(content, userId);
		
		// 之后打上日志
		logActivity("发布帖子", userId);
	}
	
	private void validateAuthentication(int userId) {
		System.out.println("检查用户" + userId + "权限");
	}

	private void logActivity(String activity, int userId) {
		System.out.print("记录用户" + userId + "活动: " + activity);
	}
}

实际运行程序:

public static void main(String[] args) {
	PostService postService = new PostServiceProxy();
	int userId = 1;
	postService.makePost("新人报道帖!", userId);
}

运行结果:

检查用户1权限
用户1发布帖子成功
记录用户1活动: 发布帖子

可以看到,从调用者的角度来看,除了创建的对象是代理类之外,实际用法与真实对象无异,却又能够增加权限检查与打日志两项功能,这便是代理模式的厉害之处。

以下是关于如何在车辆信息表中添示例数据的详细解答: 可以通过以下方法向车辆信息表中添示例数据: ```sql INSERT INTO VehicleInfo (VehicleID, LicensePlate, Brand, Model, Color, ProductionYear, EngineNumber, VIN, OwnerID, RegistrationDate, InsuranceInfo) VALUES (3, '京A67890', 'BMW', 'X5', '黑色', 2020, 'B48123456789', 'WBA1C5C56K0123456', 103, '2020-03-10', 'PICC:RC123456789'); ``` 上述代码将一条新记录插入到`VehicleInfo`表中。每条记录包含所有字段的值,确保与表结构匹配。 ```sql INSERT INTO VehicleInfo (VehicleID, LicensePlate, Brand, Model, Color, ProductionYear, EngineNumber, VIN, OwnerID, RegistrationDate, InsuranceInfo) VALUES (4, '沪B56789', 'Mercedes-Benz', 'E-Class', '银色', 2017, 'M274123456789', 'WDDHF5EB3HA123456', 104, '2017-08-15', 'PingAn:PA987654321'); ``` 通过类似的方式,可以继续添其他示例数据。每次插入时,需确保`VehicleID`唯一,并正确填写所有字段的值。 为了批量插入条记录,可以使用以下语法: ```sql INSERT INTO VehicleInfo (VehicleID, LicensePlate, Brand, Model, Color, ProductionYear, EngineNumber, VIN, OwnerID, RegistrationDate, InsuranceInfo) VALUES (5, '粤C78901', 'Audi', 'A6', '白色', 2019, 'CJT123456789', 'WAUAGF8E3KA123456', 105, '2019-11-20', 'ZhongYi:ZY123456789'), (6, '浙D89012', 'Toyota', 'Camry', '蓝色', 2021, '3ZR123456789', 'JTHBK3DG9L0123456', 106, '2021-02-15', 'PICC:RC987654321'); ``` 这种方法允许一次性插入条记录,从而提高效率并减少重复操作。 对于更复杂的数据管理需求,可以结合编程语言如Python实现自动化插入。例如,使用`pandas`库生成数据并将其插入数据库: ```python import pandas as pd from sqlalchemy import create_engine # 创建示例数据 data = { "VehicleID": [7, 8], "LicensePlate": ["京D12345", "沪C56789"], "Brand": ["Honda", "Toyota"], "Model": ["CR-V", "RAV4"], "Color": ["红色", "灰色"], "ProductionYear": [2022, 2023], "EngineNumber": ["K20123456789", "2AR123456789"], "VIN": ["JHMEC1760AS123456", "JTMZC4DJ7LW123456"], "OwnerID": [107, 108], "RegistrationDate": ["2022-05-10", "2023-01-15"], "InsuranceInfo": ["PingAn:PA111111111", "PICC:RC222222222"] } df = pd.DataFrame(data) # 连接数据库 engine = create_engine('mysql+pymysql://username:password@localhost/dbname') # 将数据插入表中 df.to_sql(name='VehicleInfo', con=engine, if_exists='append', index=False) ``` 上述代码展示了如何利用Python脚本自动生成和插入数据,适合处理大规模数据集或定期更新的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值