艾伟也谈项目管理,我是如何带领团队开发项目的
最近有不少朋友写信问我一些关于团队开发的问题,由于这段时间有些忙,没有回复.今天写一篇这方面的文章向大家介绍一下我是如何带领团队开发工作流项目的
关于团队建设,项目管理的文章网上已经有很多了,在这里我就不谈这些理论了,直接给大家展示一个我在 项目开发方,后台服务开发方式,前台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
艾伟也谈项目管理,我是如何带领团队开发项目的相关推荐
- 我是如何带领团队开发项目的
我是如何带领团队开发工作流项目的 最近有不少朋友写信问我一些关于团队开发的问题,由于这段时间有些忙,没有回复.今天写一篇这方面的文章向大家介绍一下我是如何带领团队开发工作流项目的 关于团队建设,项目管 ...
- 艾伟也谈项目管理,创建敏捷团队
简介 创建敏捷的软件开发团队并不像表面看起来那么容易.很多管理人员和团队主管会雇佣技术合格的人组成团队,扔给他们某种敏捷过程,然后就希望所有事情都像书上说的那样有效.这种方法不仅不现实,而且非常容易失 ...
- 艾伟也谈项目管理,关于项目管理的一点体会
这段时间,一直在负责一个项目的管理与开发.在时间短.任务紧,而团队人员又大部分是没有经验的菜鸟的恶劣情况下,我带领接近40人的团队,终于在客户规定的时间范围内如期交付产品.这其中,经历了需求变更.人员 ...
- 关涛:接手一个6年的平台型系统,我是如何带领团队破局前行的
原文链接:点击打开链接 摘要: 12月20日的北京云栖大会上,由云栖社区主办的开发者技术进阶峰会再度开启,在此之前,我们整理了2017杭州云栖大会开发者技术进阶专场上的精彩分享内容. 摘要:12月20 ...
- 艾伟也谈项目管理,在团队中如何推行一项新的实践
在一个老团队中,推行一项新的实践是非常不易的. 如果要求,每天10点站立会议增强团队成员之间沟通.大家会心里先衡量一下,恩,不就是每天站个十几分钟,自己说几句话,然后听别人说嘛,不难做到. 如果要求, ...
- 艾伟也谈项目管理,IT项目管理的六种错误思维
错误一:错误的需求调研阶段,导致很多项目永远无法结束! 在软件行业,在界面设计没有正式展现给客户之前,所有的工作都处于需求调研阶段.其实建筑行业已经给我们做好了先例:客户买房子之前是先要看看样板房和模 ...
- 艾伟也谈项目管理,敏捷的坏态度
虽然所有软件开发的专业人士都会对这篇文章感兴趣,但是经理.CIO以及软件架构师会对它最感兴趣.这个话题可能会引起许多争议,但我写这篇文章是为了让你了解在敏捷运动中看起来正在日益增长的问题. 你为什么在 ...
- 艾伟也谈项目管理,如何做一个合格的项目经理
项目经理这个角色说大不大,说小也不小.在大公司,项目经理这样的角色可能存在不计其数,他们很多都是寄托于项目的存在而生,项目的完成而终:但对于一些小作坊的软件公司,项目经理一职很多时候是一个长期持有的过 ...
- 艾伟也谈项目管理,说说我们项目组的考核
周六又被老板招呼去开会,烦!在会上,老板说要对我们软件部实施绩效考核,并要求我们几个项目经理在一起商量下,把具体的实施细则给敲定下来.结果我们几个经理们在公司会议室一直讨论到晚上八点多才大体弄出个实验 ...
最新文章
- linux多进程条件变量,Linux 多线程条件变量同步
- B2B专线宽带业务成为企业上云新战场——Vecloud
- kotlin内联函数let、with、run、apply、also
- oracle打补丁到11.2.0.3.4
- python接收弹幕_闲着没事,尝试一下用Python爬取B站弹幕呀~
- Tornado的同步API写法举例实现GET/POST/DELETE请求+Tornado获取post请求中的json数据(转载)
- Git使用出错:Couldn‘t reserve space for cygwin‘s heap, Win32
- 53. 最大子序和 golang (动态规划与贪心算法)
- 诺奖文章里面的动图绘制教程来了!!
- 05 ZooKeeper分布式RMI协调实战
- Shape数据上传至SDE数据库中,动态更新Mapservice的解决方案之一
- kindle看pdf乱码_kindle阅读pdf中文乱码解决
- 干货!ERP系统优化生产管理流程五大步骤
- 迷你播放器--第一阶段(1)--检索媒体音乐并添加到List播放列表
- ArrayList常见练习题解析
- Uniapp-APP后台保活插件(安卓后台保活)
- 【CodeForces 1255E1 --- Send Boxes to Alice [Easy Version]】
- H.266/VVC的编码结构和块划分
- 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了
- openDDS(一)opneDDS简介
热门文章
- Linux与时间相关的结构体及相关用法
- halcon 相似度_Halcon分类函数,shape模型
- java Map统计字符串中元素的数量
- 深入理解Solidity
- Android 网络异常
- 成功必读本:培养人脉的106个技巧
- JDK和CGLIB动态代理区别
- 解决跨域问题:No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.
- node08-express
- 【随记】SQL Server连接字符串参数说明