zoukankan      html  css  js  c++  java
  • 5.servlet容器--责任链

    章前准备

    相对于第二章的ifelse,ifif也并不少见
    呆毛:Paint类拥有print方法,他会根据传来的参数来画不同的人物,但这次传递的会是一个数组
    简单实现一:最基本的实现并观察

    /**
     * 
     * @author 程猿
     * 呆毛:Paint类拥有print方法,他会根据传来的参数来画不同的人物
     * 这次是数组
     */
    
    public class Paint {
        public static void main(String[] args)  {
            Paint paint = new Paint();
            paint.print(new String[]{"lf","sl"},"", "");
        }
        /**
         * @param Scene 场景参数
         * @param name  路人甲,实现场景什么的会使用到的参数
         * @param id    路人乙
         */
        void print(String[] scene,String name,String id){
            
            if(Arrays.asList(scene).contains("lf")){
                //好长好长的代码
                System.out.println("路飞");
            }
            if(Arrays.asList(scene).contains("sl")){
                //好长好长的代码
                System.out.println("索隆");
            }
            if(Arrays.asList(scene).contains("sz")){
                //好长好长的代码
                System.out.println("山治");
            }
                //好长好长的代码
                System.out.println("熊猫人");
        }
    }

    经历过ifelse的处理方式,这次只要模仿上一次的ifelse的处理方式就行了

    简单实现二:使用ifelse的处理方式进行修改

    /**
     * @author 程猿
     * 使用ifelse的处理方式
     */
    public class Paint {
    
        Map<String,Print>  paintMap=new HashMap(){
            {
                put("lf", new PrintLF());
                put("sl", new PrintSL());
                put("sz", new PrintSZ());
                put("", new PrintXMR());
            }
        };
        
        public static void main(String[] args)  {
            Paint paint = new Paint();
            paint.print(new String[]{"lf","sl"},"", "");
        }
    
        void print(String[] scene,String name,String id){
            for(String str:scene){
                Print print = paintMap.get(str);
                if(print!=null){
                    print.print(str, name, id);
                }
            }
        }
    }

    刨去ioc(如果再说ioc的事我就太没良心了- -),实现的增加和修改我们可以通过ioc去修改,那么流程是否也可以在封装一下呢?比如通过ioc去决定Paint方式实现的是ifif或者ifelse....其实这种需求的改变不亚于实现的改变,你可以简单的封装一下,然后观察比如

    /**
     * 
     * @author 程猿
     * 封装一下原本的调用方法并进行观察
     */
    public class IfIf{
    
        List<Print> prints = new ArrayList();
        
        public void invoke(String[] scene,String name, String id) {
            for(Print  print:prints){
                print.print(scene, name, id);
            }
        }
    
    }

    作为完整的封装,它还需要一个接口...

    测试三:封装流程的逻辑,而非实现

    public interface Pipel {
        public void invoke(String[] scene,String name,String id);
        public void add(Print print);
    }
    public class IfIfPipel  implements Pipel{
    
        List<Print> prints = new ArrayList();
        
        public void invoke(String[] scene,String name, String id) {
            for(Print  print:prints){
                print.print(scene, name, id);
            }
        }
    
        @Override
        public void add(Print print) {
            prints.add(print);
        }
    
    }
    public class IfElsePipel  implements Pipel{
        List<Print> prints = new ArrayList();
        @Override
        public void invoke(String[] scene,String name, String id) {
            for(Print  print:prints){
                boolean print2 = print.print(scene, name, id);
                if(print2){
                    break;
                }
            }
        }
        @Override
        public void add(Print print) {
            prints.add(print);
        }
    }
    /**
     * @author 程猿
     * 封装流程
     */
    public class Paint {
    
        private Pipel pipel;
        
        public void setPipel(Pipel pipel) {
            this.pipel = pipel;
        }
    
        public static void main(String[] args)  {
            Paint paint = new Paint();
            //初始化paint,可以使用-->ioc
            //Pipel pipel = new IfElsePipel();
            Pipel pipel = new IfIfPipel();
            pipel.add(new PrintLF());
            pipel.add(new PrintSL());
            pipel.add(new PrintXMR());
            pipel.add(new PrintSZ());
            
            paint.setPipel(pipel);
            //调用
            paint.print(new String[]{"lf","sl"},"", "");
        }
    
        void print(String[] scene,String name,String id){
            pipel.invoke(scene, name, id);
        }
    }

    Print的实现就不贴了...如果你觉每次都有判断要写的话,可以整个模板分离一下判断.....总之,我们达成了最开始的需求....

    仔细看看的话就能明白,ifif并不仅限于if...像那种按部就班的执行方式都适合这样的设计,这种解决解决方案就是所谓的管道,至少在tomcat里叫管道(另一个名字叫责任链)
    管道将自己分割为阈(是阈还是阀不重要...),除了对每个阈进行封装,也需要对管道的流向进行实现,管道只是一种解决方案,在为他赋予更多的业务信息就会变成其他的模式(框架),也许他们不承认是管道(或者别人就不是这样考虑的...),who cares

    对容器的管理--连排班
    比如小兵,我们需要将小兵放到部队(容器)中进行统一的管理,这时部队是个数组,当有一天发现发现这个人数太多了,已经很难去进行管理,或许我们会将部队(容器),在进行一次拆分,比如分出连排班,这里就出现了容器的容器,当然你理解为横向,纵向管理或者一维到二维的转换也没问题,类似的例子有很多...重点是容器做为调用servlet的实现,他已经不允许我们像原来一样简单的管理,就像连排班一样,他们所能够执行的任务或命令是一样的...

    tomcat_5.servlet容器.zip

    第五章 servlet容器

    1.容器接受req与res并不仅仅只做调用的工作,或许在这不方便展示,为了解释管道,文中加了2个打印的阈实现,可以理解为log,当然,这里他对管道的流程处理的更加细腻
    2.多个容器的管理方式除了使用数组容器以外,还可使用连排班(自创的名字....忽视它)的方式去管理,比如
    Wrapper:表示独立的servlet
    Context:表示一个web应用
    Host:主机
    Engine:引擎
    他们都是容器,其中下面的是上面的容器的容器....除了Wrapper不会再有子容器以外,没有其他区别

  • 相关阅读:
    TCP的状态 (SYN, FIN, ACK, PSH, RST, URG)
    理论基础+实战控制台程序实现AutoFac注入
    C# class 浅拷贝 与 深拷贝
    给定一个矩阵 A, 返回 A 的转置矩阵。
    [弹出消息] C#ShowMessageBox帮助类
    [弹出消息] C#MessageBox帮助类 (转载)
    [XML] C#XMLProcess操作Xml文档的帮助类 (转载)
    [XML] C# XmlHelper操作Xml文档的帮助类 (转载)
    [XML] resources的Xml配置文件 (转载)
    [XML] Resource帮助类
  • 原文地址:https://www.cnblogs.com/liuCy/p/4068875.html
Copyright © 2011-2022 走看看