现有如下业务层接口和实现类:
package user;
public interface MathInterFace {
int add(int a,int b);
}
package user;
public class MathImpl implements MathInterFace {
//业务逻辑层
//增加权限控制或会员分级等代码均无须改动本类
public int add(int a, int b) {
return a+b;
}
}
需求:不改变业务层代码的情况下,给业务层增加会员分级系统 VIP会员:特权:在使用add方法时,所得结果会再加上100 普通会员:可以正常使用add方法 无权限会员:无权使用 思路: 1.首先,我们需要一个工厂类,业务层对象均从此类静态方法获取 调用本类静态方法获取业务层对象时,需要传递进来一个参数,以得知会员等级,根据会员等级创建对应的调用处理器 package user;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.ResourceBundle;
/**
*
* @author 王凯旋
* @QQ 997208868
* @date 2015-08-31 17:13:20
*/
public class ProxyFactory {
/**
* 使用传递进来的会员等级配置文件中的key获取完整类路径创建调用处理器对象,
* 实现根据不同的用户,创建使用不同调用处理器的代理对象,完美解耦和
* @param clazzKey 根据会员等级配置文件中的key获取对应调用处理器完整类路径
* @return 经过代理的对象
*/
public static MathInterFace getInstance(String clazzKey) {
//创建被代理对象
MathInterFace m = new MathImpl();
//创建代理后对象,初始化为null
MathInterFace mm =null;
try {
//读用户等级配置文件
ResourceBundle rb = ResourceBundle.getBundle("user");
//根据不同的用户等级clazzKey,使用不同的调用处理器,把得到代理后对象赋值给mm
//调用处理器类的构造方法需要把代理对象传进去,所以要先获取其构造方法对象,执行构造方法并传入参数
mm = (MathInterFace) Proxy.newProxyInstance(m.getClass().getClassLoader(),
m.getClass().getInterfaces(),
(InvocationHandler) Class.forName(rb.getString(clazzKey)).
getConstructor(MathInterFace.class).newInstance(m));
} catch (Exception e) {
return null;
}
//返回代理后的对象
return mm;
}
}
2.同时,我们要创建user.properties用户等级配置文件,存放在src目录下 vip=user.Vip
default=user.Default
untitled=user.Untitled
不同的用户等级,对应不同的调用处理类
package user;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 会员类
*/
public class Vip implements InvocationHandler {
private MathInterFace m;
//接收工厂类传入的m,使用它完成代理
public Vip(MathInterFace m) {
this.m=m;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("欢迎您,尊敬的VIP用户:");
/*
* 与装饰者模式相比,动态代理模式优点在于:
* 无需重复去写被装饰对象的所有方法,可以根据方法名,方法参数,
* 选择性的改写被装饰对象的方法,且不影响原有任何方法使用。
*/
//修改了用户传入的参数
args[0] = (Integer)args[0]+100;
//用修改后的参数执行方法,用户得到的结果将发生改变
return method.invoke(m,args);
}
}
package user;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 普通用户类
*/
public class Default implements InvocationHandler {
private MathInterFace m;
public Default(MathInterFace m) {
this.m=m;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("欢迎您,普通用户:");
return method.invoke(m,args);
}
}
package user;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 无权限用户类
*/
public class Untitled implements InvocationHandler {
private MathInterFace m;
public Untitled(MathInterFace m) {
this.m=m;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/*
* 拦截原有方法
* 装饰者模式也可以实现
*/
if ("add".equals(method.getName())) {
System.out.println("你是无权限用户");
System.out.println("不能使用此功能!");
return 0; //此处如果返回null会导致调用方空指针异常,我们既然已经知道这里方法是add,所以可以返回相应返回类型的默认值
}else {
return method.invoke(m, args);
}
}
}
package user;
public class ProxyDemo {
public static void main(String[] args) {
//权限分级
//1.要求VIP用户在使用add方法时得到的结果多加100
//2.普通用户在使用add方法时结果是正常的
//3.无权限用户在使用add方法时,输出“不能使用”,并且不计算不给返回值
//VIP用户:
MathInterFace m = ProxyFactory.getInstance("vip");
System.out.println(m.add(1, 2));
//普通用户:
MathInterFace m2 = ProxyFactory.getInstance("default");
System.out.println(m2.add(1, 2));
//无权限用户:
MathInterFace m3 = ProxyFactory.getInstance("untitled");
m3.add(1, 2);
}
}
执行结果: 欢迎您,尊敬的VIP用户:
103
欢迎您,普通用户:
3
你是无权限用户
不能使用此功能!
总结: 装饰者模式:动态的将责任附加到被装饰者对象上,用于扩展对象的功能。 动态代理模式:对其他对象进行代理,以控制对被代理对象的访问。 一个是扩展功能,一个是控制访问。 |
使用AOP思想设计会员分级系统
最新推荐文章于 2025-06-15 10:36:35 发布