設(shè)計(jì)模式之職責(zé)鏈
最近,在學(xué)習(xí)ajax的時(shí)候,發(fā)現(xiàn)了一個(gè)前后臺(tái)傳輸數(shù)據(jù)的好東東:json,通過(guò)json字符串我們能很快的將java對(duì)象轉(zhuǎn)換成javascript對(duì)象,至于json具體是什么東西,可以上他的官方網(wǎng)站去查看一下。這里簡(jiǎn)單的介紹一下: json用一對(duì)大括號(hào)來(lái)表示一個(gè)對(duì)象,并用冒號(hào)隔開(kāi)屬性和值,用逗號(hào)分隔多個(gè)屬性。表示數(shù)組對(duì)象的時(shí)候json用一對(duì)中括號(hào)表示。如下:
1:json代碼來(lái)表示一個(gè)對(duì)象: {"name":"楊川","sex":"男","age":26}.
這就表示了一個(gè)人的對(duì)象。 它的屬性name = 楊川,性別=男 。年紀(jì) =26歲。
2:json表示數(shù)組: [1,2,3,{"name":"sam","sex":"man"}].
這個(gè)就是一個(gè)數(shù)組, 其實(shí)熟悉javascript的人,都應(yīng)該能看出來(lái) json非常相似于javascript的直接量。比如數(shù)組直接量,對(duì)象直接量。
恩,到這里我簡(jiǎn)單介紹一下我要做的事情。是這樣的,我們的javascript可以通過(guò)一個(gè)eval函數(shù),將json字串轉(zhuǎn)化成它自己的對(duì)象,比如上邊的那個(gè)對(duì)象我們要穿換成 我們的 javascript對(duì)象就可以這樣寫(xiě)
jsonText = " {'name':'楊川','sex':'男','age':26}"
var person = eval('('+jsonText+')'); //得到一個(gè)javascrip對(duì)象
alert(person.name) //提示: 楊川。
所以,我們只要在java服務(wù)端將pojo生成一個(gè)個(gè)的json字符串,在前臺(tái)就可以 很簡(jiǎn)單的轉(zhuǎn)換為js對(duì)象了。為前臺(tái)的數(shù)據(jù)使用提供了很大的方便 。
因此我嘗試寫(xiě)了這么一個(gè)轉(zhuǎn)換工具包,結(jié)果,在編寫(xiě)的時(shí)候,發(fā)現(xiàn)職責(zé)鏈模式到時(shí)很適合這個(gè)。就拿來(lái)用了。呵呵,當(dāng)然我下邊的 代碼不一定是唯一的,完善的,如果各位看客有更好的 思路和方法。還請(qǐng)賜教啊。
好了,言歸正傳了。
我對(duì)職責(zé)鏈的理解是這樣的,在處理某些業(yè)務(wù)的時(shí)候,我們可能會(huì)判斷不同的情況去選擇做不同的業(yè)務(wù)處理,這樣就可能導(dǎo)致大量的if else語(yǔ)句組出來(lái)。導(dǎo)致程序的擴(kuò)展維護(hù)相當(dāng)困難,就比如我這里轉(zhuǎn)換json的這個(gè)例子,我的一個(gè)tojson(Object object)函數(shù)。他里邊就要判斷這樣一些情況,如果是一個(gè)pojo則返回的字符串首尾加上一對(duì)大括號(hào),如果是數(shù)組則首尾加上一對(duì)中括號(hào)。在處理數(shù)組的時(shí)候還要考慮數(shù)組元素是pojo,數(shù)組,集合或其它等情況,當(dāng)然pojo的屬性對(duì)象,也得考慮它是否是一個(gè)基本數(shù)據(jù)類(lèi),pojo,數(shù)組或其它等情況。下邊看看我的代碼。
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語(yǔ)句,試想一下我如果再加入一個(gè)HashMap的處理方法進(jìn)來(lái),我
是不是要 到上邊 每一個(gè) 方法都要加上這個(gè)類(lèi)型的判斷處理呢?哪以后再加 呢 ??是不是很難維護(hù)了。
所以,這個(gè)地方我們就應(yīng)該采用 職責(zé)鏈模式來(lái)完成這個(gè)處理。職責(zé)鏈模式會(huì)將不同類(lèi)型的處理提出來(lái)單獨(dú)放在各自不同的類(lèi)里去處理。當(dāng)你傳入的數(shù)據(jù)類(lèi)型時(shí),它會(huì)依次在這些處理類(lèi)里傳遞,直到找到該類(lèi)型的處理類(lèi)為止。
好 ,先定義一個(gè)接口。如下:
責(zé)任鏈接口
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 這個(gè)例子我們需要把不同數(shù)據(jù)類(lèi)型提出來(lái)做相應(yīng)處理。簡(jiǎn)單的可以分為,純 pojo對(duì)象的 處理,數(shù)組的處理,集合的處理:代碼如下:
純對(duì)象的處理
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
利用反射,讀出屬性和對(duì)應(yīng)方法,并按json的格式輸出字符串,為了前臺(tái)方便轉(zhuǎn)換,這里注意了轉(zhuǎn)義字符的處理。
2:處理集合類(lèi)型:
集合類(lèi)型的處理
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("處理對(duì)象null異常");
46 }
47 }
48
49 public JSONChain getChain() {
50 return nextChain;
51 }
52
53}
54 3:數(shù)組的處理:
數(shù)組的處理
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("處理對(duì)象null異常");
38 }
39
40 }
41
42}
43
4: 責(zé)任鏈的 組裝
1/**//*
2* @(#)JSONClient.java
3* createTime:Apr 22, 2008 8:41:10 AM
4*/
5package com.sam.jsontool.util;
6
7
8/** *//**
9 * @author sam E-mail:ashan8888@163.com
10 * @version 1.0
11 */
12public 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:測(cè)認(rèn)結(jié)果:
簡(jiǎn)單的單元測(cè)試
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 * 測(cè)試一個(gè)簡(jiǎn)單的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 * 測(cè)試一個(gè)簡(jiǎn)單的 數(shù)組。
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 * 測(cè)試一個(gè)簡(jiǎn)單的 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 * 測(cè)試一個(gè)復(fù)合的 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
91360docimg_501_ /** *//**
92360docimg_502_ * 測(cè)試集合元素中某集合為空的情況
93360docimg_503_ * @throws Exception
94360docimg_504_ */
95360docimg_505_360docimg_506_ public void testCollection() throws Exception {
96360docimg_507_
97360docimg_508_ List list = new ArrayList();
98360docimg_509_ list.add("sam\\tiger");
99360docimg_510_
100360docimg_511_ list.add(new HashSet());
101360docimg_512_ Person person = new Person();
102360docimg_513_ person.setName("男");
103360docimg_514_ person.setAge(28);
104360docimg_515_ person.setSex(true);
105360docimg_516_ list.add(person);
106360docimg_517_ System.out.println(list.toString());
107360docimg_518_ System.out.println(JSONTool.toJSON(list));
108360docimg_519_ }
109360docimg_520_}
110360docimg_521_
呵呵,現(xiàn)在要是加入HashMap的類(lèi)型處理 是不是很簡(jiǎn)單了,只要加入一個(gè)類(lèi)就可以了
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)
點(diǎn)擊舉報(bào)。