






















这两天看了和测试驱动相关的开发,一开始觉得有够恶心的,本来几行代码能搞定的事,却要这么折腾。给我的感觉是,一但测试代码相对稳定了,敏捷开发者就“敏捷”地打成重构,代码整洁的旗号去对那柔弱的旧代码大开杀戒了。顺理成章的去用一些模式,可以说TDD的那些测试,就成了免死金牌。
下面写出自己对TDD的几条理解吧;
1、先把测试代码写出来,想好怎么调用,虽然编译都没过
2、用最傻,弱智的方法把编译先过了
3、让测试代码的运行给过了,先解决代码“可用”,再考虑“整洁”问题
4、如果在修改代码的时候,如果出现了两个维度上的变化,则把测试回退,一次只处理一条变化(如果你够牛XX,可以多线程操作也行啊)
注意自己的节奏。
5、看到重复代码要就提成接口或类,如果有默认实现,就提成类。
6、让代码替你思考,你把测试写到那里了,死角都在那了,你不用把逻辑放到脑子里面了,直接用测试验证就行了。
7、把一些未完成的功能,或者看得到的缺陷全都写到一个列表上,每次重构,都要解决对应的问题
8、如果重构和测试代码有冲突了,修改测试满足现有的重构
下面是自己重构的一个实践,希望 大家多多指教哈。。。
来源于<clean code >中的14章
第一部分,初稿
代码
1 /*
2
3 第14章,初稿
4 重构步骤
5 * 1.提取异常类ArgsException,并修改测试代码ArgsTest,支持新的异常类
6 * 2.重构Args
7 * 3.跑ArgsTest
8 */
9 using System;
10 using System.Collections.Generic;
11 using System.Text;
12 using System.Collections;
13 using System.Security.Policy;
14
15 namespace CleanCode.Library
16 {
17
18 public class Args
19 {
20 private String schema;
21 private String[] args;
22 private bool valid = true;
23 private IList<char> unexpectedArguments = new List<char>();
24 private Dictionary<char, bool> booleanArgs =
25 new Dictionary<char, bool>();
26 private Dictionary<char, String> stringArgs = new Dictionary<char, String>();
27 private Dictionary<char, System.Int32> intArgs = new Dictionary<char, int>();
28 private IList<char> argsFound = new List<char>();
29 private int currentArgument;
30 private char errorArgumentId = '\0';
31 private String errorParameter = "TILT";
32 private ErrorCode errorCode = ErrorCode.OK;
33
34 private enum ErrorCode
35 {
36 OK, MISSING_STRING, MISSING_INTEGER, INVALID_INTEGER, UNEXPECTED_ARGUMENT
37 }
38
39 public Args(String schema, String[] args)
40 {
41 this.schema = schema;
42 this.args = args;
43 valid = parse();
44 }
45 private bool parse()
46 {
47 if (schema.Length == 0 && args.Length == 0)
48 return true;
49 parseSchema();
50 try
51 {
52 parseArguments();
53 }
54 catch (ArgsException e)
55 {
56 }
57 return valid;
58 }
59 private bool parseSchema()
60 {
61 string[] elementSet = schema.Split(new char[] { ',' });
62 string element = string.Empty;
63 for (int i = 0; i < elementSet.Length;i++ )
64 {
65 element = elementSet[i];
66 if (element.Length > 0)
67 {
68 string trimmedElement = element.Trim();
69 parseSchemaElement(trimmedElement);
70 }
71 }
72 return true;
73 }
74 private void parseSchemaElement(string element)
75 {
76 char elementId = element[0];
77 string elementTail = element.Substring(1);
78 validateSchemaElementId(elementId);
79 if (isBooleanSchemaElement(elementTail))
80 parseBooleanSchemaElement(elementId);
81 else if (isStringSchemaElement(elementTail))
82 parseStringSchemaElement(elementId);
83 else if (isIntegerSchemaElement(elementTail))
84 {
85 parseIntegerSchemaElement(elementId);
86 }
87 else
88 {
89 throw new FormatException(
90 string.Format("Argument: {0} has invalid format: {1}.",
91 elementId, elementTail));
92 }
93 }
94 private void validateSchemaElementId(char elementId)
95 {
96 if (!System.Char.IsLetter(elementId))
97 {
98 throw new FormatException(
99 "Bad character:" + elementId + "in Args format: " + schema);
100 }
101 }
102 private void parseBooleanSchemaElement(char elementId)
103 {
104 booleanArgs.Add(elementId, false);
105 }
106 private void parseIntegerSchemaElement(char elementId)
107 {
108 intArgs.Add(elementId, 0);
109 }
110 private void parseStringSchemaElement(char elementId)
111 {
112 stringArgs.Add(elementId, "");
113 }
114 private bool isStringSchemaElement(String elementTail)
115 {
116 return elementTail.Equals("*");
117 }
118 private bool isBooleanSchemaElement(String elementTail)
119 {
120 return elementTail.Length == 0;
121 }
122 private bool isIntegerSchemaElement(String elementTail)
123 {
124 return elementTail.Equals("#");
125 }
126 private bool parseArguments()
127 {
128 for (currentArgument = 0; currentArgument < args.Length; currentArgument++)
129 {
130 string arg = args[currentArgument];
131 parseArgument(arg);
132 }
133 return true;
134 }
135 private void parseArgument(String arg)
136 {
137 if (arg.StartsWith("-"))
138 parseElements(arg);
139 }
140 private void parseElements(String arg)
141 {
142 for (int i = 1; i < arg.Length; i++)
143 parseElement(arg[i]);
144 }
145 private void parseElement(char argChar)
146 {
147 if (setArgument(argChar))
148 argsFound.Add(argChar);
149 else
150 {
151 unexpectedArguments.Add(argChar);
152 errorCode = ErrorCode.UNEXPECTED_ARGUMENT;
153 valid = false;
154 }
155 }
156 private bool setArgument(char argChar)
157 {
158 if (isBooleanArg(argChar))
159 setBooleanArg(argChar, true);
160 else if (isStringArg(argChar))
161 setStringArg(argChar);
162 else if (isIntArg(argChar))
163 setIntArg(argChar);
164 else
165 return false;
166 return true;
167 }
168 private bool isIntArg(char argChar) { return intArgs.ContainsKey(argChar); }
169 private void setIntArg(char argChar)
170 {
171 currentArgument++;
172 String parameter = null;
173 try
174 {
175 parameter = args[currentArgument];
176 intArgs[argChar] = int.Parse(parameter);
177
178 }
179 catch (IndexOutOfRangeException e)
180 {
181 valid = false;
182 errorArgumentId = argChar;
183 errorCode = ErrorCode.MISSING_INTEGER;
184 throw new ArgsException();
185 }
186 catch (FormatException e)
187 {
188 valid = false;
189 errorArgumentId = argChar;
190 errorParameter = parameter;
191 errorCode = ErrorCode.INVALID_INTEGER;
192 throw new ArgsException();
193 }
194 }
195 private void setStringArg(char argChar)
196 {
197 currentArgument++;
198 try
199 {
200
201 stringArgs[argChar]= args[currentArgument];
202 }
203 catch (IndexOutOfRangeException e)
204 {
205 valid = false;
206 errorArgumentId = argChar;
207 errorCode = ErrorCode.MISSING_STRING;
208 throw new ArgsException();
209 }
210 }
211 private bool isStringArg(char argChar)
212 {
213 return stringArgs.ContainsKey(argChar);
214 }
215 private void setBooleanArg(char argChar, bool value)
216 {
217 booleanArgs[argChar] = value;
218 }
219 private bool isBooleanArg(char argChar)
220 {
221 return booleanArgs.ContainsKey(argChar);
222 }
223 public int cardinality()
224 {
225 return argsFound.Count;
226 }
227 public String usage()
228 {
229 if (schema.Length > 0)
230 return "-[" + schema + "]";
231 else
232 return "";
233 }
234 public String errorMessage()
235 {
236 switch (errorCode)
237 {
238 case ErrorCode.OK:
239 throw new Exception("TILT: Should not get here.");
240 case ErrorCode.UNEXPECTED_ARGUMENT:
241 return unexpectedArgumentMessage();
242 case ErrorCode.MISSING_STRING:
243 return String.Format("Could not find string parameter for -%c.",
244 errorArgumentId);
245 case ErrorCode.INVALID_INTEGER:
246 return String.Format("Argument -%c expects an integer but was '%s'.",
247 errorArgumentId, errorParameter);
248 case ErrorCode.MISSING_INTEGER:
249 return String.Format("Could not find integer parameter for -%c.",
250 errorArgumentId);
251 }
252 return "";
253 }
254 private String unexpectedArgumentMessage()
255 {
256 char c = '\0';
257 StringBuilder message = new StringBuilder("Argument(s) -");
258 for (int i = 0; i < unexpectedArguments.Count; i++)
259 {
260 c = unexpectedArguments[i];
261 message.Append(c);
262 }
263 message.Append(" unexpected.");
264 return message.ToString();
265 }
266 private bool falseIfNull(bool b)
267 {
268 return b != null && b;
269 }
270 private int zeroIfNull(int i)
271 {
272 return i == null ? 0 : i;
273 }
274 private String blankIfNull(String s)
275 {
276 return s == null ? "" : s;
277 }
278 public String getString(char arg)
279 {
280 return blankIfNull(stringArgs[arg]);
281 }
282 public int getInt(char arg)
283 {
284 return zeroIfNull(intArgs[arg]);
285 }
286 public bool getBoolean(char arg)
287 {
288 return falseIfNull(booleanArgs[arg]);
289 }
290 public bool has(char arg)
291 {
292 return argsFound.Contains(arg);
293 }
294 public bool isValid()
295 {
296 return valid;
297 }
298 }
299
300 }
第二部分:单元测试ArgsTest.cs

1 using System;
2 using System.Text;
3 using System.Collections.Generic;
4
5 using Microsoft.VisualStudio.TestTools.UnitTesting;
6 using CleanCode.Library;
7
8 namespace CleanCode.Library.Test
9 {
10
11 [TestClass]
12 public class ArgsTest
13 {
14
15 public ArgsTest()
16 {
17 }
18
19 private TestContext testContextInstance;
20
21 /// <summary>
22 ///获取或设置测试上下文,该上下文提供
23 ///有关当前测试运行及其功能的信息。
24 ///</summary>
25 public TestContext TestContext
26 {
27 get
28 {
29 return testContextInstance;
30 }
31 set
32 {
33 testContextInstance = value;
34 }
35 }
36
37 #region 附加测试属性
38 //
39 // 编写测试时,还可使用以下附加属性:
40 //
41 // 在运行类中的第一个测试之前使用 ClassInitialize 运行代码
42 // [ClassInitialize()]
43 // public static void MyClassInitialize(TestContext testContext) { }
44 //
45 // 在类中的所有测试都已运行之后使用 ClassCleanup 运行代码
46 // [ClassCleanup()]
47 // public static void MyClassCleanup() { }
48 //
49 // 在运行每个测试之前,使用 TestInitialize 来运行代码
50 // [TestInitialize()]
51 // public void MyTestInitialize() { }
52 //
53 // 在每个测试运行完之后,使用 TestCleanup 来运行代码
54 // [TestCleanup()]
55 // public void MyTestCleanup() { }
56 //
57 #endregion
58
59 [TestMethod]
60 public void testCreateWithNoSchemaOrArguments()
61 {
62 Args args = new Args("", new String[0]);
63 Assert.AreEqual(0, args.cardinality());
64 }
65
66 [TestMethod]
67 public void testWithNoSchemaButWithOneArgument()
68 {
69 try
70 {
71 new Args("", new String[] { "-x" });
72 //Assert.Fail();
73 }
74 catch (ArgsException e)
75 {
76 Assert.AreEqual(ErrorCode.UNEXPECTED_ARGUMENT,
77 e.ErrorCode);
78 Assert.AreEqual('x', e.ErrorArgumentId);
79 }
80 }
81
82
83 [TestMethod]
84 public void testWithNoSchemaButWithMultipleArguments()
85 {
86 try
87 {
88 new Args("", new String[] { "-x", "-y" });
89 //Assert.Fail();
90 }
91 catch (ArgsException e)
92 {
93 Assert.AreEqual(ErrorCode.UNEXPECTED_ARGUMENT,
94 e.ErrorCode);
95 Assert.AreEqual('x', e.ErrorArgumentId);
96 }
97 }
98
99 [TestMethod]
100 public void testNonLetterSchema()
101 {
102 try
103 {
104 new Args("*", new String[] { });
105 //Assert.Fail("Args constructor should have thrown exception");
106 }
107 catch (ArgsException e)
108 {
109 Assert.AreEqual(ErrorCode.INVALID_ARGUMENT_NAME,
110 e.ErrorCode);
111 Assert.AreEqual('*', e.ErrorArgumentId);
112 }
113 }
114
115 [TestMethod]
116 public void testInvalidArgumentFormat()
117 {
118 try
119 {
120 new Args("f~", new String[] { });
121 //Assert.Fail("Args constructor should have throws exception");
122 }
123 catch (ArgsException e)
124 {
125 Assert.AreEqual(ErrorCode.INVALID_FORMAT, e.ErrorCode);
126 Assert.AreEqual('f', e.ErrorArgumentId);
127 }
128 }
129
130 [TestMethod]
131 public void testSimpleBooleanPresent()
132 {
133 Args args = new Args("x", new String[] { "-x" });
134 Assert.AreEqual(1, args.cardinality());
135 Assert.AreEqual(true, args.getBoolean('x'));
136 }
137
138 [TestMethod]
139 public void testSimpleStringPresent()
140 {
141 Args args = new Args("x*", new String[] { "-x", "param" });
142 Assert.AreEqual(1, args.cardinality());
143 Assert.AreEqual(true, args.has('x'));
144 Assert.AreEqual("param", args.getString('x'));
145 }
146
147 [TestMethod]
148 public void testMissingStringArgument()
149 {
150 try
151 {
152 new Args("x*", new String[] { "-x" });
153 //Assert.Fail();
154 }
155 catch (ArgsException e)
156 {
157 Assert.AreEqual(ErrorCode.MISSING_STRING, e.ErrorCode);
158 Assert.AreEqual('x', e.ErrorArgumentId);
159 }
160 }
161
162 [TestMethod]
163 public void testSpacesInFormat()
164 {
165 Args args = new Args("x, y", new String[] { "-xy" });
166 Assert.AreEqual(2, args.cardinality());
167 Assert.AreEqual(true, args.has('x'));
168 Assert.AreEqual(true, args.has('y'));
169 }
170
171 [TestMethod]
172 public void testSimpleIntPresent()
173 {
174 Args args = new Args("x#", new String[] { "-x", "42" });
175 Assert.AreEqual(1, args.cardinality());
176 Assert.AreEqual(true, args.has('x'));
177 Assert.AreEqual(42, args.getInt('x'));
178 }
179
180 [TestMethod]
181 public void testInvalidInteger()
182 {
183 try
184 {
185 new Args("x#", new String[] { "-x", "Forty two" });
186 //Assert.Fail();
187 }
188 catch (ArgsException e)
189 {
190 Assert.AreEqual(ErrorCode.INVALID_INTEGER, e.ErrorCode);
191 Assert.AreEqual('x', e.ErrorArgumentId);
192 Assert.AreEqual("Forty two", e.ErrorParameter);
193 }
194 }
195
196 [TestMethod]
197 public void testMissingInteger()
198 {
199 try
200 {
201 new Args("x#", new string[] { "-x" });
202 //Assert.Fail();
203 }
204 catch (ArgsException e)
205 {
206 Assert.AreEqual(ErrorCode.MISSING_INTEGER, e.ErrorCode);
207 Assert.AreEqual('x', e.ErrorArgumentId);
208 }
209 }
210
211 [TestMethod]
212 public void testSimpleDoublePresent()
213 {
214 Args args = new Args("x##", new String[] { "-x", "42.3" });
215 Assert.AreEqual(1, args.cardinality());
216 Assert.AreEqual(true, args.has('x'));
217 Assert.AreEqual(42.3, args.getDouble('x'), .001);
218 }
219
220 [TestMethod]
221 public void testInvalidDouble()
222 {
223 try
224 {
225 new Args("x##", new String[] { "-x", "Forty two" });
226 //Assert.Fail();
227 }
228 catch (ArgsException e)
229 {
230 Assert.AreEqual(ErrorCode.INVALID_DOUBLE, e.ErrorCode);
231 Assert.AreEqual('x', e.ErrorArgumentId);
232 Assert.AreEqual("Forty two", e.ErrorParameter);
233 }
234 }
235
236 [TestMethod]
237 public void testMissingDouble()
238 {
239 try
240 {
241 new Args("x##", new String[] { "-x" });
242 //Assert.Fail();
243 }
244 catch (ArgsException e)
245 {
246 Assert.AreEqual(ErrorCode.MISSING_DOUBLE, e.ErrorCode);
247 Assert.AreEqual('x', e.ErrorArgumentId);
248 }
249 }
250 }
251 }
252
第三部分 Args.cs 最终搞
代码
1 /*
2
3 第14章,
4 重构步骤
5 * 1.提取异常类ArgsException,并修改测试代码ArgsTest,支持新的异常类
6 * 2.重构Args
7 * 3.跑ArgsTest
8 * 4.添加异常类型,把FormatException 添加到ArgsException中
9 * 5.把参数类型这一维度上的变化提取到子类中(天空中的声音)。
10 * 6.提取一个子类试试,但是用父类的名称,这里提取boolean
11 * 7.修改setArgument函数,使用多态
12 * 8.删除args数组,使用iterator,原来用了两个变量,现在只用了一个
13 * 9.把setArgument函数中的多态链给去掉
14 * 9.1 把currentArgument改成protected的
15 * 9.2 重写各个子类的set属性
16 * 10.添加一个double类型的类和函数
17 * 11.在传bool类型的参数时,初值设成false如何做?
18 */
19 using System;
20 using System.Collections.Generic;
21 using System.Text;
22 using System.Collections;
23 using System.Security.Policy;
24
25 namespace CleanCode.Library
26 {
27
28
29 public class Args:IDisposable
30 {
31 #region Fileds
32
33 private String schema;
34
35 private bool valid = true;
36 private IList<char> unexpectedArguments = new List<char>();
37
38 private Dictionary<char, ArgumentMarshaler> _argumentMarshalerList = new Dictionary<char, ArgumentMarshaler>();
39
40 private IList<char> argsFound = new List<char>();
41 protected IEnumerator<string> currentArgument;
42 private IList<string> argsList;
43
44 private ErrorCode errorCode = ErrorCode.OK;
45 #endregion
46
47 #region Construcotrs
48 public Args(string schema, string[] args)
49 {
50 this.schema = schema;
51 argsList = new List<string>();
52 for (int i = 0; i < args.Length;i++ )
53 {
54 argsList.Add(args[i]);
55 }
56 valid = parse();
57 }
58 #endregion
59
60 #region Properties
61
62 #endregion
63
64 #region Methods
65 private bool parse()
66 {
67 if (0==schema.Length && 0 == argsList.Count)
68 return true;
69 parseSchema();
70 try
71 {
72 parseArguments();
73 }
74 catch (ArgsException e)
75 {
76 }
77 return valid;
78 }
79 private bool parseSchema()
80 {
81 string[] elementSet = schema.Split(new char[] { ',' });
82 string element = string.Empty;
83 for (int i = 0; i < elementSet.Length;i++ )
84 {
85 element = elementSet[i];
86 if (element.Length > 0)
87 {
88 string trimmedElement = element.Trim();
89 parseSchemaElement(trimmedElement);
90 }
91 }
92 return true;
93 }
94 private void parseSchemaElement(string element)
95 {
96 char elementId = element[0];
97 string elementTail = element.Substring(1);
98 validateSchemaElementId(elementId);
99 if (isBooleanSchemaElement(elementTail))
100 parseBooleanSchemaElement(elementId);
101 else if (isStringSchemaElement(elementTail))
102 parseStringSchemaElement(elementId);
103 else if (isIntegerSchemaElement(elementTail))
104 {
105 parseIntegerSchemaElement(elementId);
106 }
107 else if (isDoubleSchemaElement(elementTail))
108 {
109 parseDoubleSchemaElement(elementId);
110 }
111 else
112 {
113
114 throw new ArgsException(ErrorCode.INVALID_FORMAT,
115 string.Format("Argument: {0} has invalid format: {1}.",
116 elementId, elementTail),
117 elementId);
118 }
119 }
120
121 private void validateSchemaElementId(char elementId)
122 {
123 if (!System.Char.IsLetter(elementId))
124 {
125 //这里为什么是不合法的参数错误?
126 throw new ArgsException(ErrorCode.INVALID_ARGUMENT_NAME,
127 string.Empty,
128 elementId);
129
130 }
131 }
132 private void parseBooleanSchemaElement(char elementId)
133 {
134 _argumentMarshalerList.Add(elementId, new BooleanArgumentMarshaler(true));
135 }
136 private void parseIntegerSchemaElement(char elementId)
137 {
138 _argumentMarshalerList.Add(elementId, new IntegerArgumentMarshaler(0));
139
140 }
141 private void parseStringSchemaElement(char elementId)
142 {
143 _argumentMarshalerList.Add(elementId, new StringArgumentMarshaler(string.Empty));
144 }
145
146 private bool isBooleanSchemaElement(String elementTail)
147 {
148 return elementTail.Length == 0;
149 }
150
151 private bool isStringSchemaElement(String elementTail)
152 {
153 return elementTail.Equals("*");
154 }
155
156 private bool isIntegerSchemaElement(String elementTail)
157 {
158 return elementTail.Equals("#");
159 }
160 private bool parseArguments()
161 {
162 for (currentArgument = argsList.GetEnumerator(); currentArgument.MoveNext(); )
163 {
164 string arg = currentArgument.Current.ToString();
165 parseArgument(arg);
166 }
167 return true;
168 }
169 private void parseArgument(String arg)
170 {
171 if (arg.StartsWith("-"))
172 parseElements(arg);
173 }
174 private void parseElements(String arg)
175 {
176 for (int i = 1; i < arg.Length; i++)
177 parseElement(arg[i]);
178 }
179 private void parseElement(char argChar)
180 {
181 if (setArgument(argChar))
182 argsFound.Add(argChar);
183 else
184 {
185 unexpectedArguments.Add(argChar);
186 errorCode = ErrorCode.UNEXPECTED_ARGUMENT;
187 valid = false;
188 }
189 }
190 private bool setArgument(char argChar)
191 {
192 ArgumentMarshaler m;
193
194 try
195 {
196 if (_argumentMarshalerList.ContainsKey(argChar))
197 {
198 m = _argumentMarshalerList[argChar];
199 }
200 else
201 {
202 return false;
203 }
204
205 m.Set(currentArgument);
206
207 }
208 catch (ArgsException e)
209 {
210
211 valid = false;
212 throw e;
213 }
214 return true;
215 }
216
217 public int cardinality()
218 {
219 return argsFound.Count;
220 }
221
222 public String usage()
223 {
224 if (schema.Length > 0)
225 return "-[" + schema + "]";
226 else
227 return "";
228 }
229
230 private bool falseIfNull(bool b)
231 {
232 return null == b ? false : b;
233 }
234
235 private int zeroIfNull(System.Int32 i)
236 {
237 return null==i ? 0 : i;
238 }
239
240 private string blankIfNull(string s)
241 {
242 return null == s ? string.Empty : s;
243 }
244
245 public string getString(char arg)
246 {
247 return blankIfNull((string)_argumentMarshalerList[arg].Value);
248 }
249
250 public int getInt(char arg)
251 {
252 return zeroIfNull(int.Parse(_argumentMarshalerList[arg].Value.ToString()));
253 }
254
255 public bool getBoolean(char arg)
256 {
257 return falseIfNull((bool)_argumentMarshalerList[arg].Value);
258 }
259
260 public bool has(char arg)
261 {
262 return argsFound.Contains(arg);
263 }
264
265 public bool isValid()
266 {
267 return valid;
268 }
269
270
271 #endregion
272
273 #region 处理double参数的方法
274 private bool isDoubleSchemaElement(string elementTail)
275 {
276 return elementTail.Equals("##");
277 }
278
279 public double getDouble(char arg)
280 {
281 return zeroDoubleIfNull( _argumentMarshalerList[arg].Value);
282 }
283
284 private double zeroDoubleIfNull(object obj)
285 {
286 return null == obj ? 0 : double.Parse(obj.ToString());
287 }
288
289 private void parseDoubleSchemaElement(char elementId)
290 {
291 _argumentMarshalerList.Add(elementId, new DoubleArgumentMarshaler(0));
292
293 }
294 #endregion
295 #region IDisposable 成员
296
297 public void Dispose()
298 {
299 if (null!=_argumentMarshalerList)
300 {
301 _argumentMarshalerList.Clear();
302 }
303 }
304
305 #endregion
306 }
307
308 public interface ArgumentMarshaler
309 {
310 object Value
311 {
312 get;
313 }
314 void Set(IEnumerator<string> currentArgument);
315 }
316
317 public class BooleanArgumentMarshaler:ArgumentMarshaler
318 {
319 private Boolean _boolArguemnt;
320
321 public BooleanArgumentMarshaler(bool boolArguemnt)
322 {
323 this._boolArguemnt = boolArguemnt;
324 }
325
326
327 #region ArgumentMarshaler 成员
328
329 object ArgumentMarshaler.Value
330 {
331 get { return _boolArguemnt; }
332
333 }
334
335 void ArgumentMarshaler.Set(IEnumerator<string> currentArgument)
336 {
337 try
338 {
339
340 _boolArguemnt =true;
341 }
342 catch (IndexOutOfRangeException e)
343 {
344
345 ErrorCode errorCode = ErrorCode.INVALID_BOOLEAN;
346
347 throw new ArgsException(errorCode, string.Empty);
348 }
349
350 }
351
352 #endregion
353
354
355 }
356
357 public class StringArgumentMarshaler : ArgumentMarshaler
358 {
359 private string _stringArguemnt;
360 public StringArgumentMarshaler(string stringArguemnt)
361 {
362 this._stringArguemnt = stringArguemnt;
363 }
364 object ArgumentMarshaler.Value
365 {
366 get { return _stringArguemnt; }
367
368 }
369 void ArgumentMarshaler.Set(IEnumerator<string> currentArgument)
370 {
371 currentArgument.MoveNext();
372 try
373 {
374
375 _stringArguemnt= currentArgument.Current;
376 }
377 catch (InvalidOperationException e)
378 {
379
380 ErrorCode errorCode = ErrorCode.MISSING_STRING;
381 char errorArgumentId = '\0';
382 throw new ArgsException(errorCode, string.Empty, errorArgumentId);
383 }
384
385 }
386 }
387 public class IntegerArgumentMarshaler : ArgumentMarshaler
388 {
389 private System.Int32 _intArguemnt;
390 public IntegerArgumentMarshaler(int intArguemnt)
391 {
392 this._intArguemnt = intArguemnt;
393 }
394
395 object ArgumentMarshaler.Value
396 {
397 get { return _intArguemnt; }
398
399 }
400
401 void ArgumentMarshaler.Set(IEnumerator<string> currentArgument)
402 {
403 try
404 {
405 currentArgument.MoveNext();
406 _intArguemnt = int.Parse(currentArgument.Current.ToString());
407 }
408 catch (System.NullReferenceException ne)
409 {
410
411 throw new ArgsException(ErrorCode.MISSING_INTEGER);
412 }
413 catch (InvalidOperationException e)
414 {
415
416 ErrorCode errorCode = ErrorCode.MISSING_INTEGER;
417 throw new ArgsException(errorCode, string.Empty);
418 }
419
420 catch (InvalidCastException ice)
421 {
422 throw new ArgsException(ErrorCode.INVALID_FORMAT);
423 }
424 catch (FormatException fx)
425 {
426 throw new ArgsException(ErrorCode.INVALID_FORMAT);
427 }
428 }
429 }
430
431 public class DoubleArgumentMarshaler : ArgumentMarshaler
432 {
433 private double _argument;
434 public DoubleArgumentMarshaler(double argument)
435 {
436 this._argument = argument;
437 }
438
439 object ArgumentMarshaler.Value
440 {
441 get { return _argument; }
442
443 }
444
445 void ArgumentMarshaler.Set(IEnumerator<string> currentArgument)
446 {
447 try
448 {
449 currentArgument.MoveNext();
450 _argument = double.Parse(currentArgument.Current);
451 }
452 catch (System.ArgumentNullException ex)
453 {
454
455 throw new ArgsException(ErrorCode.MISSING_DOUBLE);
456 }
457 catch (InvalidOperationException e)
458 {
459
460 ErrorCode errorCode = ErrorCode.MISSING_DOUBLE;
461 throw new ArgsException(errorCode, string.Empty);
462 }
463
464 catch (InvalidCastException ice)
465 {
466 throw new ArgsException(ErrorCode.INVALID_FORMAT);
467 }
468 catch (FormatException fx)
469 {
470 throw new ArgsException(ErrorCode.INVALID_FORMAT);
471 }
472 }
473 }
474 }
第四部分 异常类 ArgsException.cs
代码
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CleanCode.Library
6 {
7
8 public enum ErrorCode
9 {
10 OK, MISSING_STRING, MISSING_INTEGER, INVALID_INTEGER, INVALID_BOOLEAN, UNEXPECTED_ARGUMENT,
11 INVALID_FORMAT, INVALID_ARGUMENT_NAME, INVALID_DOUBLE, MISSING_DOUBLE
12 }
13 public class ArgsException: Exception
14 {
15
16 #region Fileds
17 private ErrorCode _errorCode;
18 private string _msg;
19 private char _errorArgumentId = '\0';
20 private String _errorParameter = "TILT";
21 #endregion
22
23 #region Constructors
24 public ArgsException()
25 {
26 _msg = string.Empty;
27 _errorCode = ErrorCode.OK;
28 }
29
30 public ArgsException(ErrorCode errCode):this(errCode,string.Empty)
31 {
32 _msg = string.Empty;
33 _errorCode = errCode;
34 }
35
36 public ArgsException(ErrorCode errCode, string message)
37 : base(message)
38 {
39 _msg = message;
40 _errorCode = errCode;
41 }
42 public ArgsException(ErrorCode errCode, string message, char errorArgumentId)
43 : this(errCode, message)
44 {
45 _errorArgumentId = errorArgumentId;
46 }
47
48 public ArgsException(ErrorCode errCode, string message, char errorArgumentId, string errorParameter)
49 : this(errCode, message, errorArgumentId)
50 {
51 _errorParameter = errorParameter;
52 }
53
54 #endregion
55
56 #region Properties
57 public ErrorCode ErrorCode
58 {
59 get { return _errorCode; }
60 }
61
62 public char ErrorArgumentId
63 {
64 get { return this._errorArgumentId; }
65 }
66
67 public string ErrorParameter
68 {
69 get { return _errorParameter; }
70 }
71 #endregion
72
73
74 #region Message
75 public String errorMessage()
76 {
77 switch (_errorCode)
78 {
79 case ErrorCode.OK:
80 throw new Exception("TILT: Should not get here.");
81 case ErrorCode.UNEXPECTED_ARGUMENT:
82 return "Unexcepted argument exception.";
83 case ErrorCode.MISSING_STRING:
84 return String.Format("Could not find string parameter for -{0}.",
85 _errorArgumentId);
86 case ErrorCode.INVALID_INTEGER:
87 return String.Format("Argument -{0} expects an integer but was '{1}'.",
88 _errorArgumentId, _errorParameter);
89 case ErrorCode.MISSING_INTEGER:
90 return String.Format("Could not find integer parameter for -{0}.",
91 _errorArgumentId);
92
93 case ErrorCode.INVALID_DOUBLE:
94 return String.Format("Argument -{0} expects an double but was '{1}'.",
95 _errorArgumentId, _errorParameter);
96 case ErrorCode.MISSING_DOUBLE:
97 return String.Format("Could not find double parameter for -{0}.",
98 _errorArgumentId);
99 }
100 return string.Empty;
101 }
102
103
104 #endregion
105 }
106 }
107
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。