|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2007-09-27
过分的放大一个词、一个概念,一头扎进一个坑里,就会把人变傻。
很多时候,需要放弃那些东西,用普通常识想一想。 |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
TDD在我看来就是你没写一条代码路径之前,都用测试去踩一遍,走到即可。。。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
想起看到过的一个很极端的例子,一个外包项目,可以通过老外所有的测试用例,但在实际应用中根本跑不起来
|
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
hyysguyang 写道 我基本上在这里找到我要的东西:
我更确信:面对面的交流才是最直接最有效的沟通方式. 每个人有自己的开发方式,而实际上每个人的TDD也不一样,何必过分关注那么多细节,其实你们说的步骤我也在做。 谢谢各位,本帖希望到此为止. 非常感谢. 不是测试官的需求有问题,是你对需求的理解出了问题。(确实太钻牛角尖了) 不论是什么样的交流方式,总有一些基本的东西是大家共识的,这就是逻辑。 测试人员让你反转一相字符串,其含义一般人也能理解是对一个字符串进行反转操作,而不是直接返回一个字符串。(比如让你写一个1+1等于2的东西,不能直接返回2吧,只能用+的方式,算出2再返回。) 你面试失败,在我看来和TDD一点关系都没有,是你逻辑上和一般人不同。 |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
hyhongyong 写道 hyysguyang 写道 我基本上在这里找到我要的东西:
我更确信:面对面的交流才是最直接最有效的沟通方式. 每个人有自己的开发方式,而实际上每个人的TDD也不一样,何必过分关注那么多细节,其实你们说的步骤我也在做。 谢谢各位,本帖希望到此为止. 非常感谢. 不是测试官的需求有问题,是你对需求的理解出了问题。(确实太钻牛角尖了) 不论是什么样的交流方式,总有一些基本的东西是大家共识的,这就是逻辑。 测试人员让你反转一相字符串,其含义一般人也能理解是对一个字符串进行反转操作,而不是直接返回一个字符串。(比如让你写一个1+1等于2的东西,不能直接返回2吧,只能用+的方式,算出2再返回。) 你面试失败,在我看来和TDD一点关系都没有,是你逻辑上和一般人不同。 每个人对TDD理解都不一样,即便在同一个原则指导下,两个人做出来的最后结果也不一样. 正如,junit newsgroup上大家讨论的结果一样,没有所谓对与错,只有在这里面去寻找平衡,当然,这个平衡点并不是每个人都能找的到,都做的好. 你们关注的是理解需求(我一开始就说了,请不要考虑需求的理解上的问题),而我这里关注的是TDD的工作方式. javaeye上高人太多了,有这么多的人对TDD有这么深的造诣,的确佩服,有这么多人都在实践TDD(不过真的很想知道,到底有多少人把TDD作为自己的锐利武器,又有多少人每天都再以TDD的方式工作呢?你们每一个人都是在每写一行代码之前都会很自然的去写测试么?),再我看来,TDD的确不容易掌握,不过,就如Kent Beck 所说,你很容易迷恋上它,希望你也一样,迷恋TDD. Thanks. |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
but I've also seen quite a few examples where TDD-written
> > classes led to micro-design that forced a lot of refactoring to be > > made later as the complexity of the software grows. In particular, > > the idea to "do the simplest thing that can possibly work" can be > > dangerous, because sometimes, you just know where your code is going > > and it's safe to start doing things that might not necessarily be the > > simplest thing at the moment but that will save you time in the near > > future. "The simplest thing that can possibly work" is confusing because it is very subjective and what is simple to one person may be hard for another. I think "the simplest thing that could possibly work" is often interpreted as "the easiest thing that could possibly work" which at first glance looks similar but can be very different. Simple is not always or even often "easy". > the unnecessary logic introduces unnecessary risk > (which is particularly higher given the absence of more > comprehensive tests) Making mistakes is part of the learning process. If you never make mistakes, or aren't aware that you've made a mistake, you're not going to improve. That's why I practice programming. I mostly practice using TDD, but also practice coding without TDD. This gives me a safe environment in which to learn. Jeff 上面这些转自junit newsgroup. http://tech.groups.yahoo.com/group/junit/message/19846 这些才是在这次的讨论中,我学到的最重要的,非常感谢各位朋友的帮助。 谢谢. |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
hyysguyang 写道 那你为何不看看需求是什么,再这个问题上我的确钻牛角尖,也许这个例子非常的不好,我只是想表达的是,不要做不该做的事情,没有的需求永远不要去做,你认为应该这样的需求,客户未必会认为这样. 这个基本是合理的,没有提出来的需求没必要去猜测,在以后的迭代中发掘了需求可以再重构。 hyysguyang 写道 一开始我就已经说了,不要跟我说需要转换其他句子(如果要说问题,问题应该是出在我应该去引导客户,需求是不是反正任意一个句子,我已经说了这是另外一个问题,和TDD没有任何关系),就是在转换这个句子的情况下,我采用的TDD方式有什么问题?
hyysguyang 写道 我重构之后的代码的确多了十几行.如果要说问题就是我的幅度太大,我已经说了,这是我当时想到的当前消除重复的方式,如果其他时候有更好的凡是,我再替换也不迟,况且那也只是一个循环,是要稍微对java熟悉一点的人我想一看也都明 白了,也称不上什么复杂的代码. 问题在这里,你的那个return "..."不需要重构。在只转换一个句子的前提下,可以说已经没有重复了,所以不需要消除什么。 同样前提下,你写的一个测试已经足够了,写不出先失败后成功的测试。注意前提 tdd不只是驱动代码开发,还驱动需求开发。敏捷前提下,需求开发重点在已知需求,而发掘新需求不是必须的,当然这里有个度。 就你的例子,通常应该是像你说的,要引导客户,确认是否转换任意字符串。 如果测试太过简单,增加测试就可以引导需求开发。你的例子里只有一个测试,可以自问,需求真的就只有这一个点么 要灵活运用tdd。敏捷前提下,通过重构消除重复,也要看重复在哪里,重复了多少,也有个度。 就你的前提,一个return基本上是最简单的了,再做重构就教条了 |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-13
birdjavaeye 写道 hyysguyang 写道 那你为何不看看需求是什么,再这个问题上我的确钻牛角尖,也许这个例子非常的不好,我只是想表达的是,不要做不该做的事情,没有的需求永远不要去做,你认为应该这样的需求,客户未必会认为这样. 这个基本是合理的,没有提出来的需求没必要去猜测,在以后的迭代中发掘了需求可以再重构。 hyysguyang 写道 一开始我就已经说了,不要跟我说需要转换其他句子(如果要说问题,问题应该是出在我应该去引导客户,需求是不是反正任意一个句子,我已经说了这是另外一个问题,和TDD没有任何关系),就是在转换这个句子的情况下,我采用的TDD方式有什么问题?
hyysguyang 写道 我重构之后的代码的确多了十几行.如果要说问题就是我的幅度太大,我已经说了,这是我当时想到的当前消除重复的方式,如果其他时候有更好的凡是,我再替换也不迟,况且那也只是一个循环,是要稍微对java熟悉一点的人我想一看也都明 白了,也称不上什么复杂的代码. 问题在这里,你的那个return "..."不需要重构。在只转换一个句子的前提下,可以说已经没有重复了,所以不需要消除什么。 同样前提下,你写的一个测试已经足够了,写不出先失败后成功的测试。注意前提 tdd不只是驱动代码开发,还驱动需求开发。敏捷前提下,需求开发重点在已知需求,而发掘新需求不是必须的,当然这里有个度。 就你的例子,通常应该是像你说的,要引导客户,确认是否转换任意字符串。 如果测试太过简单,增加测试就可以引导需求开发。你的例子里只有一个测试,可以自问,需求真的就只有这一个点么 要灵活运用tdd。敏捷前提下,通过重构消除重复,也要看重复在哪里,重复了多少,也有个度。 就你的前提,一个return基本上是最简单的了,再做重构就教条了 引用 问题在这里,你的那个return "..."不需要重构。在只转换一个句子的前提下,可以说已经没有重复了,所以不需要消除什么。 同样前提下,你写的一个测试已经足够了,写不出先失败后成功的测试。注意前提 tdd不只是驱动代码开发,还驱动需求开发。敏捷前提下,需求开发重点在已知需求,而发掘新需求不是必须的,当然这里有个度。 就你的例子,通常应该是像你说的,要引导客户,确认是否转换任意字符串。 如果测试太过简单,增加测试就可以引导需求开发。你的例子里只有一个测试,可以自问,需求真的就只有这一个点么 要灵活运用tdd。敏捷前提下,通过重构消除重复,也要看重复在哪里,重复了多少,也有个度。 就你的前提,一个return基本上是最简单的了,再做重构就教条了 基本同意,而实际上,我一直感觉估计问题就是出在这儿,到底该不该重构?是否过度的关注重构了?这应该才是整个讨论里我比较关心的问题,至于需求的方面的,我认为是另外的问题(虽然需求和TDD息息相关,但在这儿我认为这个关注点和TDD的实践方式没有太大的关联). 而至于重构,在我看来,不论你是直接返回字符串常量也好,还是采用之前的那个比较复杂的循环方式转换也好,也或是其他方式,只要它让这个测试通过,那我就认为他们的功能是一样的,都实现同样的需求。可是有其他的朋友认为这两个代码千差万别,是完全不同的代码,而实现的功能也完全不一样,根本不属于重构(也就是说重构出了问题).我的确比较困惑,对于客户来说,他绝对不关心你的代码是怎么写的,对于他们来说多简单的代码和多复杂的代码都一样,当然,对于大家这样的JAVA高手当然不一样了,不过,我更愿意从客户的角度来看这个问题,因此,我认为这两种实现方式都完成同样的需求,实现同样的功能,因此我认为这应该属于重构,问题在于这次重构是向好的方向发展还是向坏的方向发展了? 正如前面我提到过的我重构的动机,在直接返回字符串常量之后,我认为在测试代码中的字符串常量和产品代码中返回的字符串常量在某种意义上是重复的,因此,为了消除这个重复代码,我才重构出那个循环,如果你认为这个不算重复,那你当然可以不用重构,到返回常量的时候你就完成工作了。也许我就是这儿出了问题. 在junit newsgroup里Lasse提到的: There is duplication between the two strings but the refactoring (putting the bits into a String array) removed the duplication at the cost of readability. And, sometimes, readability trumps duplication. 的确,当时我的确没有考虑到这点,从可读性上来说,的确不需要重构,直接返回字符串就完工了。 正如:jeff所说的: the unnecessary logic introduces unnecessary risk (which is particularly higher given the absence of more comprehensive tests) 因此,实际上问题在于你需要在代码重复和可读性上作出取舍。你是否取舍的合理,你做的判断是否正确这本身就不能一棍子打死. 因此,重要的是,需要在这几者之间作出权衡。尤其是软件开发里,很多地方都会存在类似这样的问题,需要再几个因素之间作出权衡,这也是一个优秀的开发人员所必备的,当然要作出怎样的一个权衡全由这个开发人员的经验与技术来决定的了。 此外,在多说一句,在重构出来的带循环的代码,不也可以处理一般的句子么?当然,除了像null,含有字符串这些特殊情况?你不认为这个是额外的好处么?我想很多人都在关注需求是转换任意一个句子而不是这个特定的字符串,因此他们毫无疑问这个是一大好处,退一步说,这难道不好么?在你这样的一个简单需求下我就可以提供更强大的功能? 可是在我看来,这个不是什么好处,这些额外好处不是客户想要的.而且增加复杂性,但是也不容许任何地方出现冗余代码,就如我不原重复做第二次同样的事情一样,因此我就重构出那么复杂的代码. 谢谢. |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-15
有收获!
|
|
| 返回顶楼 | |
|
最后更新时间:2007-09-27
引用 在我看来,不论你是直接返回字符串常量也好,还是采用之前的那个比较复杂的循环方式转换也好,也或是其他方式,只要它让这个测试通过,那我就认为他们的功能是一样的,都实现同样的需求。
怎么说呢?人,不仅要会看书,会听话,还得会动脑子。人得有常识,知识再多,要是连常识都没有,那就叫傻子。 就比如说吧,你说这两个代码: # code A
result = []
(1..5).each{|i| result << i*2}
# code B
result = (1..5).map{|i| i*2}
没有区别(虽然它们实际上可能还是有那么一点点速度或者空间上的区别),行,这是符合常识的。可是你硬要说这两个代码: // code C
public Object reverse(String str) {
return "technology devolopment software a is Tdd";
}
// code D
public String reverse(String str) {
String[] words=str.split(SPACE);
StringBuilder result=new StringBuilder();
for (int i = words.length-1; i >=0; i--) {
result.append(words[i]).append(SPACE);
}
return result.toString().trim();
}
没有区别……哎,就算你吹出大天来,我还是要说:你就算没有知识也该有点常识吧?也甭跟我讲什么测试啦什么重构啦之类的大道理,道理再大也大不过个合情合理。就您这样掰扯下去,人家不明白的还以为学重构学得岔了气呢。 |
|
| 返回顶楼 | |











