[color=red][b]2010年10月13日 再次补充:这个笔记可以删了,大家请无视,包括下面的加粗黑体字。[/b][/color]
之前写的一篇东西,现在看来问题很多:[url]http://yuan.iteye.com/blog/257923[/url]
[b](其实当前这篇也是我在摸索的过程中记录自己想法的一篇笔记,现在回头再看,认为有两个错误:1,TDD应该从Entity开始;错,自顶向下的TDD也可以从Controller甚至View开始。当然,也许有自底向上的,从Entity开始的,但我不会这么做,我觉得从需求入手更自然。这句话主要是错在“应该”那两个字,应改为“可以”。2、遇到接口就mock?错,stub和mock是有区别的。mock适用于那些创建成本很高的对象,比如HttpServletRequest。 当然这些也只是我现在的想法,之所以回来补充,是因为我发现有人在看我这些笔记,我不希望有人被我误导。其实我是个菜鸟。)[/b]
其中一个我自己也想不明白的问题就是:这里的接口是怎么来的?
这个问题我思考了很久,也在JavaEye搜索过很久,一直没有发现答案。
几乎我看过的所有描述TDD的帖子、资料、书籍——包括Test-Driven Design、Agile Java——都是先写出测试代码,然后写产品实现代码,没有见到过接口,那么接口到哪里去了?实际项目中那些Service、DAO可都是有接口的呀。唉唉,不该这么想……这么想的话岂不是让以前的做法、想法先入为主了?以前的想法是不对的(其实不能说不对,只是我觉得在采用TDD的方式开发时,所有一切的产生,包括接口,都应该是自然而然的——我需要它,所以它存在。)。TDD反对预先设计,接口不该是预先写好的,不该。
我能想到的、能接受的出现接口的场景只有下面这种:
写了段Stack的测试代码,然后用数组实现了一个栈。当我准备用链表再实现一个栈的时候,我发现我将要写的测试代码和前一个完全一样,这时候重构之前的类,使这两个类都实现同一个接口,测试代码针对接口测试。
这是接口的一个作用:切换实现。
可是项目中的那些接口怎么来的?(我怎么觉得我在思考一个老问题,似乎之前思考过……)
实在想不通的情况下,我找朋友开始讨论了。
我:我是在想,那接口是怎么出来的。
朋友:先写测试。再写接口。再写实现。。
我:再写接口干嘛?
朋友:写接口。。为什么不写接口呢?面向接口实现。。。这个是面向对象基础。。。
(这时候我应该反应过来的,其实我的问题跟以前初学Java不久时遇到的一样:为什么要有接口?但我当时一心想表达自己的想法,没意识到这个问题。不过很快,我就想到了。)
我:只有一种情况下我可能会写接口。就是比如说,我实现了2种栈,一种是用数组实现的,一种是用链表实现的。然后针对它们的测试代码完全一样,这时候重构。
朋友:这个方式不一样嘛。如果一开始你就预计到你要写接口。那就先接口
我:tdd不赞成预先设计
朋友:如果你100%确认这个是需要的。。。那你干嘛去返工呢?XP也讲究设计的。
我:我知道,但接口不应该是这么出来的。。
我:像我说的那种情况我才能接受。但往往代码只有一种实现,所以接口的主要用处并不是“切换实现”。
我:而是分离关注点……
我(终于想起来了……):哦。。我知道了。
我:TDD应该从Entity开始,Entity没有接口。写Entity需要用到与Entity逻辑无关的对象的时候,但你又不想去考虑这个无关对象具体实现的时候,接口就出来了。然后mock这个接口……
然后怎么着?然后一切就自然而然了。
p.s:在记录这些东西的时候,我在翻看聊天记录,发现朋友说的一些并不是没有道理,比如说这个:“实际上你写模型也是接口。最初的时候可以叫接口。比如你写了方法。但里面没实现。也是接口嘛。”也许这两句表达得不是很好,但我很清楚的知道他要说的意思,同时我明白了为什么后来他问我:“ruby有接口么?”只是我在思考一个问题的时候,不喜欢被另一个问题打断。好在这不是面对面的讨论,我可以先不看对方的文字,只顾发言、思考,否则像我这种本来就很容易分心走神的人思路肯定中断。所以我在公司里会议上从来不喜欢发言——因为被打断得太多了——只是在会议之后写些文字。我很明白发言之前为什么最好要先举手。——这后面的不重要,p.s而已。
之前写的一篇东西,现在看来问题很多:[url]http://yuan.iteye.com/blog/257923[/url]
[b](其实当前这篇也是我在摸索的过程中记录自己想法的一篇笔记,现在回头再看,认为有两个错误:1,TDD应该从Entity开始;错,自顶向下的TDD也可以从Controller甚至View开始。当然,也许有自底向上的,从Entity开始的,但我不会这么做,我觉得从需求入手更自然。这句话主要是错在“应该”那两个字,应改为“可以”。2、遇到接口就mock?错,stub和mock是有区别的。mock适用于那些创建成本很高的对象,比如HttpServletRequest。 当然这些也只是我现在的想法,之所以回来补充,是因为我发现有人在看我这些笔记,我不希望有人被我误导。其实我是个菜鸟。)[/b]
其中一个我自己也想不明白的问题就是:这里的接口是怎么来的?
这个问题我思考了很久,也在JavaEye搜索过很久,一直没有发现答案。
几乎我看过的所有描述TDD的帖子、资料、书籍——包括Test-Driven Design、Agile Java——都是先写出测试代码,然后写产品实现代码,没有见到过接口,那么接口到哪里去了?实际项目中那些Service、DAO可都是有接口的呀。唉唉,不该这么想……这么想的话岂不是让以前的做法、想法先入为主了?以前的想法是不对的(其实不能说不对,只是我觉得在采用TDD的方式开发时,所有一切的产生,包括接口,都应该是自然而然的——我需要它,所以它存在。)。TDD反对预先设计,接口不该是预先写好的,不该。
我能想到的、能接受的出现接口的场景只有下面这种:
写了段Stack的测试代码,然后用数组实现了一个栈。当我准备用链表再实现一个栈的时候,我发现我将要写的测试代码和前一个完全一样,这时候重构之前的类,使这两个类都实现同一个接口,测试代码针对接口测试。
这是接口的一个作用:切换实现。
可是项目中的那些接口怎么来的?(我怎么觉得我在思考一个老问题,似乎之前思考过……)
实在想不通的情况下,我找朋友开始讨论了。
我:我是在想,那接口是怎么出来的。
朋友:先写测试。再写接口。再写实现。。
我:再写接口干嘛?
朋友:写接口。。为什么不写接口呢?面向接口实现。。。这个是面向对象基础。。。
(这时候我应该反应过来的,其实我的问题跟以前初学Java不久时遇到的一样:为什么要有接口?但我当时一心想表达自己的想法,没意识到这个问题。不过很快,我就想到了。)
我:只有一种情况下我可能会写接口。就是比如说,我实现了2种栈,一种是用数组实现的,一种是用链表实现的。然后针对它们的测试代码完全一样,这时候重构。
朋友:这个方式不一样嘛。如果一开始你就预计到你要写接口。那就先接口
我:tdd不赞成预先设计
朋友:如果你100%确认这个是需要的。。。那你干嘛去返工呢?XP也讲究设计的。
我:我知道,但接口不应该是这么出来的。。
我:像我说的那种情况我才能接受。但往往代码只有一种实现,所以接口的主要用处并不是“切换实现”。
我:而是分离关注点……
我(终于想起来了……):哦。。我知道了。
我:TDD应该从Entity开始,Entity没有接口。写Entity需要用到与Entity逻辑无关的对象的时候,但你又不想去考虑这个无关对象具体实现的时候,接口就出来了。然后mock这个接口……
然后怎么着?然后一切就自然而然了。
p.s:在记录这些东西的时候,我在翻看聊天记录,发现朋友说的一些并不是没有道理,比如说这个:“实际上你写模型也是接口。最初的时候可以叫接口。比如你写了方法。但里面没实现。也是接口嘛。”也许这两句表达得不是很好,但我很清楚的知道他要说的意思,同时我明白了为什么后来他问我:“ruby有接口么?”只是我在思考一个问题的时候,不喜欢被另一个问题打断。好在这不是面对面的讨论,我可以先不看对方的文字,只顾发言、思考,否则像我这种本来就很容易分心走神的人思路肯定中断。所以我在公司里会议上从来不喜欢发言——因为被打断得太多了——只是在会议之后写些文字。我很明白发言之前为什么最好要先举手。——这后面的不重要,p.s而已。