设计模式之职责链模式

设计模式之职责链模式

设计模式之职责链 
 最近,在学习ajax的时候,发现了一个前后台传输数据的好东东:json,通过json字符串我们能很快的将java对象转换成javascript对象,至于json具体是什么东西,可以上他的官方网站去查看一下。这里简单的介绍一下: json用一对大括号来表示一个对象,并用冒号隔开属性和值,用逗号分隔多个属性。表示数组对象的时候json用一对中括号表示。如下:
   1:json代码来表示一个对象:   {"name":"杨川","sex":"男","age":26}.
     这就表示了一个人的对象。 它的属性name = 杨川,性别=男 。年纪 =26岁。
   2:json表示数组: [1,2,3,{"name":"sam","sex":"man"}].
     这个就是一个数组,  其实熟悉javascript的人,都应该能看出来 json非常相似于javascript的直接量。比如数组直接量,对象直接量。
   恩,到这里我简单介绍一下我要做的事情。是这样的,我们的javascript可以通过一个eval函数,将json字串转化成它自己的对象,比如上边的那个对象我们要穿换成 我们的 javascript对象就可以这样写
   jsonText = " {'name':'杨川','sex':'男','age':26}"
   var person = eval('('+jsonText+')');  //得到一个javascrip对象
   alert(person.name)  //提示: 杨川。
所以,我们只要在java服务端将pojo生成一个个的json字符串,在前台就可以 很简单的转换为js对象了。为前台的数据使用提供了很大的方便 。
  因此我尝试写了这么一个转换工具包,结果,在编写的时候,发现职责链模式到时很适合这个。就拿来用了。呵呵,当然我下边的 代码不一定是唯一的,完善的,如果各位看客有更好的 思路和方法。还请赐教啊。
      好了,言归正传了。
  我对职责链的理解是这样的,在处理某些业务的时候,我们可能会判断不同的情况去选择做不同的业务处理,这样就可能导致大量的if else语句组出来。导致程序的扩展维护相当困难,就比如我这里转换json的这个例子,我的一个tojson(Object object)函数。他里边就要判断这样一些情况,如果是一个pojo则返回的字符串首尾加上一对大括号,如果是数组则首尾加上一对中括号。在处理数组的时候还要考虑数组元素是pojo,数组,集合或其它等情况,当然pojo的属性对象,也得考虑它是否是一个基本数据类,pojo,数组或其它等情况。下边看看我的代码。

public class JSONArray{
@SuppressWarnings("unchecked")
 public static String toJson(Collection collection) {
  StringBuffer buffer = new StringBuffer();
  buffer.append("[");
  for (Object object : collection) {
   if (object instanceof Collection) {
    System.out.println(object.toString());
    JsonArray.toJson((Collection) object);
   } else {
    if (object.getClass().isArray()) {
     System.out.println(object.toString());
     JsonArray.toJson((Object[]) object);
    } else {
     if (buffer.length() > 1)
      buffer.append(",");
     buffer.append(JsonObject.toJson(object));
    }
   }
  }
  buffer.append("]");
  return buffer.toString();
 }

 @SuppressWarnings("unchecked")
 public static String toJson(Object[] collection) {

  StringBuffer buffer = new StringBuffer();
  buffer.append("[");
  for (Object object : collection) {
   if (object.getClass().isArray()) {
    System.out.println(object.toString());
    JsonArray.toJson((Object[]) object);
   } else {
    if (object instanceof Collection) {
     System.out.println(object.toString());
     JsonArray.toJson((Object[]) object);
    } else {
     if (buffer.length() > 1)
      buffer.append(",");
     buffer.append(JsonObject.toJson(object));
    }
   }

  }
  buffer.append("]");
  return buffer.toString();
 }

}
看看上边 这段代码,是不是很多if else语句,试想一下我如果再加入一个HashMap的处理方法进来,我
是不是要 到上边 每一个 方法都要加上这个类型的判断处理呢?哪以后再加 呢 ??是不是很难维护了。
       所以,这个地方我们就应该采用 职责链模式来完成这个处理。职责链模式会将不同类型的处理提出来单独放在各自不同的类里去处理。当你传入的数据类型时,它会依次在这些处理类里传递,直到找到该类型的处理类为止。

    好 ,先定义一个接口。如下:

责任链接口
 1/**//*
 2* @(#)JSONChain.java
 3* createTime:Apr 21, 2008 9:08:24 PM
 4*/

 5package com.sam.jsontool.util;
 6/** *//**
 7 * @author sam E-mail:ashan8888@163.com
 8 * @version 1.0
 9 */

10public interface JSONChain {
11   void addChain(JSONChain chain);
12   String doChain(Object objects) throws JSONException;
13   JSONChain getChain();   
14}

15
16
17
这个例子我们需要把不同数据类型提出来做相应处理。简单的可以分为,纯 pojo对象的 处理,数组的处理,集合的处理:代码如下:
纯对象的处理
  1/**//*
  2 * @(#)JSONObject.java
  3 * createTime:Apr 22, 2008 11:08:27 AM
  4 */

  5package com.sam.jsontool.util;
  6
  7import java.beans.BeanInfo;
  8import java.beans.IntrospectionException;
  9import java.beans.Introspector;
 10import java.beans.PropertyDescriptor;
 11import java.lang.reflect.InvocationTargetException;
 12import java.lang.reflect.Method;
 13
 14/** *//**
 15 * @author sam E-mail:ashan8888@163.com
 16 * @version 1.0
 17 */

 18public class JSONObject implements JSONChain {
 19
 20    public void addChain(JSONChain chain) {
 21
 22    }

 23
 24    public String doChain(Object objects) {
 25
 26        return toJson(objects);
 27    }

 28
 29    public JSONChain getChain() {
 30        return null;
 31    }

 32
 33    /** *//**
 34     * This method handles a object to a jsonText
 35     * 
 36     * @param object
 37     *            which it will be convert a json text;
 38     * @return a json text
 39     * @throws IllegalArgumentException
 40     * @throws IllegalAccessException
 41     * @throws InvocationTargetException
 42     * @throws IntrospectionException
 43     */

 44    @SuppressWarnings("unchecked")
 45    public static String toJson(Object object) {
 46        if (null == object)
 47            return "null";
 48        if (object.getClass().getPackage().getName().equals("java.lang"))
 49            return object.toString();
 50        Object methodResult = null;
 51        BeanInfo beanInfo = getBeanInfo(object);
 52        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
 53        Method method = null;
 54        StringBuffer buffer = new StringBuffer();
 55        buffer.append("{");
 56        for (PropertyDescriptor descriptor : descriptors) {
 57            method = descriptor.getReadMethod();
 58            if (null != method) {
 59                methodResult = invokeMethod(object, method);
 60                if (null == methodResult)
 61                    methodResult = "null";
 62                if (buffer.indexOf(":"> 1)
 63                    buffer.append(",");
 64                buffer.append("\"" + descriptor.getName() + "\":");
 65
 66                if (!methodResult.getClass().getPackage().getName().equals(
 67                        "java.lang")) {
 68                    buffer.append(toJson(methodResult));
 69                }
 else {
 70                    buffer.append(quote( methodResult.toString() ));
 71                }

 72            }

 73        }

 74        buffer.append("}");
 75        return buffer.toString();
 76    }

 77
 78    /** *//**
 79     * This method is return a BeanInfo object and it without Object class's
 80     * infomation.
 81     * 
 82     * @param object
 83     * @return
 84     */

 85    private static BeanInfo getBeanInfo(Object object) {
 86        BeanInfo beanInfo = null;
 87        try {
 88            beanInfo = Introspector
 89                    .getBeanInfo(object.getClass(), Object.class);
 90        }
 catch (IntrospectionException e) {
 91            e.printStackTrace();
 92        }

 93        return beanInfo;
 94    }

 95
 96    /** *//**
 97     * this method is called when you want invoke a method via ref
 98     * 
 99     * @param object
100     * @param method
101     * @return if no method find "null" will be return.
102     */

103    private static Object invokeMethod(Object object, Method method) {
104        Object result = null;
105        try {
106            result = method.invoke(object, new Object[0]);
107        }
 catch (IllegalArgumentException e) {
108            e.printStackTrace();
109        }
 catch (IllegalAccessException e) {
110            e.printStackTrace();
111        }
 catch (InvocationTargetException e) {
112            e.printStackTrace();
113        }

114        return result;
115    }

116    
117     public static String quote(String string) {
118            if (string == null || string.length() == 0{
119                return "\"\"";
120            }

121
122            char         b;
123            char         c = 0;
124            int          i;
125            int          len = string.length();
126            StringBuffer sb = new StringBuffer(len + 4);
127            String       t;
128
129            sb.append('"');
130            for (i = 0; i < len; i += 1{
131                b = c;
132                c = string.charAt(i);
133                switch (c) {
134                case '\\':
135                case '"':
136                    sb.append('\\');
137                    sb.append(c);
138                    break;
139                case '/':
140                    if (b == '<'{
141                        sb.append('\\');
142                    }

143                    sb.append(c);
144                    break;
145                case '\b':
146                    sb.append("\\b");
147                    break;
148                case '\t':
149                    sb.append("\\t");
150                    break;
151                case '\n':
152                    sb.append("\\n");
153                    break;
154                case '\f':
155                    sb.append("\\f");
156                    break;
157                case '\r':
158                    sb.append("\\r");
159                    break;
160                default:
161                    if (c < ' '{
162                        t = "000" + Integer.toHexString(c);
163                        sb.append("\\u" + t.substring(t.length() - 4));
164                    }
 else {
165                        sb.append(c);
166                    }

167                }

168            }

169            sb.append('"');
170            return sb.toString();
171        }

172
173}

174

利用反射,读出属性和对应方法,并按json的格式输出字符串,为了前台方便转换,这里注意了转义字符的处理。

2:处理集合类型:
集合类型的处理
 1/**//*
 2 * @(#)JSONCollection.java
 3 * createTime:Apr 22, 2008 7:31:54 PM
 4 */

 5package com.sam.jsontool.util;
 6
 7import java.util.Collection;
 8import java.util.Iterator;
 9
10/** *//**
11 * This class is handles Collection Object to a jsonText
12 * 
13 * @author sam E-mail:ashan8888@163.com
14 * @version 1.0
15 */

16public class JSONCollection implements JSONChain {
17
18    private JSONChain nextChain;
19
20    public void addChain(JSONChain chain) {
21        this.nextChain = chain;
22    }

23
24    @SuppressWarnings("unchecked")
25    public String doChain(Object objects) throws JSONException {
26        if ((null != objects) && (objects instanceof Collection)) {
27            StringBuffer buffer = new StringBuffer();
28            Iterator iterator = ((Collection) objects).iterator();
29            if (null == iterator) {
30                buffer.append("null");
31                return buffer.toString();
32            }

33            buffer.append("[");
34            while (iterator.hasNext()) {
35                if (buffer.length() > 1)
36                    buffer.append(",");
37                buffer.append(JSONTool.toJSON(iterator.next()));
38            }

39            buffer.append("]");
40            return buffer.toString();
41        }
 else {
42            if (nextChain != null)
43                return nextChain.doChain(objects);
44            else
45                throw new JSONException("处理对象null异常");
46        }

47    }

48
49    public JSONChain getChain() {
50        return nextChain;
51    }

52
53}

54
3:数组的处理:
数组的处理
 1/**//*
 2 * @(#)JSONObject.java
 3 * createTime:Apr 21, 2008 8:08:42 PM
 4 */

 5package com.sam.jsontool.util;
 6
 7/** *//**
 8 * @author sam E-mail:ashan8888@163.com
 9 * @version 1.0
10 */

11public class JSONArray implements JSONChain {
12
13    private JSONChain nextChain;
14
15    public void addChain(JSONChain chain) {
16        nextChain = chain;
17    }

18
19    public JSONChain getChain() {
20        return nextChain;
21    }

22
23    public String doChain(Object objects) throws JSONException {
24        if ((null!=objects)&& (objects.getClass().isArray())) {
25            StringBuffer buffer = new StringBuffer();
26            buffer.append("[");
27            for (Object obj : (Object[]) objects) {
28                if (buffer.length() > 1)
29                    buffer.append(",");
30                buffer.append(JSONTool.toJSON(obj));
31            }

32            buffer.append("]");
33            return buffer.toString();
34        }
 else {
35            if(nextChain != null)
36                 return nextChain.doChain(objects);
37                else throw new JSONException("处理对象null异常"); 
38        }

39
40    }

41
42}

43


4: 责任链的 组装
 1 /**/ /*
 2* @(#)JSONClient.java
 3* createTime:Apr 22, 2008 8:41:10 AM
 4*/

 5 package  com.sam.jsontool.util;
 6
 7
 8 /** */ /**
 9 * @author sam E-mail:ashan8888@163.com
10 * @version 1.0
11 */

12 public   class  JSONTool  {
13    
14    private static JSONArray array ; 
15    private static JSONCollection collection;
16    private static JSONObject obj;
17    static{
18        array= new JSONArray(); 
19        collection = new JSONCollection();
20        obj = new JSONObject();
21        collection.addChain(array);
22        array.addChain(obj);
23    }

24    
25    
26    public static String toJSON(Object object){        
27        String result = null;
28        try {
29            result = collection.doChain(object);
30        }
 catch (JSONException e) {
31            e.printStackTrace();        
32        }

33        return result;
34    }

35    
36    
37}

38
5:测认结果:
简单的单元测试
  1/**//*
  2* @(#)JSONArrayTest.java
  3* createTime:Apr 21, 2008 8:22:27 PM
  4*/

  5package com.sam.jsontool.utiltest;
  6
  7import java.util.ArrayList;
  8import java.util.HashSet;
  9import java.util.List;
 10
 11import com.sam.jsontool.util.JSONTool;
 12
 13import junit.framework.TestCase;
 14
 15/** *//**
 16 * @author sam E-mail:ashan8888@163.com
 17 * @version 1.0
 18 */

 19public class JSONArrayTest extends TestCase {
 20
 21/** *//**
 22 *  测试一个简单的javabean。
 23 * @throws Exception
 24 */

 25    public void testSimpleJB() throws Exception {
 26        Person person = new Person();
 27        person.setName("");
 28        person.setAge(28);
 29        person.setSex(true);
 30        System.out.println(JSONTool.toJSON(person));
 31    }

 32    /** *//**
 33     * 测试一个简单的 数组。
 34     * @throws Exception
 35     */

 36    public void testSimpleArray() throws Exception {
 37        Object[] objects = new  Object[10];
 38        for(int i = 0;i<10;i++){
 39            Person person = new Person();
 40            person.setName("");
 41            person.setAge(28+i);
 42            person.setSex(true);
 43            objects[i] = person;            
 44        }

 45        System.out.println(JSONTool.toJSON(objects));
 46    }

 47/** *//**
 48 * 测试一个简单的 list.
 49 * @throws Exception
 50 */

 51    @SuppressWarnings("unchecked")
 52    public void testSimpleList() throws Exception {
 53        List list = new  ArrayList();
 54        for(int i = 0;i<10;i++){
 55            Person person = new Person();
 56            person.setName("");
 57            person.setAge(28+i);
 58            person.setSex(true);
 59            list.add(person);
 60        }

 61        System.out.println(JSONTool.toJSON(list));
 62    }

 63    /** *//**
 64     * 测试一个复合的 list
 65     * @throws Exception
 66     */

 67    @SuppressWarnings("unchecked")
 68    public void testcomList() throws Exception {
 69        Object[] objects = new  Object[3];
 70        for(int i = 0;i<2;i++){
 71            Person person = new Person();
 72            person.setName("");
 73            person.setAge(28+i);
 74            person.setSex(true);
 75            objects[i] = person;            
 76        }

 77        List list = new  ArrayList();
 78        list.add(123);
 79        for(int i = 1;i<5;i++){
 80            Person person = new Person();
 81            person.setName("");
 82            person.setAge(28+i);
 83            person.setSex(true);
 84            if (i==2{
 85                list.add(objects);
 86            }
else list.add(person);
 87        }

 88        System.out.println(JSONTool.toJSON(list));
 89    }

 90    
 91    /** *//**
 92     * 测试集合元素中某集合为空的情况
 93     * @throws Exception
 94     */

 95    public void testCollection() throws Exception {
 96        
 97        List list = new  ArrayList();
 98        list.add("sam\\tiger");
 99        
100        list.add(new HashSet());
101        Person person = new Person();
102        person.setName("");
103        person.setAge(28);
104        person.setSex(true);
105        list.add(person);
106        System.out.println(list.toString());
107        System.out.println(JSONTool.toJSON(list));
108    }

109}

110

呵呵,现在要是加入HashMap的类型处理 是不是很简单了,只要加入一个类就可以了

你可能感兴趣的:(设计模式之职责链模式)