《快速软件开发》学习笔记 – Part 1.2 避免典型错误

  本书一个观点:项目成功往往不是因为你做了多少正确的事,而是因为你避免很多错误的事 下面就是作者眼中的典型错误,我们可以看看哪些对我们有帮助: 与人员相关的典型错误:   1.挫伤积极性   2.人员素质低,无法胜任   3.对有问题的人员没有采取措施,任由他破坏项目   4.英雄主义。导致风险,削弱多个角色的合作   5.项目后期加入人员 (why not?)   6.办公环境拥挤杂乱(这也不行?)   7.开发人员与客户之间发生摩擦(缺少沟通)   8.不现实的预期:三个月就要完成怀孕生子   9.缺乏管理层支持 10.缺乏各种角色的齐心协力 11.缺乏用户早期介入 12.一味搞管理、搞政治,忽略了实际的产出 13.自欺欺人地作出假设:“我敢肯定客户不需要这个功能” 与过程相关的典型错误: 1.过于乐观的计划. Mission Impossible. 2.缺乏足够的风险管理,没有主动预防典型错误 3.对承包方不加认真管理 4.缺乏计划 5.放弃计划 6.“项目前期工作”没有做好时间管理 7.不切实际地跳过需求、设计等前期工作 8.设计低劣,过多workarounds 9.缺少QA 10.缺少管理控制,项目追踪 11.太早或过于频繁的集成,导致浪费时间 12.估算时漏掉必要的任务:“这个东西很快就可以做好,可以不计入” 13.功能变化时不是去修订计划,而只是追赶计划 14.直接进行编码 与产品有关的典型错误 1.开发不需要或者不重要的功能 2.失控的需求变更 3.开发人员想玩新酷技术 4.在进度改变的同时加入新的功能(为什么说这错了?) 5.不是在做软件开发,而是在做软件研究(不确定性太多) 与技术有关的典型错误 1.盲目采用别人宣传的"银弹" 2.过高估计新技术、新方法带来的节省量 3.项目中间换用新工具,忽略了高昂的学习成本 …

《快速软件开发》学习笔记 – Part 1.2 避免典型错误 Read More »

《快速软件开发》学习笔记 – Part 1.1 概述

实现快速开发的 四大基本策略(“and”关系):   1.避免典型错误 (必须)   2.找好开发基础 (必须)   3.管理风险,以避免灾难的发生 (必须)   4.采用面向进度管理的实践 (有用但不是必须) 影响软件项目成功的四个维度:   1.人员。如组织架构,开发人员水平,激励等   2.过程   3.产品。如产品规模   4.技术 四个维度必须都要给力,不能偏废 书上提出了一个概念叫做“有效开发”,这种风格强调成本、进度与功能的平衡;当然,它并不是唯一的路,如果你觉得进度最重要,那可以更多地采取面向进度的实践 本书不提倡的快速开发方式:code-like-hell,不做细致规划+拼命加班。它的缺点有:   1.加班未必就能及时交付   2.长期激励问题。老让人加班意味着不停给甜头,否则人家走人   3.不可重复。这个项目加班加多了,下个项目可能就会怠工   4.无组织无计划造成开发组织与其它组织沟通混乱,冲突增多 本书提倡的策略是:   1.周密地计划   2.有效利用时间。用心工作而不是辛苦工作。   3.采用基于进度的实践  

你依赖了它,可能也就依赖了它的邻居

如果你的应用App依赖了远程接口API_Real,那API_Real所处的系统里的其他接口如API_Neighbor其实也和你的应用产生了间接耦合:发布时的依赖。 比如说,API_Neighbor重新发布时,它所处的整个系统都要重新发布,也就是说API_Real在发布期间可能暂时无法服务,这就会影响你的App的运行。 一个影响更严重的例子是: 你更新了API_Real,别人更新了API_Neighbor,大家说好一起发布。结果发布时API_Neighbor出了问题,要紧急查错和修改,这个过程可能会持续一两天。那对API_Real来说,要么等着API_Neighbor修好一起上;要么在构建库里把API_Neighbor去掉,重新打包,只发布API_Real(这一般比较麻烦,而且会有点风险) 另一种对邻居的依赖是在二进制依赖时发生的。虽然你宣称只依赖了Jar包里的XXXService, 但你的同事可能会直接去调这个Jar包里的XXXDAO,以后XXXDAO的改动都可能影响到你的应用。

ibatis的statement的命名空间问题

只要保证一个sql-map文件里面不重复就可以了: 原文是: 3.2.4.1. id The required id attribute provides a name for this statement, which must be unique within this <SqlMap>.

复习ibatis

Ibatis 相比于 spring jdbc template的好处: 1.把 column value <=> JavaBean这种映射放到XML里来做会比在java代码里来做方便(作者很谦虚地说这只是他个人的体会) 2.SQL里的parameter可以用#age#, #name#来表示,而不是问号; 这可以增强sql的可读性 3.可以方便地将ResultSet一步映射为组合对象(如类A里面关联了类B的实例作为属性),免于用java进行手工组装。这意味着你的数据层bean可以写成domain风格,而不是table model风格 4.可以把动态SQL的拼写放在XML里,维持一个相对整洁的外观。这个在多条件搜索时大有用武之地。 5.可以在XML里重用SQL片断,比在JAVA里重用要直观一些 ========================================== 一些边角的东西: 1.“null value replacement”可以让你设置:在参数值为空时,用某个值来填充 2. 尽量用resultMap,而不是resultClass. 看这里 3. 支持复合主键 4. 动态SQL拼写除了支持<isNull>和<isNotNull>,还支持<isPropertyAvailable>(对付多态对象有效),<isEmpty>(对付未trimToNull的字符串有效)和它们的反义词

隔离,分层,专注

把核心服务隔离出来,做成独立的层次;并使它内聚于自身,而不必受到非核心的东西的干扰。它向外界提供简明的视图,并只按自己的特性和目标变化,不必屈从于其它东西的需要。 其他的东西,不再跟核心服务混杂在一起;它们只能通过依赖、组合核心服务,实现自己的目标。 代价是: 处处需要适配

Service层的单元测试:在测试方法单元性和所需Mock的次数上取得平衡

都说单元测试应该喵准单个方法,每个测试方法只测一小部分逻辑。 但另一方面,如果测试时总是要Mock,你就要想办法少Mock一些东西,因为Mock代码写起来是很累、很难看的 Service层的代码往往就是这种情况。看个例子: 你会怎么测下面这样的代码: //仔细看下,这是一棵4层的判定树 public class Service { //为了层次清晰,没有使用驼峰式命名 public boolean do_biz() { if (!is_biz_one_valid()) { return false; } return is_biz_two_valid(); } boolean is_biz_two_valid() { if (!is_two_a_valid()) { return false; } return is_two_b_valid(); } boolean is_two_b_valid() { if (!is_two_b_left_valid()) { return false; } return is_two_b_right_valid(); } … 本着每个测试方法只测一小块逻辑的原则,你可能会这样写: @Test public void test_do_biz() { Service …

Service层的单元测试:在测试方法单元性和所需Mock的次数上取得平衡 Read More »

Service层的单元测试:与其Mock别人,不如Mock自己

此为抛砖贴,希望能引出更好的见解。 你会怎么单元测试这样一个service层的类? public class Service { private BizOne bizOne; private BizTwo bizTwo; public boolean doBiz(Object param) { Object resultOne = bizOne.getIt(param); if (resultOne == null) { return false; } return bizTwo.getIt(param) == null; } … } 不管怎么测,对bizOne和bizTwo的调用都得mock掉,否则你的测试类可能会直接访问数据库或者依赖容器。所以你可能会这样写测试代码: // do mocking BizOne bizOne = expectBizOneNotReturnNull(param); BizTwo bizTwo = expectBizTwoReturnNull(param); // inject mocked objects service.setBizOne(bizOne); service.setBizTwo(bizTwo); assertTrue(service.doBiz(param)); …

Service层的单元测试:与其Mock别人,不如Mock自己 Read More »

Spring的集成测试测什么?

spring reference的原文:     *The correct wiring of your Spring IoC container contexts.     * Data access using JDBC or an ORM tool. This would include such things as the correctness of SQL statements, Hibernate queries, JPA entity mappings, etc.

Ubuntu下强行杀死多个java进程中的一个

有时候你必须用kill -9强行杀死一个java进程,但由于你机上启了多个java程序,你不知道你要杀的进程号是哪个。办法是: ps a|grep java (后面还可以再接|grep xxx, xxx为你这个java_opts的一些关键字) 通过这个命令找到PID,然后再kill -9 之