一、何为代理
在我们生活中有这样一种场景,当你要去租房时,现在的社会很难直接找到房东本人,找到了房东租房时的很多细节可能把握不定,那么中介应运而生,这也是下面谈静态代理举的例子,房东只有一个需求,那就是赶快帮我把房子出租出去,客户也只有一个需求,尽快找到我满意的房子
二、代理模式的好处
可以使真实角色的任务更加纯粹,不需要去关注一些细节的业务
公共部分交给了代理,实现了业务的分工
公共业务发生扩展的时候,方便集中管理
三、角色分析
1、抽象角色:一般使用接口或抽象类
2、真实角色:被代理的角色
3、代理角色:代理真实角色,代理真实角色后,我们会做一些附属操作
4、客户角色:访问代理对象的人
四、代码实现
1、抽象角色,这里用接口创建一个租房的方法,真实对象实现这个方法(也就是房东)
package cn.kexing.Proxy;
//租房
public interface Rent {
void rent();
}
2、真实角色(房东)
package cn.kexing.Proxy;
//房东
public class Host implements Rent{
//调用抽象角色,出租房子
@Override
public void rent() {
System.out.println("房东要出租房子!");
}
}
3、代理角色,代理房东,帮他完成租房功能,另外代理角色还可以执行额外的操作,必须中介带客户看房,签合同,当然 代理不是白代理的,还要抽点手续费
package cn.kexing.Proxy;
//代理对象 代理房东去出租房子,代理对象可做其他工作
/**
*
*/
public class StaticProxy {
private Host host;
public StaticProxy() {
}
public StaticProxy(Host host) {
this.host = host;
}
public void rent(){
host.rent();
//中介的额外操作
watch();
result();
fee();
}
public void watch(){
System.out.println("中介带客户去看房!");
}
public void result(){
System.out.println("中介带客户签合同!");
}
public void fee(){
System.out.println("中介收取一定的手续费!");
}
}
4、客户
package cn.kexing.Proxy;
//客户,需要租房子
public class Client {
public static void main(String[] args) {
Host host = new Host();
StaticProxy proxy = new StaticProxy(host);
proxy.rent();
}
}
五、再理解静态代理
上面我们说过:公共部分交给了代理,实现了业务的分工 这句话怎么理解,这里有一个场景,当你的上级给你说让你在所有业务代码里增加一条输出日志功能,却又不能更改原有代码,这时就可以用代理实现公共部分功能
1、业务接口
package cn.kexing.Proxy2;
//业务接口
public interface UserService {
void add();
void delete();
void update();
void select();
}
2、业务实现
package cn.kexing.Proxy2;
/**
* 业务接口实现类
*/
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加一个用户");
}
@Override
public void delete() {
System.out.println("删除一个用户");
}
@Override
public void update() {
System.out.println("修改一个用户");
}
@Override
public void select() {
System.out.println("查询一个用户");
}
}
3、代理业务,增加日志
package cn.kexing.Proxy2;
/**
* 若想要修改业务的方法,但又不能修改原有的代码
* 那么创建一个代理类来实现
*/
public class UserServiceProxy {
private UserServiceImpl userService;
public UserServiceProxy() {
}
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
public void add(){
log("add");
userService.add();
}
public void delete(){
log("delete");
userService.delete();
}
public void update(){
log("update");
userService.update();
}
public void select(){
log("select");
userService.select();
}
public void log(String method){
System.out.println("【debug】 实现了"+method+"方法");
}
}
4、客户使用
package cn.kexing.Proxy2;
public class Client {
public static void main(String[] args) {
UserServiceImpl service = new UserServiceImpl();
UserServiceProxy proxy = new UserServiceProxy();
proxy.setUserService(service);
proxy.add();
proxy.delete();
proxy.update();
proxy.select();
}
}
静态代理
- 优点:代码结构简单,较容易实现
- 缺点:无法适配所有代理场景,如果有新的需求,需要修改代理类,不符合软件工程的开闭原则
开闭原则:在编写程序的过程中,软件的所有对象应该是对扩展是开放的,而对修改是关闭的
所以,为了提高类的可扩展性和可维护性,满足开闭原则,Java 提供了动态代理机制。
下篇文章来续动态代理