一、说明
代理模式(百度百科):
- 为其他对象提供一种代理以控制对这个对象的访问。
- 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
二、组成
- 抽象角色(subject):通过接口、抽象类声明真是角色需要的业务方法。
- 代理角色(Proxy)代理真实角色操作。
- 真实角色(RealSubject):实现抽象角色,定义真实角色需要的业务逻辑。
三、类图
四、优缺点
优点:
- 保护目标对象:代理对象可以在客户端和目标对象之间起到中介作用。
- 高拓展性
缺点:
- 我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
五、使用场景
- 房产中介、4s店等类似场景
六、注
细心的同学很容易发现,静态代理的类图和装饰者模式类图基本一致。那么他们有什么区别呢?
- 1.装饰者模式,顾名思义是用来做装饰,也就是拓展使用的。
- 2.代理模式,和装饰者最大的却别就是设计理念。代理模式是具有一定自主性的,全权代理。代理人可以决定是否来调用被代理人的接口。而装饰者模式则没有这种自主性特性。
- 比如4s店可以只在营业9点-18点才买给你车,其他时间就可以不卖。
七、代码举例
(1)subject 抽象接口
/**
* 接口类
*/
public interface ISaleCarInterface {
//卖车
void saleCar();
}
(2) RealSubject 宝马汽车厂
/**
* 被代理人:宝马汽车厂
*/
public class BMW implements ISaleCarInterface{
/**
* 汽车厂商自己卖车需要的手续
*/
@Override
public void saleCar() {
System.out.println("----宝马厂:收钱----");
System.out.println("----宝马厂:签合同----");
System.out.println("----宝马厂:交车----");
}
}
(3) proxy 代理商:4s店
/**
* 代理人:北京4s店分销商
*/
public class ProxyBeiJing4S implements ISaleCarInterface {
/**
* 代理宝马厂卖车
* 代理模式和装饰模式区别:
* 这两种模式实现起来基本一样,
* 但代理模式设计时是具有一定自主性,代理人在某些情况下可以不调用被代理人,也就是4s店有权不卖给某个人。
* 而装饰模式是必须要调用被装饰类的,装饰模式仅仅是对被装饰类做一些前置工作而已。
*/
@Override
public void saleCar() {
GregorianCalendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour < 9 || hour > 18) {
System.out.println("====4s店:下班了,明天再来吧!====");
return;
}
System.out.println("====4s店:收费====");
System.out.println("====4s店:收取佣金====");
System.out.println("====4s店:去厂商取车====");
BMW bmw = new BMW();
bmw.saleCar();
System.out.println("====4s店:给客户推销保险====");
System.out.println("====4s店:交车!====");
}
}
(4) 客户端测试类
public class Test {
public static void main(String[] args) {
//静态代理模式
ProxyBeiJing4S proxy = new ProxyBeiJing4S();
proxy.saleCar();
}
}
执行结果1:
====4s店:收费====
====4s店:收取佣金====
====4s店:去厂商取车====
----宝马厂:收钱----
----宝马厂:签合同----
----宝马厂:交车----
====4s店:给客户推销保险====
====4s店:交车!====
执行结果2:
====4s店:下班了,明天再来吧!====