您当前的位置: 首页 > 

java持续实践

暂无认证

  • 4浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

设计模式 装饰器模式

java持续实践 发布时间:2022-03-26 11:45:07 ,浏览量:4

文章目录
      • 装饰器模式使用的情景
      • 装饰器模式使用的任务
      • 装饰器模式实战
        • 不使用装饰器模式写法
        • 使用装饰器模式写法 (行动)

装饰器模式使用的情景

在不改原有类的基础上, 给类新增功能.

装饰器模式使用的任务

单点登录模块, 一开始只是认证某个权限, 但随着业务的发展, 需要验证很多其他权限. 限定的任务是在不改变原有单点登录代码上 , 对验证权限进行扩展.

装饰器模式实战

创建tutorials-12.0-0模块.

public interface HandlerInterceptor {

    boolean preHandle(String request, String response, Object handler);
}

单点登录拦截器SsoInterceptor

public class SsoInterceptor implements HandlerInterceptor{

    public boolean preHandle(String request, String response, Object handler) {
        // 模拟登录获取cookie
        String ticket = request.substring(1, 8);
        // 模拟登录校验
        return ticket.equals("success");
    }
}
不使用装饰器模式写法

创建tutorials-12.0-1模块. queryUserInfo 代表有用户查询权限

public class LoginSsoDecorator extends SsoInterceptor {

    private static Map authMap = new ConcurrentHashMap();

    static {
        authMap.put("huahua", "queryUserInfo");
        authMap.put("doudou", "queryUserInfo");
    }

    @Override
    public boolean preHandle(String request, String response, Object handler) {
        // 模拟获取cookie
        String ticket = request.substring(1, 8);
        boolean success = ticket.equals("success");

        if (!success) return false;

        String userId = request.substring(8);
        String method = authMap.get(userId);
        return "queryUserInfo".equals(method);
    }
}

测试类如下

public class ApiTest {

    @Test
    public void test_LoginSsoDecorator() {
        LoginSsoDecorator ssoDecorator = new LoginSsoDecorator();
        String request = "1successhuahua";
        boolean success = ssoDecorator.preHandle(request, "ertert454", "t");
        System.out.println("登录校验: " + request + (success ? "放行" : "拦截"));
    }
}
使用装饰器模式写法 (行动)

使用装饰器模式的uml图 在这里插入图片描述 创建tutorials-12.0-2模块 创建SsoDecorator抽象装饰器

public abstract class SsoDecorator implements HandlerInterceptor {

    private HandlerInterceptor handlerInterceptor;

    public SsoDecorator() {
    }

    public SsoDecorator(HandlerInterceptor handlerInterceptor) {
        this.handlerInterceptor = handlerInterceptor;
    }

    @Override
    public boolean preHandle(String request, String response, Object handler) {
        return handlerInterceptor.preHandle(request, response, handler);
    }
}

创建LoginSsoDecorator 扩展服务

public class LoginSsoDecorator extends SsoDecorator {

    private Logger logger = LoggerFactory.getLogger(LoginSsoDecorator.class);

    private static Map authMap = new ConcurrentHashMap();

    static {
        authMap.put("huahua", "queryUserInfo");
        authMap.put("doudou", "queryUserInfo");
    }

    public LoginSsoDecorator(HandlerInterceptor handlerInterceptor) {
        super(handlerInterceptor);
    }

    @Override
    public boolean preHandle(String request, String response, Object handler) {
        boolean success = super.preHandle(request, response, handler);
        if (!success) return false;
        String userId = request.substring(8);
        String method = authMap.get(userId);
        logger.info("模拟单点登录方法访问拦截器校验: {} {}", userId, method);
        // 模拟方法校验
        return "queryUserInfo".equals(method);
    }
}

扩展服务的preHandle方法, 既执行了父类的方法, 也执行了扩展的方法.

测试类 (结果)

public class ApiTest {

    @Test
    public void test_LoginSsoDecorator() {
        LoginSsoDecorator ssoDecorator = new LoginSsoDecorator(new SsoInterceptor());
        String request = "1successhuahua";
        boolean success = ssoDecorator.preHandle(request, "ttttweee", "t");
        System.out.println("登录校验: "+request+(success ? " 放行": "拦截"));
    }
}

11:40:32.836 [main] INFO  com.thc.design.LoginSsoDecorator - 模拟单点登录方法访问拦截器校验: huahua queryUserInfo
登录校验: 1successhuahua 放行

装饰器实现的重点是对抽象类继承接口方式的使用,同时设定被继承的接口可以通过构造函数传递其实现类,由此增加扩展性并重写方法里可以实现此部分父类实现的功能。

关注
打赏
1658054974
查看更多评论
立即登录/注册

微信扫码登录

0.1118s