[毕业生的商业软件开发之路]尽早暴露错误原则
2011-08-30 11:16
281 查看
近期开始接触到在校学生、高校实习生和毕业生,在此说一下笔者对这些徘徊在职场门口的学生一些建议,希望能给这些初学者进入软件开发行业带来一些帮助,使得毕业生能更顺利的进入软件开发公司开始职场生涯,人生来一个完美的转弯。
-----------------------------------------------------------------------
开发者应当遵守“尽早暴露错误”的开发原则,这是因为程序错误是客观存在的事实,应当正视它并有效的处理它,而不是简单粗暴的和谐掉。而且在开发中应当尽早暴露出程序的错误,这有助于发现错误的本质,帮助改善程序质量;若一味的和谐掩盖错误,则错误越拖影响越大,最后不可收拾,程序崩溃。[袁永福版权所有]
下面举个这条原则的例子,现数据库中有一个名为Customers的数据表,其内容如下:
对此笔者可以写出以下的两种代码来读取并输出其中的数据:
第一种:
using (IDbConnection conn = new OleDbConnection())
{
// 连接数据库
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ System.IO.Path.Combine(Application.StartupPath, "Customers.mdb");
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
// 设置SQL语句
cmd.CommandText = @"
Select
CustomerID ,
CompanyName ,
ContactName ,
ContactTitle ,
Address ,
City
From Customers";
// 读取并输出数据
IDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
Console.WriteLine("CustomerID =" + reader["CustomerID"]);
Console.WriteLine("CompanyName =" + reader["CompanyName"]);
Console.WriteLine("ContactName =" + reader["ContactName"]);
Console.WriteLine("ContactTitle=" + reader["ContactTitle"]);
Console.WriteLine("Address =" + reader["Address"]);
Console.WriteLine("City =" + reader["City"]);
}//if
reader.Close();
}//using
}//using
第二种:
using (IDbConnection conn = new OleDbConnection())
{
// 连接数据库
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ System.IO.Path.Combine(Application.StartupPath, "Customers.mdb");
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
// 设置SQL语句
cmd.CommandText = @"Select * From Customers";
// 读取并输出数据
IDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
Console.WriteLine("CustomerID =" + reader["CustomerID"]);
Console.WriteLine("CompanyName =" + reader["CompanyName"]);
Console.WriteLine("ContactName =" + reader["ContactName"]);
Console.WriteLine("ContactTitle=" + reader["ContactTitle"]);
Console.WriteLine("Address =" + reader["Address"]);
Console.WriteLine("City =" + reader["City"]);
}//if
reader.Close();
}//using
}//using
这两种代码的唯一的区别就在于其中使用了不同的SQL语句,第一种代码使用的SQL语句是
而第二种代码使用的SQL语句是
第一种SQL语句字符比较多,开发者比较懒的话很容易写出第二种SQL语句。不过笔者推荐使用第一种SQL语句,因为第一种SQL语句符合尽早暴露程序错误的原则。[袁永福版权所有]
如果当数据库没有问题,则两种SQL语句都能执行,程序都能正确的读取数据,此时第二种写法反而貌似不错。
不过实际中应用程序开发和运行环境很复杂,比如发生了代码中字段名拼写错误、数据库字段结构发生改变,这些都是需要考虑到的问题。
例如数据表[袁永福版权所有]Customers中的字段Address由于某种原因删掉了,于是这两种代码都会发生错误。
对于第一种代码,程序会在执行代码“IDataReader reader = cmd.ExecuteReader();”时就会爆出异常“至少一个参数没有指定值 OleDbException”。此时开发者借助VS.NET可以很快的确定出发生错误的代码,并根据错误提示很容易猜测SQL语句写错了。于是开发者进行SQL语句与数据库结构的对比,很快就能发现错误的本质,那就是字段Address突然没了。
而对于第二种代码,程序顺利的执行了代码“IDataReader reader = cmd.ExecuteReader();”,但在执行代码“Console.WriteLine("Address =" + reader["Address"]);”时爆出异常“Address IndexOutOfRangeException”。对于这个错误,开发者首先会有些迷惑,不知为什么发生错误,因为错误提示信息和数据库联系不大,而后怀疑代码中的“reader["Address"]”出现字段名拼写错误,花上一段时间仔细校对确定无误后才会往前继续寻找错误的来源,会发现SQL语句没有拼写错误,最后才会想到去查数据库结构,绕了半天才发现数据库字段Address没了,这才是错误的本质。
在这个例子中,数据库字段Address删掉的那一刻起,系统就存在隐患,而第一种代码能在第一时间由于这个隐患而爆出错误,而开发者就能立即定位到离隐患最近的代码,得到跟隐患密切相关的错误提示信息,也就能非常快的发现问题的本质,从而解决问题。这是一种将错误扼杀在摇篮当中的做法,对开发者对程序都有好处。[袁永福版权所有]
而第二种代码很和谐,没能在第一时间让隐患爆出错误,让隐患养着更肥,一直默默的影响着程序的运行,最终隐患爆出更大的更让人摸不着头脑的错误,使得开发者需要花费更多的时间精力来处理这个错误,这是姑息隐患,将错误养大了出栏再杀的做法,对开发者对程序都有害处。
在VB中有一个写作“On Error Resume Next”的语句,号称能和谐掉程序中所有的错误,让程序不爆出任何异常,丫就彻彻底底的破坛子破摔、掩耳盗铃的做法,因此这种写法应用得比较少。
因此开发者要写出一个真正和谐的程序,其过程必然不能简单粗暴的和谐,要尽可能早的让各种隐患爆出程序错误;隐患要上访变成错误,程序不能打击压制,而且程序要疏通各种隐患上访的通道,让开发者更快的发现错误的本质,更快的解决错误。尊重科学规律,正视隐患和错误,正确处理错误而不是打压隐患,程序才能和谐健壮。
嘿嘿,人类社会又何尝不是这样啊。[袁永福版权所有]
-----------------------------------------------------------------------
开发者应当遵守“尽早暴露错误”的开发原则,这是因为程序错误是客观存在的事实,应当正视它并有效的处理它,而不是简单粗暴的和谐掉。而且在开发中应当尽早暴露出程序的错误,这有助于发现错误的本质,帮助改善程序质量;若一味的和谐掩盖错误,则错误越拖影响越大,最后不可收拾,程序崩溃。[袁永福版权所有]
下面举个这条原则的例子,现数据库中有一个名为Customers的数据表,其内容如下:
CustomerID | CompanyName | ContactName | ContactTitle | Address | City |
1 | 少室山公司 | 方证 | 采购员 | 东园西甲 30 号 | 长平 |
2 | 擎天航空 | 雷震子 | 销售代表 | 常保阁东 80 号 | 莫斯科 |
3 | 华夏工程 | 李大禹 | 市场经理 | 广发北路 10 号 | 幽州 |
4 | 武当投资 | 宋青书 | 物主 | 临翠大街 80 号 | 巴伐利亚 |
5 | 擎天南京公司 | 大星星 | 物主 | 花园东街 90 号 | 许安 |
第一种:
using (IDbConnection conn = new OleDbConnection())
{
// 连接数据库
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ System.IO.Path.Combine(Application.StartupPath, "Customers.mdb");
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
// 设置SQL语句
cmd.CommandText = @"
Select
CustomerID ,
CompanyName ,
ContactName ,
ContactTitle ,
Address ,
City
From Customers";
// 读取并输出数据
IDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
Console.WriteLine("CustomerID =" + reader["CustomerID"]);
Console.WriteLine("CompanyName =" + reader["CompanyName"]);
Console.WriteLine("ContactName =" + reader["ContactName"]);
Console.WriteLine("ContactTitle=" + reader["ContactTitle"]);
Console.WriteLine("Address =" + reader["Address"]);
Console.WriteLine("City =" + reader["City"]);
}//if
reader.Close();
}//using
}//using
第二种:
using (IDbConnection conn = new OleDbConnection())
{
// 连接数据库
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ System.IO.Path.Combine(Application.StartupPath, "Customers.mdb");
conn.Open();
using (IDbCommand cmd = conn.CreateCommand())
{
// 设置SQL语句
cmd.CommandText = @"Select * From Customers";
// 读取并输出数据
IDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
Console.WriteLine("CustomerID =" + reader["CustomerID"]);
Console.WriteLine("CompanyName =" + reader["CompanyName"]);
Console.WriteLine("ContactName =" + reader["ContactName"]);
Console.WriteLine("ContactTitle=" + reader["ContactTitle"]);
Console.WriteLine("Address =" + reader["Address"]);
Console.WriteLine("City =" + reader["City"]);
}//if
reader.Close();
}//using
}//using
这两种代码的唯一的区别就在于其中使用了不同的SQL语句,第一种代码使用的SQL语句是
Select CustomerID , CompanyName , ContactName , ContactTitle , Address , City From Customers |
Select * From Customers |
如果当数据库没有问题,则两种SQL语句都能执行,程序都能正确的读取数据,此时第二种写法反而貌似不错。
不过实际中应用程序开发和运行环境很复杂,比如发生了代码中字段名拼写错误、数据库字段结构发生改变,这些都是需要考虑到的问题。
例如数据表[袁永福版权所有]Customers中的字段Address由于某种原因删掉了,于是这两种代码都会发生错误。
对于第一种代码,程序会在执行代码“IDataReader reader = cmd.ExecuteReader();”时就会爆出异常“至少一个参数没有指定值 OleDbException”。此时开发者借助VS.NET可以很快的确定出发生错误的代码,并根据错误提示很容易猜测SQL语句写错了。于是开发者进行SQL语句与数据库结构的对比,很快就能发现错误的本质,那就是字段Address突然没了。
而对于第二种代码,程序顺利的执行了代码“IDataReader reader = cmd.ExecuteReader();”,但在执行代码“Console.WriteLine("Address =" + reader["Address"]);”时爆出异常“Address IndexOutOfRangeException”。对于这个错误,开发者首先会有些迷惑,不知为什么发生错误,因为错误提示信息和数据库联系不大,而后怀疑代码中的“reader["Address"]”出现字段名拼写错误,花上一段时间仔细校对确定无误后才会往前继续寻找错误的来源,会发现SQL语句没有拼写错误,最后才会想到去查数据库结构,绕了半天才发现数据库字段Address没了,这才是错误的本质。
在这个例子中,数据库字段Address删掉的那一刻起,系统就存在隐患,而第一种代码能在第一时间由于这个隐患而爆出错误,而开发者就能立即定位到离隐患最近的代码,得到跟隐患密切相关的错误提示信息,也就能非常快的发现问题的本质,从而解决问题。这是一种将错误扼杀在摇篮当中的做法,对开发者对程序都有好处。[袁永福版权所有]
而第二种代码很和谐,没能在第一时间让隐患爆出错误,让隐患养着更肥,一直默默的影响着程序的运行,最终隐患爆出更大的更让人摸不着头脑的错误,使得开发者需要花费更多的时间精力来处理这个错误,这是姑息隐患,将错误养大了出栏再杀的做法,对开发者对程序都有害处。
在VB中有一个写作“On Error Resume Next”的语句,号称能和谐掉程序中所有的错误,让程序不爆出任何异常,丫就彻彻底底的破坛子破摔、掩耳盗铃的做法,因此这种写法应用得比较少。
因此开发者要写出一个真正和谐的程序,其过程必然不能简单粗暴的和谐,要尽可能早的让各种隐患爆出程序错误;隐患要上访变成错误,程序不能打击压制,而且程序要疏通各种隐患上访的通道,让开发者更快的发现错误的本质,更快的解决错误。尊重科学规律,正视隐患和错误,正确处理错误而不是打压隐患,程序才能和谐健壮。
嘿嘿,人类社会又何尝不是这样啊。[袁永福版权所有]
相关文章推荐
- [毕业生的商业软件开发之路]尽早暴露错误原则 推荐
- [毕业生的商业软件开发之路]Windows窗体设计概念及原则
- [毕业生的商业软件开发之路]Windows窗体设计概念及原则
- [毕业生的商业软件开发之路]Windows窗体设计概念及原则 (转载自博客园)
- 毕业生的商业软件开发之路-最小权限原则
- 毕业生的商业软件开发之路--技术之害
- [毕业生的商业软件开发之路]解决方案资源管理器 推荐
- [毕业生的商业软件开发之路]C#表达式以及判断语法结构
- [毕业生的商业软件开发之路]C#异常处理
- [毕业生的商业软件开发之路]系列文章目录规划
- [毕业生的商业软件开发之路]解决方案资源管理器
- [毕业生的商业软件开发之路]C#类型成员 推荐
- [毕业生的商业软件开发之路]C#表达式以及判断语法结构 推荐
- 毕业生的商业软件开发之路 --- C#基本语法-C#代码模块逻辑框架
- [毕业生的商业软件开发之路]C#类型成员
- [毕业生的商业软件开发之路]C#进阶建议 推荐
- 毕业生的商业软件开发之路 --- 现代商业软件开发概况
- [毕业生的商业软件开发之路] C#类型2
- [毕业生的商业软件开发之路]积累与创新 推荐
- [毕业生的商业软件开发之路]现代商业软件开发概况 推荐