章前准备
相对于第二章的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的实现,他已经不允许我们像原来一样简单的管理,就像连排班一样,他们所能够执行的任务或命令是一样的...
第五章 servlet容器
1.容器接受req与res并不仅仅只做调用的工作,或许在这不方便展示,为了解释管道,文中加了2个打印的阈实现,可以理解为log,当然,这里他对管道的流程处理的更加细腻
2.多个容器的管理方式除了使用数组容器以外,还可使用连排班(自创的名字....忽视它)的方式去管理,比如
Wrapper:表示独立的servlet
Context:表示一个web应用
Host:主机
Engine:引擎
他们都是容器,其中下面的是上面的容器的容器....除了Wrapper不会再有子容器以外,没有其他区别