领导力大挑战
在实施Scrum项目的过程中,Scrum Master的角色是相当关键的,因为他是团队的推动者。本文围绕什么是仆人式领导、仆人式领导的起源、如何将领导力传达给团队、Scrum Master作为仆人式领导者的角色展开叙述,同时重点阐述仆人式领导者应有的基本内外特征。
该内容已经被标记书签!
标记书签错误,请重试!
作者 李剑 发布于 2009年3月12日
防御式编程是保护自己的程序不受外部侵害的一种有效方式。代码大全在“防御式编程”这一章中讲到,可以用断言(assert)来检查真实情况是否满足自己的预期,例如指针非空。
上个月Miško Hevery写了一篇文章:断言,还是不断言,描述了在构造器中编写断言给单元测试所造成的种种不便。
他先举了一个实际例子:
class House {
Door door;
Window window;
Roof roof;
Kitchen kitchen;
LivingRoom livingRoom;
BedRoom bedRoom;
House(Door door, Window window,
Roof roof, Kitchen kitchen,
LivingRoom livingRoom,
BedRoom bedRoom){
this.door = Assert.notNull(door);
this.window = Assert.notNull(window);
this.roof = Assert.notNull(roof);
this.kitchen = Assert.notNull(kitchen);
this.livingRoom = Assert.notNull(livingRoom);
this.bedRoom = Assert.notNull(bedRoom);
}
void secure() {
door.lock();
window.close();
}
}
然后说到,因为secure方法只需要door和window两个对象,所以理所当然的是,在测试这个方法的时候只需要初始化door和window,其他参数用null代替,如: 、
House house = new House(door, window,null, null, null, null);
这样的方法才能够让人看明白意图,但是因为构造器中做了参数非空的断言,所以就不得不这样初始化House对象:
House house = new House(door, window,
new Roof(),
new Kitchen(),
new LivingRoom(),
new BedRoom());
这样就让人不太能看得懂到底是哪些对象真正在测试方法中被用到了。而当构造器中的参数增多,代码的可读性就会更差。Miško最后提到:
我不是反对断言,我也在自己的代码中也常用,不过我的大多数断言只是用来检查对象的内部状态,而不是是不是传入了一个null值。检查是不是null往往会影响到代码的测试,如果要我在完好测试过的代码和有断言但是没测试的代码之间做选择,结果是不言而喻的。
有不少人跟帖反对Miško的观点,他们认为这根本不是断言的问题,而是来自于设计本身,例如
你为啥不用mock框架而非要自己初始化那么一堆东西呢?在.NET世界里面有个新词,叫做automocker——你可以把它看作是mock框架和ioc容器的混合体……
看看这个链接吧:http://blog.eleutian.com/CommentView,guid,762249da-e25a-4503-8f20-c6d59b1a69bc.aspx
Howie则说:
不管是我写的代码,还是我看到的代码,都是在调用对象的时候去做断言,而不是在保存对象的时候。这样合理不?所以你应该在 secure()方法里面写Assert.notNull(door);Assert.notNull(window)。用到的时候再去检查,而不是提前 就把一切都检查好,以备过几天以后需要用。
zdsbs提出用Builder来取代构造器:
Door door = new Door();
Window window = new Window();
House house = HouseBuilder.new().with(door).with(window);
house.secure();
assertTrue(door.isLocked());
assertTrue(window.isClosed());
这样问题就很好的解决了,其他变量都可以在HouseBuilder里面提供一些缺省值,你也不会创建出具有非法状态的对象来。
earlNameless对Miško的设计思路直接抨击说:
我不同意你的看法,因为你这个例子里面,人们得先知道你所测试的方法只用到了door和window,没用其他任何东西。
所以你的测试人员就得了解方法的具体实现,而这是不应该的……我如果有个可以滑开的房顶,我就得还给它上锁,可现在房顶是null。
后面有几个人同意earlNameLess的看法:测试代码需要清楚的了解实现代码的内部实现方式实在不是什么好做法。建议根据具体情况提取出接口,或者用一下Ioc容器。
不过也有些人对earlNameless的看法表示反对,例如 Adam Tybor说到:
为了写测试,不就是得知道实现方式么。这是TDD,不是TAD,不是么?如果房顶还需要加锁,那就让测试失败,然后改实现,直到所有测试变绿。
上面有很多讨论都是针对Misko的测试代码不得不知道实现细节这个做法的。虽然,测试代码了解内部细节是有点不太稳定,但这是单元测试,单元测试是白盒 测试,不是黑盒。如果你用mock,那你肯定得知道内部细节……再说的清楚一点,你是在测试基于给定的条件,你的代码能够得到预期的结果。你必须得知道这 些条件是啥,把那些不满足的条件排除掉。
如果有人来改了实现细节,那测试就会失败。不过这也暴露出一个问题来,你必须得有一整套单元测试可以做回顾。如果我改了行为,我也就修改了测试的意图。然后我就得修改测试,让它对新的假设起作用。
所以这要看你是想测试行为还是输入输出,这已经是设计测试的哲学范畴了……
跑题跑了一阵子以后,rnaufal回到原来话题上,直接抛出了JDK文档:
JDK文档中有一篇的标题是“用断言编程”,链接在这里:“http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html#usage”
里面写着:不要在public方法中用断言做变量检查。
读者朋友,你在自己的代码中使用防御式编程么?用过assert来检查null与否么?你的单元测试是在检查行为,还是检查输入输出呢?欢迎分享你们的意见。
李剑 李剑──ThoughtWorks高级咨询师,在持续集成、重构等领域具有丰富的经验;多次为国内大型企业敏捷组织转型提供咨询和培训服务。
在实施Scrum项目的过程中,Scrum Master的角色是相当关键的,因为他是团队的推动者。本文围绕什么是仆人式领导、仆人式领导的起源、如何将领导力传达给团队、Scrum Master作为仆人式领导者的角色展开叙述,同时重点阐述仆人式领导者应有的基本内外特征。
论道WP第三篇专栏,以应用程序栏的使用为中心,包括了软键盘带来的问题、应用程序栏介绍、如何绑定应用程序栏的属性等几个方面的具体话题,为开发者顺利使用应用程序栏开发提供了具体指导。
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本文详细介绍了Java SE1.6中对于锁的性能优化,以及锁的存储结构及升级过程。
本次分享将首先介绍现代富文本编辑器的组成和实现,然后结合UEditor的开发过程,与参会者分享UEditor在设计和实现的过程中,所涉及到的核心功能的细节实现。
本次演讲视频录制于百度技术沙龙。
我们所开发的应用程序大多都需要提供一个图形用户界面(GUI)。关于GUI应用的架构设计,已经有了Form & Control、MVC,、MVP、 Passive View等多种模式。模式可以帮助我们建立优雅的架构,但前提是弄清楚模式的应用场景。弄清楚GUI应用面临的设计上的问题,有助于我们正确的挑选设计方案。
MongoDB是一种非常易用的NoSQL方案,Brian C. Dilley在这篇文章里介绍了MongoDB的优劣势,并介绍了MJORM项目。MJORM用于MongoDB,是一个没有注解的Java ORM库。
随着网络基础设施的逐步成熟,从RPC进化到Web Service,并在业界开始普遍推行SOA,再到后来的RESTful平台以及云计算中的PaaS与SaaS概念的推广,分布式架构在企业应用中开始呈现出不同的风貌,然而殊途同归,这些分布式架构的目标仍然是希望回到建造巴别塔的时代,系统之间的交流不再为不同语言与平台的隔阂而产生障碍。
5 条回复
关注此讨论 回复