重构与注释讨论
引言:
最近看了《重构》《重构与模式》这2本书,书里反复强调了一个观点:“重构好的代码不要注释,如果你要加注释,就说明这部分代码需要重构”
于是在一次模块开发时,我尽量按照书里的思想去重构并且尽量不写注释,但是结果却不是我期望的。看我代码的人批评我注释没有,难以看懂......并且在会议上组长也批评了我。我那时感觉非常委屈,也没啥好辩解的,要不是看了这本书我也不会为了重构而不去写注释,但我冷静思考了一下,有以下原因:
1.我的重构可能不够好
2.我的英语水平和阅读我代码人的英语水平也许都不咋样。
3.这是在中国不是外国
4.程序员水平差距大,看我代码的人,不理解重构和模式
也许这些原因导致了这次事件,我也要反思一下,是否以后仍然要写注释,重构还是要的,注释也需要,毕竟我不想再被批评了
也请有想法的朋友也讨论一下这个话题!package junit.framework;import java.lang.reflect.*;public abstract class TestCase extends Assert implements Test {/** * the name of the test case */private String fName;/** * No-arg constructor to enable serialization. This method * is not intended to be used by mere mortals without calling setName(). */public TestCase() {fName= null;}/** * Constructs a test case with the given name. */public TestCase(String name) {fName= name;}/** * Counts the number of test cases executed by run(TestResult result). */public int countTestCases() {return 1;}/** * Creates a default TestResult object * * @see TestResult */protected TestResult createResult() { return new TestResult();}/** * A convenience method to run this test, collecting the results with a * default TestResult object. * * @see TestResult */public TestResult run() {TestResult result= createResult();run(result);return result;}/** * Runs the test case and collects the results in TestResult. */public void run(TestResult result) {result.run(this);}/** * Runs the bare test sequence. * @exception Throwable if any exception is thrown */public void runBare() throws Throwable {setUp();try {runTest();}finally {tearDown();}}/** * Override to run the test and assert its state. * @exception Throwable if any exception is thrown */protected void runTest() throws Throwable {assertNotNull(fName);Method runMethod= null;try {// use getMethod to get all public inherited// methods. getDeclaredMethods returns all// methods of this class but excludes the// inherited ones.runMethod= getClass().getMethod(fName, null);} catch (NoSuchMethodException e) {fail("Method ""+fName+"" not found");}if (!Modifier.isPublic(runMethod.getModifiers())) {fail("Method ""+fName+"" should be public");}try {runMethod.invoke(this, new Class[0]);}catch (InvocationTargetException e) {e.fillInStackTrace();throw e.getTargetException();}catch (IllegalAccessException e) {e.fillInStackTrace();throw e;}}/** * Sets up the fixture, for example, open a network connection. * This method is called before a test is executed. */protected void setUp() throws Exception {}/** * Tears down the fixture, for example, close a network connection. * This method is called after a test is executed. */protected void tearDown() throws Exception {}/** * Returns a string representation of the test case */public String toString() { return getName() + "(" + getClass().getName() + ")";}/** * Gets the name of a TestCase * @return returns a String */public String getName() {return fName;}/** * Sets the name of a TestCase * @param name The name to set */public void setName(String name) {fName= name;}}
24 楼 dimscar 2007-08-31 是的,我现在公司里的一个项目,代码太乱,注释也太少,我真是没有办法理解,业务又那么复杂,唉!! 25 楼 yearssilent 2007-08-31 最近偶也在看重构与模式,不过偶不觉得重构好的代码不要注释,如果你要加注释,就说明这部分代码需要重构,比如一个项目非常大,不加注释可能以后别人就没法维护,重构重在改进代码. 26 楼 mingj 2007-09-01 lz的问题我也有遇到
开发人员的水平参差不齐
最好的办法就是对代码keep it simple and stupid
这样也就不用写什么注释了 27 楼 gigix 2007-09-01 Godlikeme 写道拿一个最熟悉,堪称TDD,Refactor经典的junit代码看看。
这个例子举得很好
这段代码,各位认真看一看的话,几乎所有的注释都是JavaDoc,也几乎所有的方法都在5行以下
唯一一处出现在代码中的注释,其所在的方法也是唯一一个超过5行的比较长的方法
而正好是这个方法,稍加注意就能看出,它可以毫不费劲地重构出三个更小、更独立的方法,这几个方法的签名将很好地描述它们自己 28 楼 wuyulunbi134 2007-09-02 再精髓的代码也需要注释、英语水平不同每个人取的方法名在别人那里理解上也会不同。 29 楼 calmness 2007-09-03 LZ这个问题,其实应该从注释本身去理解,按照《重构》一书,可见作者对注释的理解为功能性的注释,也就是说每个注释是针对某段具有具体功能性的代码,因此,对于作者来说,当在代码中遇到他认为需要注释的代码的时候,那就代表该段代码可以作为单独的一个方法,而该方法的名称就可以替代注释来进行描述该段代码的功能,而我们很多人在写注释的时候,都是以细节为主,准确来说是业务流程中细节的注释,而非是功能的注释,这个区分清楚就不难理解该书作者的意思了。 30 楼 hyhongyong 2007-09-04 只要重构的好,方法名取得恰当,函数内部应该是不需要注释的。当然这是理想情况,在程序员水平不齐的情况下,适当加点函数内注释,有助于理解!
我们项目别说函数内注释,就是类有的都没有注释。