代码复审
一、概要
经过代码复审,代码可读性较好,比较容易维护,但代码缺少注释,且代码没有逐行都执行并检查过。
二、设计规范部分
项目模式遵从已知的设计模式或项目中常用的模式,没有硬编码或字符串/数字等存在,
代码在IE,firefox等平台下都可运行没有依赖于单一平台不会影响将来的移植。
但是存在无用的代码可以清除,如:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using CodingCook.SQL; namespace CodingCook { namespace Affairs { public class Answer { public struct AnswerList { public int qid; public int aid; public int uid; public string createdTime; public string modifiedTime; public string content; } public int GiveAnswer(int qid, int uid, string content) { return new AnswerSQL().Insert(uid, qid, content); } public int Modify(int aid, string content) { return new AnswerSQL().Update(aid, content); } /* public string[] Show(int qid) { int i = 0; AnswerList[] answers; string[] columns = { "qid", "aid", "uid", "created", "modified", "content" }; SqlDataReader sr = SelectAll(columns); while (sr.Read()) { answers[i].qid = sr[0]; answers[i].aid = sr[1]; answers[i].uid = sr[2]; answers[i].createdTime = sr[3].ToString(); answers[i].modifiedTime = sr[4].ToString(); answers[i].content = sr[5].ToString(); i++; } sr.Close(); } */ } } }
可以将无用代码清除。
三、代码规范部分
缩进符合要求,行宽合适,括号逻辑表达清楚。
断行与空白的{ }行有少数情况下存在问题,如:
此处可以加大括号,最好每个“{”和“}”都独占一行。
分行部分存在有问题的地方,如:
不要把多行语句放在一行上。更严格地说,不要把不同的变量定义在一行上。
在命名问题上,大部分还是做的很好的
所有的类型/类/函数名都用Pascal形式,所有的变量都用Camel形式。
类/类型/变量:名词或组合名词,如Member、ProductInfo等。
函数则用动词或动宾组合词来表示,如get/set; RenderPage()。
命名在下划线上也没有问题
但是代码缺少注释,只能通过代码本身理解代码,是重大的问题之一。
四、具体代码部分
有对错误进行处理,对于调用的外部函数检查了返回值并处理了异常。
以上是截图,下面是代码。
public int Update(int aid, string content) { content = CodingCook.Helper.AntiInjection.ReplaceSingleQuote(content); if (content == null || content.Trim() == "") return -1; //string nowDate = DateTime.Now.ToString("f"); connection.Open(); StringBuilder updateSQL = new StringBuilder( string.Format("UPDATE Answer SET content = '{0}', lastmodified = getdate() WHERE aid = {1}", content, aid)); SqlCommand update = new SqlCommand(updateSQL.ToString(), connection); int lineAffected; try { lineAffected = update.ExecuteNonQuery(); } catch (Exception) { Console.WriteLine("AnswerSQL的SQL语句失败。\n"); lineAffected = -1; } connection.Close(); return lineAffected; }
public SqlDataReader SelectAll(string[] columns) { if (columns.Length == 0) return null; connection.Open(); StringBuilder selectSQL = new StringBuilder("SELECT "); string attris = string.Join(", ", columns); selectSQL.AppendFormat("{0} FROM Answer ;", attris); SqlCommand select = new SqlCommand(selectSQL.ToString(), connection); SqlDataReader dataReader; try { dataReader = select.ExecuteReader(CommandBehavior.CloseConnection); } catch (Exception) { Console.WriteLine("Answer 的SelectAll失败.\n"); dataReader = null; } return dataReader; }
可以看出,申请数据库连接资源得到了及时的释放,对可能出现错误的地方做了try,catch处理,对返回值做了检查。
参数传递无错误,字符串的长度字节长度和字符长度都存在,以0开始计数,循环没有出现死循环。
申请及时适时释放,没有可能导致资源泄露。数据结构中没有无用的元素。
以上是截图,以下是源代码
public List<CommentModel> CommentList(int qid, int aid) { List<CommentModel> cs = new List<CommentModel>(); string[] columns = {"comment_id", "uid", "created", "lastmodified", "content" }; SqlDataReader reader = new CodingCook.SQL.CommentSQL().Select(columns, qid, aid); while (reader.Read()) { DateTime cr = DateTime.Parse(reader[2].ToString()); DateTime mo = DateTime.Parse(reader[3].ToString()); cs.Add(new CommentModel(qid, aid, (int)reader[0], (int)reader[1], cr, mo, reader[4].ToString())); } reader.Close(); return cs; }
五、可读性
以下是源代码
namespace CodingCook { namespace SQL { public class CommentSQL : SQL.SQLBase { // aid 和 qid 有且仅有一个为 -1,返回comment_id public int Insert(int uid, int qid, int aid, string content) { if (aid == -1 && qid == -1) return -1; if (aid != -1 && qid != -1) return -1; bool contentExist = false; content = CodingCook.Helper.AntiInjection.ReplaceSingleQuote(content); if (content != null && content.Trim() != "") contentExist = true; connection.Open(); StringBuilder insertSQL = new StringBuilder("INSERT INTO Comment(uid, qid, aid, "); if (contentExist) insertSQL.Append("content, "); insertSQL.AppendFormat("created, lastmodified) OUTPUT inserted.comment_id VALUES({0}, {1}, {2}, ", uid, qid, aid); if (contentExist) insertSQL.AppendFormat("'{0}', ", content); insertSQL.Append("getdate(), getdate());"); SqlCommand insert = new SqlCommand(insertSQL.ToString(), connection); int comment_id; try { comment_id = Convert.ToInt32(insert.ExecuteScalar()); } catch (Exception) { Console.WriteLine("CommentSQL的执行失败\n"); comment_id = -1; } connection.Close(); return comment_id; } public int Update(int comment_id, string content) { if (content == null || content.Trim() == "") return -1; connection.Open(); StringBuilder UpdateSQL = new StringBuilder( string.Format("UPDATE Comment SET content = '{0}', lastmodified = getdate() WHERE commen_id = {1}", content, comment_id)); SqlCommand update = new SqlCommand(UpdateSQL.ToString(), connection); int lineAffected; try { lineAffected = update.ExecuteNonQuery(); } catch (Exception) { Console.WriteLine("CommentSQL的执行失败\n"); lineAffected = -1; } connection.Close(); return lineAffected; } public SqlDataReader Select(string[] columns, int qid, int aid) { if (columns.Length == 0) return null; connection.Open(); string where = "qid"; if (qid == -1) { where = "aid"; } StringBuilder selectSQL = new StringBuilder("SELECT "); string attris = string.Join(", ", columns); selectSQL.AppendFormat("{0} FROM Comment WHERE {1} = {2};", attris, where, aid); SqlCommand select = new SqlCommand(selectSQL.ToString(), connection); SqlDataReader dataReader; try { dataReader = select.ExecuteReader(CommandBehavior.CloseConnection); } catch (Exception) { Console.WriteLine("Comment 的Select失败.\n"); dataReader = null; } return dataReader; } public SqlDataReader SelectAll(string[] columns) { if (columns.Length == 0) return null; connection.Open(); StringBuilder selectSQL = new StringBuilder("SELECT "); string attris = string.Join(", ", columns); selectSQL.AppendFormat("{0} FROM Comment ;", attris); SqlCommand select = new SqlCommand(selectSQL.ToString(), connection); SqlDataReader dataReader; try { dataReader = select.ExecuteReader(CommandBehavior.CloseConnection); } catch (Exception) { Console.WriteLine("Comment 的SelectAll失败.\n"); dataReader = null; } return dataReader; } } } }
整体代码结构清晰,但缺少注释,不是很容易读懂,可以看出变量命名还是通俗易懂的,但只有一行注释,以后应该补上详细的注释。
六、可测试性
代码需要更新或创建新的单元测试,但目前还没有完成全部的单元测试。
Coding Cook小组 最终评分,93分。
主要扣分在注释少,if语句大括号使用不频繁上。整体代码风格良好,缩进整齐,
命名方式绝大多数很规范,因为代码量大,没有来得及每个方法都经行单元测试也是扣分点之一,
但总的来说还是很好的代码书写习惯。