代理模式也称委托模式,是结构型设计模式之一,在实际应用中使用非常广泛,因此我们必须掌握这个设计模式。
定义:为一个对象提供一个代理对象,通过这个代理对象控制这个对象的行为。
使用场景:
-
直接访问或者控制对象的行为困难的时候,可以通过对象的代理对象间接控制对象的行为,为了使用简单透明,委托对象和代理对象需要实现相同的接口,即同类型,使用方法一样。
-
可以一定程度上保证对象的安全性。即不必直接将对象暴露给客户端,而是暴露该对象的代理对象给客户端,使得将该对象更加安全。但这不是主要的,不然就直接用原型模式了。
和适配器模式的区别:
-
适配器模式是为了一个接口不兼容而导致该接口不能直接使用而用适配器去为该接口适配以到达可以使用的目的,可能需要添加接口的行为(扩展)。
-
代理模式为了使得直接控制一个类的行为困难而使用和该类具有相同行为(实现了相同的接口)的代理对象代替原对象的行为(间接控制),不会添加接口的行为(只是代替而已)。
今年过年小明嫌收到的压岁钱太少了,生气了,马上就要开学了,自己不愿自己去学校报道了,那怎么办,小明的父母可不能让小明不报道啊,但又拿小明没办法,那只好自己代替小明去给小明报道了呗,于是带着小明的寒假作业去学校给小明报道了…
以上面的这个例子为例实现代码模式:
代码实现:
报道的行为(接口)
~~~
/**
* 开学报道行为(接口)
* @author lt
*
*/
public interface Report {
// 去学校
void goSchool();
// 交学费
void pay();
// 领书本
void getBook();
// 回家
void goHome();
}
~~~
学生(被代理的对象)
~~~
/**
* 学生 (被代理对象)
* @author lt
*
*/
public class Student implements Report{
@Override
public void goSchool() {
System.out.println("开开心心地去学校报道了");
}
@Override
public void pay() {
System.out.println("交了4000学费!");
}
@Override
public void getBook() {
System.out.println("领取了6本书!");
}
@Override
public void goHome() {
System.out.println("总算报道完了,回家了!");
}
}
~~~
家长(代理对象)
~~~
/**
* 家长 (代理对象)
* @author lt
*
*/
public class Parent implements Report{
private Report student; // 持有被代理对象的引用
public Parent(Report student){
this.student = student;
}
@Override
public void goSchool() {
student.goSchool();
}
@Override
public void pay() {
student.pay();
}
@Override
public void getBook() {
student.getBook();
}
@Override
public void goHome() {
student.goHome();
}
}
~~~
测试:(具体的一次报道行为)
~~~
public class Test {
public static void main(String[] args) {
// 小明15岁了,现在在上初中
Report children = new Student();
// 小明今年过年没收到去年那么多的压岁钱,不高兴了,去年都是自己去报道,今年不去了
Parent parent = new Parent(children);
parent.goSchool();
parent.pay();
parent.getBook();
parent.goHome();
}
}
~~~
![这里写图片描述](https://box.kancloud.cn/2016-03-17_56ea5b37bc3df.jpg "")
通常开学报道的时候都好开心的,因为毕竟刚完年,收到不少压岁钱,还等着快点去学校花呢。但小明太侨情了,嫌压岁钱太少了,宁死也不去报道,要小明自己去学校报道太难了,小明的父母只好代替小明去报名了。代替小明去报名也不只有父母才可以哦,还可以是自己的亲戚或者其他和关系好的朋友也行。当然,小明的父母也可以代替别人家的孩子报道,比如亲戚或者朋友的孩子报道。这说明了,当控制一个对象的行为难的时,可以通过代理对象代替具有一组实现了相同接口的对象的行为,而一个对象也可以有其他的代理对象,前提是两者实现了相同的接口,即具有相同的行为。
总结:
代理模式的例子无论是在生活中还是在代码世界里都很常见,使用广泛,具有解决某些需求的优点,同时也具有设计模式的通病,那就是类的增加。掌握设计模式关键在于理解,而不是死记模板,当我在写代码的时候在某些特定场合可以自然而然地将我们的设计模式融入应用到我们的程序中,使得我们的程序结构更加清晰,灵活性高,易于扩展等等。