设计模式之架构中的适配者模式

定义:
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
优点:
1、可以让任何两个没有关联的类一起运行。
2、提高了类的复用。
3、灵活性好
缺点:
过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接
口的实现,一个系统如果太多出现这种情况,无异于一场灾难。

以自定义Spring架构来说明

在这里插入图片描述

适配器视图渲染

在这里插入图片描述
做视图解析的时候,有不同的解析方式,比如有直接输入json数据、重定向、转发、输出文件流等多种方式。通常采用哪种解析方式由执行方法的返回值决定,例如返回一个字符串,我们可以把返回的字符串当做响应的页面,这时候可以采用转发的方式,如果返回的是一个javabean,这时候我们可以采用输出json字符串的方式解析。像这一块的实现,我们可以采用适配器模式实现。

实现步骤:
1、定义一个视图解析接口ViewHandler,提供2种解析方式,分别为json输出和forward
2、为接口实现每种解析方式。分别创建PrintViewHandler和ForwardViewHandler
3、创建一个视图渲染接口View,View中提供渲染方法render
4、创建View的渲染实现ViewAdapter,通过提供的相应结果,来创建对应的试图解析器,并调用解析方式

适配器模式实现视图解析

1)创建视图解析器接口

public interface ViewHandler {

    //json输出
    default void print(HttpServletResponse response,Object result){};

    //转发
    default void forward(HttpServletRequest request,HttpServletResponse response,Object result){}
}

2)创建json解析和转发
JSON解析对象: PrintViewHandler

public class PrintViewHandler implements ViewHandler {

    //输出json
    @Override
    public void print(HttpServletResponse response, Object result) {
        try {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(result));
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

转发解析对象: ForwardViewHandler

public class ForwardViewHandler implements ViewHandler {

    //转发
    @Override
    public void forward(HttpServletRequest request, HttpServletResponse response, Object result) {
        try {
            request.getRequestDispatcher(result.toString()).forward(request,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3)视图渲染接口和实现
视图渲染接口: View

public interface View {

    //渲染方法
    void render(HttpServletRequest request, HttpServletResponse response,Object result);

}

视图渲染实现: ViewAdapter

public class ViewAdapter implements View {

    private ViewHandler viewHandler;

    //渲染实现
    @Override
    public void render(HttpServletRequest request, HttpServletResponse response, Object result) {
        if(result instanceof String){
            //转发
            viewHandler = new ForwardViewHandler();
            viewHandler.forward(request,response,result);
        }else{
            viewHandler = new PrintViewHandler();
            viewHandler.print(response,result);
        }
    }
}

我们创建一个类 DispacherServlet ,继承BaseInit,同时在 web.xml 中把 BaseInit 换成 DispacherServlet ,并重写 service 方法,实现拦截所有用户请求,在 service 中使用执行反射调用,然后调用刚才写好的适配器查找对应的渲染方式执行渲染,代码如下:

public class DispacherServlet extends BaseInit {

    private View view;

    /***
     * 拦截用户所有请求
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取uri
        String uri = req.getRequestURI();

        //反射调用
        Object result = invoke(uri);
        if(result!=null){
            //响应结果给用户
            view = new ViewAdapter();
            view.render(req,resp,result);
        }
    }

    //执行反射调用
    public Object invoke(String uri){
        try {
            //从methods中获取指定的方法
            Method method = XmlBeanFactory.methods.get(uri);
            if(method!=null){
                //执行反射调用
                //Class<?> clazz = method.getDeclaringClass(); //获取方法所在类
                //return method.invoke(clazz.newInstance());

                //通过工厂获取实例
                Object instance = beanFactory.getUrlBean(uri);
                return method.invoke(instance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值