Archive for the '技术(Tech)' Category

苦闷的项目经理

项目启动会议开始, 项目经理拿出自己的项目计划信心满满的想要告诉大家接下来的项目实施应该如何展开. 可是刚刚开始就被需求分析师和产品经理质疑:
模块划分不合理,应该按照业务场景制定发布计划.
这意味着项目经理原本按照功能和系统模块制定的计划被90%的推翻.
为什么会有这样的问题?
项目经理的技术出身导致其对项目的scope估计无可避免的过早考虑到设计(甚至是代码重用)
而产品经理和需求方更多关注的是产品提供的feature,或者说一个"完整的"功能点.在scrum里我们称为"用户故事".
而项目经理的项目计划又有两份,一份是给"上面"看的,也就是用户,产品经理,需求方;而另一份是给"下面"看的,也就是系统设计/开发人员.而这里显然是第一份.因为关注点不同.
这也是项目驱动(project-oriented)和产品驱动(product-oriented)的交付方式和内容的不同.
项目驱动更多的是在整个项目结束后交付完整的代码和所有的功能.因为项目(开发)的周期相对较短.
而产品驱动则是要在不同的阶段都要交付feature和功能(当然你觉得每个阶段都可以用项目驱动来做也没什么不妥),同时还要兼顾整体的系统设计和重用性/维护性等问题.因为产品(开发)的周期通常较长,夜长也就梦多了,开发周期可能同时伴随的维护任务和设计重构.在产品驱动模式中,项目经理需要更好的平衡能力和全局掌控能力.

项目启动会议开始, 项目经理拿出自己的项目计划信心满满的想要告诉大家接下来的项目实施应该如何展开. 可是刚刚开始就被需求分析师和产品经理质疑:

模块划分不合理,应该按照业务场景制定发布计划.

这意味着项目经理原本按照功能和系统模块制定的计划被90%的推翻.

为什么会有这样的问题?

项目经理的技术出身导致其对项目的scope估计无可避免的过早考虑到设计(甚至是代码重用)

而产品经理和需求方更多关注的是产品提供的feature,或者说一个"完整的"功能点.在scrum里我们称为"用户故事".

而项目经理的项目计划又有两份,一份是给"上面"看的,也就是用户,产品经理,需求方;而另一份是给"下面"看的,也就是系统设计/开发人员.而这里显然是第一份.因为关注点不同.

这也是项目驱动(project-oriented)和产品驱动(product-oriented)的交付方式和内容的不同.

项目驱动更多的是在整个项目结束后交付完整的代码和所有的功能.因为项目(开发)的周期相对较短.

而产品驱动则是要在不同的阶段都要交付feature和功能(当然你觉得每个阶段都可以用项目驱动来做也没什么不妥),同时还要兼顾整体的系统设计和重用性/维护性等问题.因为产品(开发)的周期通常较长,夜长也就梦多了,开发周期可能同时伴随的维护任务和设计重构.在产品驱动模式中,项目经理需要更好的平衡能力和全局掌控能力.

团队持续集成手记

早就想试试持续集成.终于有机会了.
刚开始用cruise-control但是免费版有使用限制,而且界面似乎也不是很友好.没用的信息比较多.所以在忍受了1周以后废弃,改用hudson.
hudson比想象中的简单.安装和配置过程不说了.没什么难的东西,多尝试几次即可.
我们的项目用到的是ivy和ant,据说如果项目使用了maven的话就更简单了."因为hudson和maven的搭配几乎可以用天衣无缝来形容".
在使用了hudson将我们的所有模块导入后,整个构建越来越稳定了.而且build fail总是可以在第一时间捕捉并消灭掉.团队初尝ci的好处.
之后我们在构建过程中加入了自动化单元测试和覆盖率工具,当我们发现项目中broken的测试时,团队成员居然自发的去修复他们.在引入单元测试和覆盖率工具3天后,所有单元测试都pass,测试通过率100%.但团队对覆盖率这个东东还不是很了解.似乎也没有多少动力去提高他.此时,覆盖率只有40%左右.
之后我们又引入了findbugs和PMD,发现代码中存在的大量坏味道.此时ci-game插件起了作用.因为每改一个相应的"bug"都会有相应的分数.整个团队掀起了"打怪"狂潮.甚至加班打怪的情况.1周后,我们消灭了90%的不良代码.期间虽然会出现一些改错的地方.但基本上通过持续的代码review(因为所有团队成员都在不停的review代码),即便少有的几次改错的地方也是在第一时间发现并纠正了.
此时,似乎没有什么"怪"可以打了,但ci-game的竞争仍然激烈.此时团队发起了覆盖率提升行动,通过将不同的模块划拨给不同的小组,然后设置一个预期的目标(比如让aaa模块的测试行覆盖率从50%提升到70%.并且每提升1%都可以有5分.ci-game再一次大显神威.覆盖率行动成功并按照计划达到目标.
其实所有这些自动化的事情都可以在每ci工具的情况做到,也可以有类似ci-game这样的机制来提高团队对提高代码质量的积极性.但hudson提供的对代码的"透明",让所有人都可以随时看到代码有哪些问题,改进的如何,更重要的是意识到自己写的代码是会被别人看到的!
hudson,很和谐!

早就想试试持续集成.终于有机会了.

刚开始用cruise-control但是免费版有使用限制,而且界面似乎也不是很友好.没用的信息比较多.所以在忍受了1周以后废弃,改用hudson.

hudson比想象中的简单.安装和配置过程不说了.没什么难的东西,多尝试几次即可.

我们的项目用到的是ivy和ant,据说如果项目使用了maven的话就更简单了."因为hudson和maven的搭配几乎可以用天衣无缝来形容".

在使用了hudson将我们的所有模块导入后,整个构建越来越稳定了.而且build fail总是可以在第一时间捕捉并消灭掉.团队初尝ci的好处.

之后我们在构建过程中加入了自动化单元测试和覆盖率工具,当我们发现项目中broken的测试时,团队成员居然自发的去修复他们.在引入单元测试和覆盖率工具3天后,所有单元测试都pass,测试通过率100%.但团队对覆盖率这个东东还不是很了解.似乎也没有多少动力去提高他.此时,覆盖率只有40%左右.

之后我们又引入了findbugs和PMD,发现代码中存在的大量坏味道.此时ci-game插件起了作用.因为每改一个相应的"bug"都会有相应的分数.整个团队掀起了"打怪"狂潮.甚至加班打怪的情况.1周后,我们消灭了90%的不良代码.期间虽然会出现一些改错的地方.但基本上通过持续的代码review(因为所有团队成员都在不停的review代码),即便少有的几次改错的地方也是在第一时间发现并纠正了.

此时,似乎没有什么"怪"可以打了,但ci-game的竞争仍然激烈.此时团队发起了覆盖率提升行动,通过将不同的模块划拨给不同的小组,然后设置一个预期的目标(比如让aaa模块的测试行覆盖率从50%提升到70%.并且每提升1%都可以有5分.ci-game再一次大显神威.覆盖率行动成功并按照计划达到目标.

其实所有这些自动化的事情都可以在每ci工具的情况做到,也可以有类似ci-game这样的机制来提高团队对提高代码质量的积极性.但hudson提供的对代码的"透明",让所有人都可以随时看到代码有哪些问题,改进的如何,更重要的是意识到自己写的代码是会被别人看到的!

当基础模块部分基本稳定后,我们将应用模块也做到自动化构建和发布到开发集成环境.每小时进行一次发布.确保了我们集成开发环境始终都有最新的版本. 后续我们准备将自动化smoke test也做一些,也许不需要很彻底,只需要基本的接口可用即可.

hudson,不,持续集成,很和谐!

[笔记]敏捷估计与规划

敏捷估计与规划笔记

敏捷宣言推崇:
1.个人与交互重于开发过程和工具
--敏捷开发小组认为: 一个由使用普通工具的优秀人员组成的/运行良好的小组,总是会比由使用优秀工具和过程的普通人组成的,紊乱的小组做的更好.
--我们花了太多的时间试图定义一个开发过程,以便把人当作机器上可被替换的齿轮,却没有取得成功
2.可用的软件重于复杂的文档
--每次迭代结束时获得一个稳定的,逐渐增强的版本,比便更频繁的收集对产品和开发过程的反馈
--将反馈回馈到开发过程,以保证开发小组始终在处理最有价值的功能
3.寻求客户的合作重于对合同的谈判
--这是一个希望,也许不是开发小组可以控制的 --我认为
4.对变化的响应重于始终遵循固定的计划
--最终的目标!!是向项目客户和用户交付更多的价值(或者更多的必要特性,更合理的时间,更小的成本)
--而切记计划是为目标服务的 --我认为

基于活动而不是基于功能进行规划 (是不好的!)
基于活动的规划分散了我们对功能的注意力,而功能才是衡量客户价值的担忧
忽视关于用户最终需要什么的不确定性,会导致虽然然按时完成了项目,却没有包含在制定计划以后发现的那些重要功能.

敏捷开发小组的主要工作方式:
1.作为一个整体工作
2.按短迭代周期工作
3.每次迭代交付一些成果
4.关注业务优先级
5.检查与调整

如何分割用户故事
1.按照数据边界分割
按照用户故事所支持数据的边界分割大型用户故事
2.按照操作边界分割
把大型用户故事分割成独立的建立/读取/更新/删除操作
3.去除横切考虑
为用户故事建立两个版本:一个具备对横切考虑的支持,另一个不具备这种支持.
4.不用满足性能限制
5.分割具有混合优先级的用户故事
6.不要把故事分割成任务
而是寻找一个方法来让曳光弹穿过整个故事
7.避免相关变化的诱惑
在一个适当规模的功能中增加相关变化会把事情弄糟,除非这些变化具有同样的优先级
8.组合用户故事
对按照2周一次的迭代周期工作的开发小组来说,合适的做法是3~5天做完

速度驱动的迭代规划步骤
调整优先级/确定目标速度->确定迭代目标->选择用户故事->分解任务->对任务估计

承诺驱动的迭代规划
调整优先级->确定迭代目标->选择要增加的用户故事/把故事扩展成任务/对任务估计->要求小组作出承诺<->移除一个用户故事(如果无法承诺)->迭代规划完成(可以承诺)

easymock三步走

第一步:创建mock对象(createMock)
例: MyService myServiceMock = createMock(MyService.class);
第二步:记录预期行为(expect)
例:
SomeObject someobj = new SomeObject();
someobj.setBar("bar");
expect(myServiceMock.foo(isA(Some.class),anyInt())).andReturn(someobj );
第三步:回放(replay)
replay(myServiceMock);

[翻译]API设计黄金法则

API设计黄金法则

原文: http://programmer.97things.oreilly.com/wiki/index.php/The_Golden_Rule_of_API_Design
API的设计通常是一项艰巨的任务,尤其当设计的API非常庞大时. 如果你设计的API将会有成百上千的用户时,你要考虑今后应该如何扩展来避免不小心把客户端的代码搞挂. 除此之外,你还要考虑用户在使用API的过程中对你的影响.如果你的API类使用它内部的一个方法时,你要记得 - 用户可以通过子类复写(override)他,而这,可能会是灾难性的. 你将不能修改那些方法,因为用户已经这样使用它们了. 你今后的内部实现将无可避免的由你的用户来决定,而不再是你.

API程序员有各种各样的方法来解决这个问题,但最简单的还是禁止用户修改API.如果你用的是Java你可能会把所有的类都声明为final,如果用C#,则声明所有的方法为sealed.无论用什么语言,你都可以通过单例(singleton)或者静态工厂方法来避免用户复写代码,或者不当的扩展和使用你的代码.这些听起来很有道理,但,真是这样吗?

在过去的10年,我们渐渐意识到单元测试是一种非常非常重要的实践,但这一实践却并没有完全被整个行业所认可. 显而易见的是,大多数情况下,为一个未经测试的类编写测试用例时总是很难.你会发现使用了API的代码和API耦合的就像是上了强力胶一样.没有办法去模拟API类的行为,进而容易的测试API和你的代码之间的交互.

经过一段时间后也许会有改善,但只有我们在开始设计API时就考虑到测试问题.不幸的是,这可能需要你(API的设计者)多花一点时间 - 不仅测试自己的代码,还要考虑用户如何测试他们的代码. 这里就引出了伟大的"API设计黄金法则": 仅仅给API写测试用例是不够的;你还要为使用API的代码写单元测试.只有这样做了,你才会在第一时间体会用户在使用你的API时进行测试时的种种问题.

让API易于测试的方法有很多.static,final和sealed并不见得是不合理的,他们有相应的使用场景.但意识到测试问题是很重要的,最好的办法就是自己去感受.一旦你这样做了,你将更加胜任各种设计挑战.

By Michael Feathers

读书 – 软件架构师应该知道的97件事

-摘自"软件架构师应该知道的97件事"

"...但在现实世界中,最好的架构师不是要去解决难题,而是要围绕难题开展工作.架构师要能够将四处弥漫的软件问题圈起来,并画出其中的各种边界(接口),确保对问题有稳定的,完整的认识."
--Stable problems get high-quality solutions
"架构师要从整体上看待杂乱无章的数据/概念/数据处理逻辑,架构师要能够将他们作为整体看待,并将它们分解为更小的片段或"块".重点在于,这些问题必须是稳定的,它们在范围上有限且稳定,可以作为系统模块解决."
--Stable problems get high-quality solutions
--上面两点说的无外两点: 正确的确定scope, 合理的架构拆解

"从架构师角度看,困难的所在,是要找到设置边界的自然之处,并定义出构建可工作系统所需要的合适接口.大型的企业系统,其自然边界稀少及多个领域之间互有纠缠,做到这点尤为困难."
--Architects' focus is on the boundary and interfaces

"称职的架构师应该勇于接受新观念,敢于尝试新的设计思路和工具,促进项目/团队,甚至整个行业的发展;他不会浪费大把的时间参与管理层会议,或者妄想独自编写所有代码;他应该采纳好点子,营造活跃的思考氛围.只有思想开放的架构师才能平衡各种矛盾因素,顺利完成项目."
--Janus the architect

"将程序设计--或者更准确的说,软件开发, 看作发现和学习的过程,而不是生产和建造的过程."
"如果把编写代码看成设计行为,而不是生产行为,我们就能采用一些已经被证明有效的管理方式,这些方法过去用于管理具有不可预测性的创新工作,比如研发新车/新药/新的电脑游戏.我所指的是敏捷的产品管理方法和精益生产方法,比如scrum,它们关注如何为客户实现最大的投资收益"
--Programming is an act of design

"沉下心来改善系统的生产效率,缩短流程,避免各行其是,才能缩短开发时间.采取一切可行的措施,例如运用模拟方法,降低依赖性,细致划分系统模块,等等.总之要杜绝一起草率提价任务的念头"
--Commit-and-run is a crime

hessian的异常处理和异常监控机制

现在项目中用到大量hessian, 虽然做到了系统间的解耦和方便的调用.但并不确定当出现系统异常时如何在最快的时间发现并能自动重置.今天想了一些办法,记录下来可以在后续的工作中尝试. 这些方法并不一定只适用于hessian.

1. 拦截hessian调用异常,然后将异常请求放到重试mq中.由专门的mdb对这些调用异常进行重试.对于非实时的调用可以用这种方式, 调用方需要同样适用mdb对这些"异步的异常重试处理"进行处理. 这样做是不是反而增加了系统复杂性? 遇到异常通常是哪些原因: 无非是服务端挂掉(包括重启中),网路连接异常. 只要是暂时性的大不了重试呗. 保证数据正确性和完整性就可以了. 如果能在第一时间做到报警就很不错了.

2. 对所有的远程接口进行定期心跳测试,当满足某些规则时报警.这样可能是增加服务器的负载. 会不会因为这些反而影响到吞吐量?

3.有点类似第一条,将所有hessian调用都变为异步,充分利用mdb和mq.同步请求的处理是否能够满足要求? 还是在系统设计时就考虑一些这方面的东西 - 尽量不要使用客户端直接发起的同步业务操作; 业务操作接口设计为无状态的,避免操作之间的过度依赖 ...

先就想到这么多. 休息一下,准备晚上看西班牙和荷兰的决赛!

概要设计模板-来自互联网

1.引言

1.1编写目的

  [说明编写这份概要设计说明书的目的,指出预期的读者。]

1.2背景

  a.[待开发软件系统的名称;]

  b.[列出本项目的任务提出者、开发者、用户。]

1.3定义

  [列出本文件中用到的专门术语的定义和外文首字母组词的原词组。]

1.4参考资料

  [列出有关的参考资料。]

2.总体设计

2.1需求规定

  [说明对本系统的主要的输入输出项目、处理的功能性能要求。包括]

  2.1.1系统功能

  2.1.2系统性能

    2.1.2.1精度

    2.1.2.2时间特性要求

    2.1.2.4可靠性

    2.1.2.5灵活性

  2.1.3输入输出要求

  2.1.4数据管理能力要求

  2.1.5故障处理要求

  2.1.6其他专门要求

2.2运行环境

  [简要地说明对本系统的运行环境的规定。]

  2.2.1设备

  [列出运行该软件所需要的硬设备。说明其中的新型设备及其专门功能。]

  2.2.2支持软件

  [列出支持软件,包括要用到的操作系统、编译(或汇编)程序、测试支持软件

等。]

1  2.2.3接口

  [说明该系统同其他系统之间的接口、数据通信协议等]

  2.2.4控制

  [说明控制该系统的运行的方法和控制信号,并说明这些控制信号的来源。]

2.3基本设计概念和处理流程

  [说明本系统的基本设计概念和处理流程,尽量使用图表的形式。]

2.4结构

  [给出系统结构总体框图(包括软件、硬件结构框图),说明本系统的各模块的

划分,扼要说明每个系统模块的标识符和功能,分层次地给出各模块之间的控制与被

控制关系。]

2.5功能需求与系统模块的关系

  [本条用一张矩阵图说明各项功能需求的实现同各模块的分配关系。]

    [系统模块1] [系统模块2] [……] [系统模块m]

[功能需求1]  √             

[功能需求2]      √         

[┇]                

[功能需求n]      √       √ 

2.6人工处理过程

  [说明在本系统的工作过程中不得不包含的人工处理过程。]

2.7尚未解决的问题

  [说明在概要设计过程中尚未解决而设计者认为在系统完成之前必须解决的各个

问题。]

3.接口设计

3.1用户接口

  [说明将向用户提供的命令和它们的语法结构,以及相应的回答信息。]

  [说明提供给用户操作的硬件控制面板的定义。]

3.2外部接口

  [说明本系统同外界的所有接口的安排包括软件与硬件之间的接口、本系统与各

支持系统之间的接口关系。]

3.3内部接口

  [说明本系统之内的各个系统元素之间的接口的安排。]

4.运行设计

4.1运行模块组合

  [说明对系统施加不同的外界运行控制时所引起的各种不同的运行模块组合,说

明每种运行所历经的内部模块的支持软件。]

4.2运行控制

  [说明每一种外界的运行控制的方式方法和操作步骤。]

4.3运行时间

  [说明每种运行模块组合将占用各种资源的时间。]

5.系统数据结构设计

  [不涉及软件设计可不包含]

5.1逻辑结构设计要点

  [给出本系统内软件所使用的每个数据结构的名称、标识符以及它们之中每个数

据项、记录、文卷和系的标识、定义、长度及它们之间的层次的或表格的相互关系。

]

5.2物理结构设计要点

  [给出本系统内软件所使用的每个数据结构中的每个数据项的存储要求,访问方

法、存取单位、存取的物理关系、设计考虑和保密条件。]

5.3数据结构与程序的关系

  [说明各个数据结构与访问这些数据结构的各个程序之间的对应关系。]

    [程序1] [程序2] [……] [程序m]

[数据结构1]  √             

[数据结构2]      √         

[┇]                

[数据结构n]      √       √ 

6.系统出错处理设计

6.1出错信息

  [用一览表的方式说明每种可能的出错或故障情况出现时,系统输出信息的形式

、含意及处理方法。]

6.2补救措施

  [说明故障出现后可能采取的变通措施。包括:]

  a.后备技术 [说明准备采用的后备技术,当原始系统数据万一丢失时启用的副本

的建立和启动的技术,例如周期性地把磁盘信息记录到磁带上去就是对于磁盘媒体的

一种后备技术。]

  b.降效技术 [说明准备采用的后备技术,使用另一个效率稍低的系统或方法来求

得所需结果的某些部分,例如一个自动系统的降效技术可以是手工操作和数据的人工

记录。]

  c.恢复及再启动技术 [说明将使用的恢复再启动技术,使软件从故障点恢复执行

或使软件从头开始重新运行的方法。]

6.3系统维护设计

  [说明为了系统维护的方便而在程序内部设计中作出的安排,包括在程序中专门

安排用于系统的检查与维护的检测点和专用模块。]

scrum读书笔记

Scrum的运作基础是个人和团队的承诺,而非严密的规划和控制.相对于强行控制和规划,其忠诚度.自组织和员工责任感是更为有效的机制.

阅读和谈论scrum,与具体实施它是两码事.scrum必须先就位,才有机会被充分理解.
-scrum敏捷项目管理 c4

wtk3的模拟器不支持相机模拟

用来Java_ME_platform_SDK_3.0中自带的几个模拟器居然发现无法模拟相机,而这个是在wtk2.5里一个很寻常的功能.为什么同样的一个东西升级之后变得更差呢???
最郁闷的是wtk2.5的模拟器在win7中无法打开.win7提示无法兼容配色方案.郁闷!!