设计链模式
1、现在假设一个场景:做一个BBS系统,也就意味着人们可以在论坛上自由言论。一个好的系统肯定要对言论进行处理,比如说敏感词汇、脚本代码等等。
A、原始的做法:
1 package program.design.model; 2 public class LinkedDesign { 3 public static void main(String[] args) { 4 String msg="<script>this is 敏感 information</script>"; 5 6 MsgProcessor prossor=new MsgProcessor(); 7 prossor.setMsg(msg); 8 String result=prossor.process(); 9 System.out.println(result); 10 } 11 } 12 13 14 package program.design.model; 15 public class MsgProcessor { 16 private String msg; 17 public String process() { 18 //process the html tag<> 19 String result=msg.replaceAll("<","[") 20 .replaceAll(">","]") 21 //process the sensitive vocabulary 22 .replace("敏感","☺"); 23 return result; 24 } 25 26 public String getMsg() { 27 return msg; 28 } 29 public void setMsg(String msg) { 30 this.msg = msg; 31 } 32 }
评价:如此进行处理的话,如果现在添加了新的需求,也就意味着要对msg添加新的处理逻辑,或者改变原先的处理逻辑,那么这就不得不去修改这段逻辑代码了。设计模式的初衷就是有额外的逻辑或功能模块添加的时候,不会对原来的逻辑代码进行大幅的修改。
B、在这里,msg的处理方法是不断变化的,我们可以将每一种处理方式设计成一个相应的类。如处理敏感词汇的类SensitiveFilter、处理脚本代码的类HTMLFilter。为了是一个类型能接收这些所有的类,我们就得定义一个接口,使得这些处理过滤类都实现这个接口。
1 package program.design.model; 2 3 public class Main { 4 public static void main(String[] args) { 5 String msg="<script>this is 敏感 information</script>"; 6 MsgProcessor processor=new MsgProcessor(); 7 processor.setMsg(msg); 8 String result=processor.process(); 9 System.out.println(result); 10 } 11 } 12 13 14 public class MsgProcessor { 15 16 private String msg; 17 public String process() { 18 Filter[] filters=new Filter[]{new HTMLFilter(),new SensitiveFilter()}; 19 for(int i=0;i<filters.length;i++) { 20 msg=filters[i].doFilter(msg); 21 } 22 23 return msg; 24 } 25 public String getMsg() { 26 return msg; 27 } 28 public void setMsg(String msg) { 29 this.msg = msg; 30 } 31 } 32 33 34 public interface Filter { 35 String doFilter(String str); 36 } 37 38 39 public class HTMLFilter implements Filter{ 40 @Override 41 public String doFilter(String str) { 42 String result=str.replaceAll("<", "[") 43 .replaceAll(">", "]"); 44 return result; 45 } 46 } 47 48 49 50 public class SensitiveFilter implements Filter{ 51 @Override 52 public String doFilter(String str) { 53 String result=str.replace("敏感","☺"); 54 return result; 55 } 56 }
评价:这样,代码就变得灵活多了,增加新的规则时,我们只需添加新的过滤类且只要对逻辑代码进行少量的改动,但是还是存在改动的情况,即增加新的过滤规则时,要将新的过滤实例在逻辑代码的数组中给出来。而一个真正好的设计模式要达到的效果是:不对处理逻辑代码进行任何的修改,即不会对MsgProcessor进行修改。那么现在还得增加一个FilterChain,所有的Filter放在这个类当中,我们在真正用时只需实例化FilterChain,并调用其中的方法,也不用去修改FilterChain当中的逻辑代码。
1 import java.util.ArrayList; 2 import java.util.List; 3 4 /** 5 *实现Filter接口的好处是,FilterChain不仅可以将FilterChain 6 *串起来,还可以将Filter串起来 7 */ 8 public class FilterChain implements Filter{ 9 List<Filter> filters=new ArrayList<Filter>(); 10 //返回this,使得可以进行链式编程 11 public FilterChain addFilter(Filter filter) { 12 filters.add(filter); 13 return this; 14 } 15 @Override 16 public String doFilter(String str) { 17 for(Filter f:filters) { 18 str=f.doFilter(str); 19 } 20 return str; 21 } 22 } 23 24 25 public class Main { 26 public static void main(String[] args) { 27 String msg="<script>this is 敏感 information</script>"; 28 FilterChain fc=new FilterChain(); 29 fc.addFilter(new HTMLFilter()) 30 .addFilter(new SensitiveFilter()); 31 32 String result=fc.doFilter(msg); 33 System.out.println(result); 34 } 35 }
评论:设计模式就是要站在制作类库的角度去编写代码,而这里的class Main就是使用者在实际编程的过程当中所要调用类库当中提供的类去实现自己的逻辑。“责任链的编程模式”做到了这一点,我们在编程的时候,如果有新的需求产生,并不需要去改动“类库当中的类”;而是添加新的处理逻辑,再在在使用者角度里的class Main当中对代码进行修改。