艾伟也谈项目管理,我是如何带领团队开发项目的
最近有不少朋友寫信問我一些關于團隊開發的問題,由于這段時間有些忙,沒有回復.今天寫一篇這方面的文章向大家介紹一下我是如何帶領團隊開發工作流項目的
關于團隊建設,項目管理的文章網上已經有很多了,在這里我就不談這些理論了,直接給大家展示一個我在 項目開發方,后臺服務開發方式,前臺UI開發方式,后臺服務與前臺UI對接方式,代碼文檔,頁面的開發文檔,源碼管理,單元測試,以及單元測試文檔,實現思路設計文檔,數據庫文檔,數據庫設計規范,編碼規范,操做數據的方法命名規則 方面的一些片斷,這是一個為期6個月的工作流平臺開發項目,是今年3月份啟動的,現在已完成,比計劃時間多出25天.核心開發人員(不包括美工,需求,黑盒測試)共有12人(編號從114到125)
補充一點:在UI草圖設計上,這次想用繪圖板,但最后還是使用鉛筆繪制+掃描的方式制做的.
項目開發方式說明圖
?
后臺服務開發方式說明圖
?
前臺UI開發方式說明圖
后臺服務與前臺UI對接方式說明圖
?
代碼文檔(片斷節選)
| √ | 方法簽名 | public int? addBaseEnumeration(string powerID, List list) |
| √ | 返回值 |
|
| √ | 參數 |
|
| √ | 約束 | <1> 調用[security.checkPowerID方法]判斷[powerID],如果[security.checkPowerID方法]返回[false],返回[401] <2> 如果參數[list]為[null],返回[-1] <3> 如果參數[list]中的[baseEnumeration.rowID]為[Guid.Empty],返回[-2] <4> 如果參數[list]中的[baseEnumeration.entity]為[null]或[string.Empty], 返回[-3] <5> 如果參數[list]中的[baseEnumeration.field]為[null]或[string.Empty], 返回[-4] <6> 如果參數[list]中的[baseEnumeration.entityType]為[null]或[string.Empty], 返回[-5] <7> 如果參數[list]中的[baseEnumeration.title]為[null]或[string.Empty], 返回[-6] <8> 如果參數[list]中的[baseEnumeration.value]為[null]或[string.Empty], 返回[-7] <9> 如果參數[list]中存在[rowID]重復的記錄,返回[-8] <10>如果參數[list]中存在[entity][field][value]重復的記錄,返回[-9] <11>如果參數[list]中的[baseEnumeration.rowID]在數據庫中已存在, 返回[3] <12>如果聯合唯一索引[entity][field][value]在數據庫中已存在, 返回[4] <13>如果參數[entity]為["baseEnumeration"],[field]為[entitytype]的數據,返回[7] <14>如果參數[entityType]的傳入值不是枚舉表[entitytype]的基礎枚舉數據, 返回[5] <15>如果插入時數據庫異常, 返回[6] |
| √ | 說明 | [Entity][field][value] 聯合唯一索引 <14>獲取[Entitytype]基礎枚舉數據時,使用[23 selectBaseEnumerationTypeName]得到枚舉類型名稱 |
| √ | 單元測試 | (組合測試),(自動判斷返回狀態),(自動判斷返回結果) WFServiceTestProject. manageServiceTest. addBaseEnumerationTest() |
?
| //[26] 批量添加枚舉 public int? addBaseEnumeration(string powerID, List list) { //<1> if (!security.checkPowerID(powerID)) { return 401; } //<2> if (list == null) { return -1; } using (wxwinterDBDataContext db = new wxwinterDBDataContext()) { //<3> if (list.Count(p => p.rowID == Guid.Empty) > 0) { return -2; } //<4> if (list.Count(p => string.IsNullOrEmpty(p.entity)) > 0) { return -3; } //<5> if (list.Count(p => string.IsNullOrEmpty(p.field)) > 0) { return -4; } //<6> if (list.Count(p => string.IsNullOrEmpty(p.entityType)) > 0) { return -5; } ............................... |
頁面的開發文檔(片斷節選)
| 模塊編號 | Wxwinter.Index.Power.manageDutyControl | |
| 模塊需要調用的其它UI模塊列表 | Wxwinter.Index.Power.insertDutyControl Wxwinter.Index.Power.changeDutyControl | |
| 模塊的調用入口UI | Wxwinter.Index.Power.navigationOrganizationControl | |
| UI類型 | [ V ] 中控件 700 * 500 | |
| 工具欄按鈕的調用路徑 | [ V ] 無工具欄 | |
| 模塊調用方式 | [ V ] 模式化彈出框 | |
| action說明 | 不需要action | |
?
源碼管理
?
單元測試,以及單元測試文檔(片斷節選)
文檔
| × | 方法簽名 | public int? transactComplete(string powerID , Guid instanceID , Guid stateID , string transactResult , status status) |
| × | 返回值 |
|
| × | 參數 |
|
| × | 約束 | <1>調用[security.checkPowerID方法]判斷[powerID],如果[security.checkPowerID方法]返回[false],返回[401] <2>調用[checkInstanceState()]方法對[instanceID][stateID]指定的實例狀態進行驗證,返回值不為[null],返回[checkInstanceState()]的返回值 <3>調用[checkStatus()]方法對[status]進行驗證,返回值不為[null],返回[checkStatus()]的返回值 <4>得到[wfStateTransactTask]表中 [ wfStateTransactTask.instanceID = instanceID && wfStateTransactTask.stateID = stateID && wfStateTransactTask.departmentNo = status.departmentNo && wfStateTransactTask.dutyNo = status.dutyNo && wfStateTransactTask.personNo = status.personNo ] 的記錄并賦給變量[taskInfo],如果不存在,返回[1] <5>如果[taskInfo.runState != runState.wait],返回[2] <6>修改 [ taskInfo.runState=runState.end taskInfo.completeTime=System.DateTime.Now taskInfo.transactResult=transactResult ] 用[taskInfo]修改[wfStateTransactTask]表中記錄 <7>向[wfStepList]中插入數據 [ flowID = taskInfo.flowID flowName = taskInfo.flowName nodeID = taskInfo.nodeID nodeName = taskInfo.nodeName departmentNo = status.departmentNo departmentName = status.departmentName dutyNo = status.dutyNo dutyName = status.dutyName personNo = status.personNo personName = status.personName instanceID = taskInfo.instanceID stateID = taskInfo.stateID processID = taskInfo.processID processName = taskInfo.processName stepAction = stepAction.辦理 stepTime = System.DateTime.Now taskID = stepAction.辦理 ] <8>如果數據庫提交失敗,返回[3],成功,返回[null] |
| × | 說明 | 調用[checkInstanceState()]方法對實例狀態進行驗證 |
| × | 單元測試 | ? |
?
單元測試選項
| 范圍 | 判斷 | 影響 |
| (無) ? (不需要) ? (全路徑) ? (正常路徑) ? (簡單調用) ? (組合測試) ? (已在外部調試通過) | (自動判斷返回狀態) ? (自動判斷返回結果) ? (人工判斷返回結果,結果控制臺輸出) ? (人工判斷返回結果,結果存入磁盤) ? (自動判斷操作結果) ? (人工判斷操作結果,結果存入數據庫) ? (人工判斷操作結果,結果存入數據庫) ? (不出異常即可) ? (說明…) | (操作數據庫,完成測試后已復原) ? (操作數據庫,已做state標記) ? (操作數據庫,需要手工復原) ? (操作臨時數據庫) |
實現思路設計文檔(片斷節選)
例1:工作流結構的解析
例2:刪除部門職能人員的約束
?
例3:查詢用戶的模塊權限
public List<viewRelationModel> searchModelPowerOfPerson(string powerID,string personNo)
searchModelPowerOfPerson("","user1")
| step1 | 使用 searchStatusList("", "user1") 得到[得到身份列表]
| |||||||||||||||||||||||||
| step2 | 用得到的身份與[powerRelationModel]對比,并返回如下算法的集合
|
?
數據庫文檔
wfFlow 流程表
表說明:存儲流程模板的屬性信息,該表內容是將xoml存入時,解析xoml后一次性生成的,不能修改
| flowID | 流程編號 | f1 | 來自iFlow |
| flowName | 流程名稱 | f2 | |
| flowType | 流程類型 | f3 | |
| flowDescription | 流程說明 | f4 | |
| businessType | 業務類型 | f5 | |
| startWindow | 啟動窗體 | f6 | |
| dataFormList | 表單列表 | f7 | |
| startDataForm | 啟動時填寫的表單 | f8 | |
| inputFormItems | 傳入表單 | f9 | |
| inputFormItemsExpandData | 傳入表單擴展數據 | f10 | |
| commandOption | 命令選項 | f11 | |
| commandOptionExpandData | 命令選項擴展數據 | f12 | |
| ownedType | 流程歸屬類型 | f13 | |
| timelimitUnit | 時限單位 | l1 | 來自iTimelimit |
| timelimit | 時限 | l2 | |
| overtimeOperate | 超時操作 | l3 | |
| calendar? | 日歷 | l4 | |
| residualTimelimit | 剩余時限 | l5 | |
| createDepartmentNo | 創建部門編號 | 創建該流程模板的人員所在部門的編號 | |
| createDepartmentName | 創建部門名稱 | ? | |
| createDutyNo | 創建職能編號 | 創建該流程模板的人員所擔任的職能的編號 | |
| createDutyName | 創建職能名稱 | ? | |
| createPersonNo | 創建人員編號 | 創建該流程模板的人員的編號 | |
| createPersonName | 創建人員名稱 | ? | |
| createTime | 創建時間 | ? | |
| isCheckout | 是否簽出 | 如果為真,簽出人可以對流程模板進行修改,非簽出人不能再將該模板簽出進行修改,如果為假,就可以將該流程簽出進行修改 | |
| checkoutPersonNo | 簽出人員編號 | ? | |
| checkoutPersonName | 簽出人員名稱 | ? | |
| checkoutTime | 簽出時間 | ? | |
| checkinTime | 簽入時間 | ? | |
| isFreeze | 是否凍結 | 如果為真,流程模板處于凍結狀態,不能被啟動 如果為假,流程模板可以正常啟動 | |
wfFlow 流程表 表結構
數據庫設計規范(片斷節選)
| SQL Server 類型 | C# 類型 | 說明 |
| nvarchar(50) | string |
對應的UI為單行行文本框,標簽,提示文字 |
| nvarchar(255) | string |
對應的UI為垂直滾動條的多行文本框,或多段的標簽 |
| nvarchar(MAX) | string |
對應的UI為雙滾動條的多行文本框 |
編碼規范(片斷節選)
操做數據的方法命名規則
| 前綴 | 含義 | 傳入 | 返回 |
| get | 得到單條記錄 | rowID | 單條記錄對象 |
| 唯一鍵 | |||
| search | 查詢多條記錄 | 唯一鍵 | List<記錄對象> |
| 非唯一鍵 | |||
| 多個參數, [and/or]關系組合 | |||
| select | 查詢多條記錄 | 唯一鍵,[字段名] | List 字段名所對應的[表.字段.ToString()] |
| 非唯一鍵,[字段名] | |||
| 多個參數, [and/or]關系組合,[字段名] | |||
| change | 修改單條 | 記錄對像 | 執行狀態 |
| stringResult.state 執行狀態 stringResult.value 出問題的字段 | |||
| set | 修改單條 | 唯一鍵,[字段名],[值] | 執行狀態 |
| rowID,[字段名],[值] | |||
| update | 修改多條 (事物) | List<記錄對象> | 執行狀態 |
| modify | 修改多條 (無事物) | List<記錄對象> | 無法完成修改的List<記錄對象> |
| insert | 添加單條 | 記錄對象 | 執行狀態 |
| add | 批量添加 (事物) | List<記錄對象> | 執行狀態 |
| stringResult.state 執行狀態 stringResult.value 出問題的字段 | |||
| append | 批量添加 (無事物) | List<記錄對象> | 無法完成添加的List<記錄對象> |
| remove | 刪除單條 | rowID | 執行狀態 |
| 唯一鍵 | |||
| delete | 刪除多條 (事物) | List<記錄對象> | 執行狀態 |
| clear | 刪除多條 (事物) | 多個參數, [and/or]關系組合 | 執行狀態 |
| wipe | 刪除多條 (無事物) | List<記錄對象> | 無法完成刪除的List<記錄對象> |
| execute | 執行sql | SQL 字串 ? 存儲過程 | 執行狀態 |
| stringResult.state 執行狀態 stringResult.value 問題 | |||
| stringResult.state 執行狀態 stringResult.value 返回對象的XML | |||
| binding | 添加單條(關系表) | 記錄對象 | 執行狀態 |
| unbinding | 刪除單條(關系表) | rowID | 執行狀態 |
轉載于:https://www.cnblogs.com/waw/archive/2011/08/29/2158562.html
總結
以上是生活随笔為你收集整理的艾伟也谈项目管理,我是如何带领团队开发项目的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Versant 对象型数据库
- 下一篇: Memcache应用场景