代理模式(Prototype Pattern)– 设计模式之结构型模式:
目录
代理模式(Prototype Pattern)
定义:Provide a surrogate or placeholder for another object to control access to it.
为其它对象提供一种代理以控制对这个对象的访问
类图
代理模式通用类图:
保护代理:根据访问权限决定用户是否访问对象的代理。
例子-美食店:
过程:
在生活中,有一些特色小吃店,比如煎饼果子点,每天制作的分量只有300份,卖完就打烊了。牛肉点,没有新鲜牛肉,差不多就打烊了。
类图:
代码:
客户 Customer
public class Customer {
private final String name;
public Customer(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
美食店 FoodShop
public interface FoodShop {
void enter(Customer customer);
}
煎饼果子店 BattercakeShop
public class BattercakeShop implements FoodShop {
public void enter(Customer customer) {
System.out.println(customer+" 来到煎饼果子店。");
}
}
拉面店 StretchedNoodlesShop
public class StretchedNoodlesShop implements FoodShop {
public void enter(Customer customer) {
System.out.println(customer+"来到拉面店");
}
}
美食店代理 SwitchInvoke
public class FoodShopProxy implements FoodShop {
private static final int NUM_CUSTOMER_ALLOWED = 2;
private int numCustomers;
private final FoodShop foodShop;
FoodShopProxy(FoodShop foodShop) {
this.foodShop = foodShop;
}
@Override
public void enter(Customer customer) {
if (numCustomers < NUM_CUSTOMER_ALLOWED) {
foodShop.enter(customer);
numCustomers++;
} else {
System.out.println(customer+",抱歉,今天东西卖完了,请明天早点来!");
}
}
}
在代理类中,实现引入代理对象的内容,并实现要代理的行动。用于美食店代理,控制每天的进店人数。
测试:,
public class FoodShopProxyTest {
public static void main(String[] args) {
System.out.println("====== 煎饼果子店 ======");
FoodShopProxy proxy = new FoodShopProxy(new BattercakeShop());
proxy.enter(new Customer("张三"));
proxy.enter(new Customer("李四"));
proxy.enter(new Customer("王五"));
proxy.enter(new Customer("赵六"));
System.out.println("====== 拉面店 ======");
proxy = new FoodShopProxy(new StretchedNoodlesShop());
proxy.enter(new Customer("小红"));
proxy.enter(new Customer("小明"));
proxy.enter(new Customer("小兰"));
proxy.enter(new Customer("小虎"));
proxy.enter(new Customer("小花"));
}
}
结果:
====== 煎饼果子店 ======
张三 来到煎饼果子店。
李四 来到煎饼果子店。
王五,抱歉,今天东西卖完了,请明天早点来!
赵六,抱歉,今天东西卖完了,请明天早点来!
====== 拉面店 ======
小红来到拉面店
小明来到拉面店
小兰,抱歉,今天东西卖完了,请明天早点来!
小虎,抱歉,今天东西卖完了,请明天早点来!
小花,抱歉,今天东西卖完了,请明天早点来!
分析
代理实现,最重要的是在代理类中,实现引入代理对象的内容,并实现要代理的行动。实际中,经常把一些业务让别人帮忙做,比如例子中的,让代理去控制进店的人数,还可以代理卖商品。
总结:
优点:
1、职责清晰。
2、高扩展性。
3、智能化。
缺点:
1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
使用场景
1,远程代理(Remote Proxy):也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
2,虚拟代理(Virtual Proxy):根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象
3,安全代理(Safe Proxy):用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候
4,防火墙代理(FireWall Proxy):控制网络资源的访问,保护主题免于“坏客户”的侵害
5,智能引用代理(Smart Reference Proxy):当主题被引用时,进行额外的动作,例如计算一个对象被引用的次数。
6,缓存代理(Caching Proxy):为开销大的运算结果提供暂时存储,它也允许多个客户共享结果,以减少计算或网络延迟。
7,同步代理(Synchronization Proxy):在多线程的情况下为主题提供安全的访问
8,复杂隐藏代理(Complexity Hiding Proxy):用来隐藏一个类的复杂集合的复杂度,并进行访问控制,有时候也称为外观代理(Façade Proxy),这不难理解。复杂隐藏代理和外观模式是不一样的,因为代理控制访问,而外观模式只提供另一组接口。
9,写入时复杂代理(Copy-On-Write Proxy):用来控制对象的复制,方法是延迟对象的复制,知道客户真的需要为止。这是虚拟代理的变体。