代理模式
优点:
1、可以让功能共纯粹,实现业务的分工单一性。
2、业务扩展时通过代理可以不影响现有代码。
示例1、 静态代理:客户租房(消费者)>>>通过中介(代理)>>>房东(生产者)
房东与中介有共同的出租房的方法,可以抽象出共同的接口
//出租房的接口,里面有出租的抽象接口
public interface Rent {
// 出租房
void rent();
}
//房东有一个房子,实现出租房接口
public class Host implements Rent{
//房子有一个出租的方法
public void rent(){
System.out.println("出租房子");
}
}
/**
* 中介(代理),中介不仅有出租房的方法,还有其他方法,比如:带顾客看房、签订合同、收取中介费
* 中介实际出租的是房东的房子,所以中介要调用房东的出租房方法,客户要租那个房子是由客户决定的,创建代理时传要过来房子对象
*/
public class Proxy implements Rent{
//房东(房子)
private Host host;
//构造方法传入房子对象
public Proxy(Host host) {
this.host = host;
}
//代理租房方法,代理方法中可以操作代理这的特有方法
//中介可以带客户看房,确定后签订合同,
@Override
public void rent() {
seeHome();//看房
host.rent();//调用房东的租房方法
hetong();//签合同
}
/**
* 中介特有方法-看房
*/
public void seeHome(){
System.out.println("带你看房");
}
/**
* 中介特有方法-签合同
*/
public void hetong(){
System.out.println("签承租合同");
}
}
public class Client {
public static void main(String[] args) {
//创建房子对象
Host host = new Host();
//创建代理对象,并将房子信息传入
Rent rent=new Proxy(host);
rent.rent();
}
}
示例2、 动态代理:增删改查用户>>>动态代理>>>用户管理
增删改查用户时,调用方法前后增加日志信息,不修改原有代码
//用户管理接口
public interface UserService {
void add();
void delete();
void update();
void query();
}
/**
* 用户管理实现类
*/
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 query() {
System.out.println("查询用户");
}
}
//引用reflect反射包下的类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 万能动态代理类,通过反射机制调用被代理的方法
*/
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的目标对象,用万能对象声明
private Object target;
//可以用set方法也可以用构造方法赋值
public void setTarget(Object target) {
this.target = target;
}
//通过反射动态获取代理对象
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//通过反射调用要执行的方法,在该方法中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理,调用方法前执行");
beforeLog();
Object invoke = method.invoke(target, args);
afterLog()
System.out.println("动态代理,调用方法后执行");
return invoke;
}
private void beforeLog() {
System.out.println("方法前输出日志");
}
private void afterLog() {
System.out.println("方法后输出日志");
}
}
/**
* 消费者
*/
public class Client {
public static void main(String[] args) {
//创建用户Service对象
UserService userService1 = new UserServiceImpl();
//直接调用方法
userService1.add();
userService1.delete();
//通过代理调用方法
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setTarget(userService1);
UserService userService2 = (UserService) pih.getProxy();
System.out.println("--------");
userService2.add();
System.out.println("--------");
userService2.delete();
}
}