1、静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真实角色,代理真实角色后,会做一些附属操作。
- 客户:访问代理对象的人
代码步骤:
-
接口
package com.Lv; /** * @Author: Lv * @Description:租房这个操作作为接口 * @Vision: 1.0 * @Date: Created in 10:14 2020/8/4 */ public interface Rent { //出租房子 void hire(); }
-
真实角色
package com.Lv; /** * @Author: Lv * @Description:房东要出租房子,实现租房接口 * @Vision: 1.0 * @Date: Created in 10:15 2020/8/4 */ public class Host implements Rent { public void hire() { System.out.println("房东要出租房子"); } }
-
代理角色
package com.Lv; /** * @Author: Lv * @Description:中介负责将所有房东的房子集中管理,出租给租客, * 并进行一些附属操作,例:收中介费 * @Vision: 1.0 * @Date: Created in 10:22 2020/8/4 */ public class Intermediary implements Rent { //房东向出租房子,但有不想去找租客以及做一些签合同什么的操作, // 只想租出去收租金,于是交给中介。 private Host host; public Intermediary() { } public Intermediary(Host host) { this.host = host; } //中介也要出租房子 public void hire() { //中介租出的是房东的房子 host.hire(); fare(); contract(); } //中介附属操作,收中介费 public void fare(){ System.out.println("中介收中介费"); } public void contract(){ System.out.println("中介签租赁合同"); } }
-
客户端访问代理角色
package com.Lv; /** * @Author: Lv * @Description:租客要租房子 * @Vision: 1.0 * @Date: Created in 10:29 2020/8/4 */ public class Custom { public static void main(String[] args) { //租客看中的房子是哪个房东的 Host host = new Host(); //租客要租房子,找中介,说明看中的是哪个房东的房子,和中介完成其他操作 Intermediary intermediary = new Intermediary(host); intermediary.hire(); } }
代理模式的好处:
- 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
- 公共的业务就交给代理角色,实现了业务的分工。
- 公共业务发生扩展时,方便集中管理。
缺点:
- 一个真实角色就会产生一个代理角色;代码量会翻倍,开发效率会变低。
2、代理模式再理解
这是一个正常的业务
public interface UserDao {
//增加用户
void addUser();
//删除用户
void deleteUser();
//修改用户
void updateUser();
//查询用户
void queryUser();
}
public class UserDaoImpl implements UserDao {
public void addUser() {
System.out.println("增加一个用户");
}
public void deleteUser() {
System.out.println("删除一个用户");
}
public void updateUser() {
System.out.println("修改一个用户");
}
public void queryUser() {
System.out.println("查询一个用户");
}
}
public interface UserService {
//增加用户
void addUser();
//删除用户
void deleteUser();
//修改用户
void updateUser();
//查询用户
void queryUser();
}
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl();
public void addUser() {
userDao.addUser();
}
public void deleteUser() {
userDao.deleteUser();
}
public void updateUser() {
userDao.updateUser();
}
public void queryUser() {
userDao.queryUser();
}
}
//模拟Servlet
public class User {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.addUser();
}
}
这时,我们在这条已经正常运行的业务上想增加一个日志输出功能,可以通过修改原有代码完成,但修改原有已经跑起来的代码时大忌了,这时,就可以用代理模式完成。
增加一个代理类
package com.Lv.demo02;
import com.Lv.demo02.service.UserService;
import com.Lv.demo02.service.UserServiceImpl;
/**
* @Author: Lv
* @Description:代理类
* @Vision: 1.0
* @Date: Created in 11:17 2020/8/4
*/
public class UserServiceProxy implements UserService {
private UserServiceImpl userService;
//通过set注入要代理的对象
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
public void addUser() {
//调用service的方法,实现增加用户
userService.addUser();
log("增加用户");
}
public void deleteUser() {
userService.deleteUser();
log("删除用户");
}
public void updateUser() {
userService.updateUser();
log("修改用户");
}
public void queryUser() {
userService.queryUser();
log("查询用户");
}
//日志
public void log(String msg){
System.out.println("实现了"+msg+"方法");
}
}
用户调用代理类
public class User {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
//这时用户只需要调用代理对象即可
UserServiceProxy userServiceProxy= new UserServiceProxy();
userServiceProxy.setUserService(userService);
//这时用户调用代理对象的方法访问真实对象的方法
userServiceProxy.addUser();
}
}