Thursday

Clean Code (Robert Cecil Martin) - Chapter5 Formatting- My summary

I have tried to make a short summary for chapter 5 of the Clean Code(Robert Cecil Martin) book. All codes  and some sentences that i liked too much in the summary are quoted from the book. I hope the summary will also be useful for you.

Vertical Formatting

1. Significant systems can be created with classes up to 200 lines long (maximum 500 lines).
(You can reach average values for some global projects in the book.)

2."Variable Declarations"
Local variables should appear a the top of each function.

private static void readPreferences() {
       InputStream is= null;
       try {
              is= new FileInputStream(getPreferencesFile());
              setPreferences(new Properties(getPreferences()));
              getPreferences().load(is);
       } catch (IOException e) {
              try {
              if (is != null)
                                   is.close();
              } catch (IOException e1) {
              }
       }
}

3."Instance variables"
"The common convention in Java, however, is to put them all at the top of the class."
"The important thing is for the instance variables to be declared in one well-known place. Everybody should know where to go to see the declarations."

In the below example, you see two instance variables declared in the middle of the class. It is hard to realize where the declarations are.
public class public class TestSuite implements Test {
       static public Test createTest(Class<? extends TestCase> theClass, String name) {
       ...
       }
      
       public static Constructor<? extends TestCase> getTestConstructor(Class<? extends TestCase> theClass)
       throws NoSuchMethodException {
              ...
       }
      
       public static Test warning(final String message) {
              ...
       }
      
       private static String exceptionToString(Throwable t) {
              ...
       }
      
       private String fName;
       private Vector<Test> fTests= new Vector<Test>(10);
      
       public TestSuite() {
       }
      
       public TestSuite(final Class<? extends TestCase> theClass) {
              ...
       }
      
       public TestSuite(Class<? extends TestCase> theClass, String name) {
              ...
       }
      
       ... ... ... ... ...
}

4."Dependent Functions."
"If one function calls another, they should be vertically close, and the caller should be above the callee, if at all possible.This gives the program a natural flow."
public class WikiPageResponder implements SecureResponder {
       protected WikiPage page;
       protected PageData pageData;
       protected String pageTitle;
       protected Request request;
       protected PageCrawler crawler;
      
       public Response makeResponse(FitNesseContext context, Request request)
              throws Exception {
              String pageName = getPageNameOrDefault(request, "FrontPage");
              loadPage(pageName, context);
              if (page == null)
                     return notFoundResponse(context, request);
              else
                     return makePageResponse(context);
       }
      
       private String getPageNameOrDefault(Request request, String defaultPageName)
       {
              String pageName = request.getResource();
              if (StringUtil.isBlank(pageName))
                           pageName = defaultPageName;
             
              return pageName;
       }
      
       protected void loadPage(String resource, FitNesseContext context)
                     throws Exception {
              WikiPagePath path = PathParser.parse(resource);
              crawler = context.root.getPageCrawler();
              crawler.setDeadEndStrategy(new VirtualEnabledPageCrawler());
              page = crawler.getPage(context.root, path);
              if (page != null)
                           pageData = page.getData();
       }
      
       private Response notFoundResponse(FitNesseContext context, Request request)
                     throws Exception {
              return new NotFoundResponder().makeResponse(context, request);
       }
      
       private SimpleResponse makePageResponse(FitNesseContext context)
              throws Exception {
              pageTitle = PathParser.render(crawler.getFullPath(page));
              String html = makeHtml(context);
             
              SimpleResponse response = new SimpleResponse();
              response.setMaxAge(0);
              response.setContent(html);
              return response;
       }
}

5."Conceptual Affinity."
"The stronger that affinity, the less vertical distance there should be between them."
The following functions call each other, so the closer to the vertical is better.
public class Assert {
       static public void assertTrue(String message, boolean condition) {
              if (!condition)
                     fail(message);
       }
      
       static public void assertTrue(boolean condition) {
              assertTrue(null, condition);
       }
      
       static public void assertFalse(String message, boolean condition) {
              assertTrue(message, !condition);
       }
      
       static public void assertFalse(boolean condition) {
              assertFalse(null, condition);
       }
}

Horizontal Formatting

6. A good character limit on a line is 100-120. 
"I used to follow the rule that you should never have to scroll to the right."

7."Horizontal Openness and Density"
Surround the assignment operators with white space.
Don't put spaces between the function and the parenthesis.
private void measureLine(String line) {
       lineCount++;
       int lineSize = line.length();
       totalChars += lineSize;
       lineWidthHistogram.addLine(lineSize, lineCount);
       recordWidestLine(lineSize);
}

public static double root2(int a, int b, int c) {

8. "Horizontal Alignment"
The below kind of alignment is not useful.
public class FitNesseExpediter implements ResponseSender
{
       private       Socket               socket;
       private       InputStream          input;
       private       OutputStream        output;
       private       Request              request;
       private       Response             response;
       private       FitNesseContext     context;
       protected     long                 requestParsingTimeLimit;
       private       long                 requestProgress;
       private       long                 requestParsingDeadline;
       private       boolean              hasError;
      
       public        FitNesseExpediter(Socket s,
                                      FitNesseContext context) throws Exception
       {
              this.context = context;
              socket = s;
              input = s.getInputStream();
              output = s.getOutputStream();
              requestParsingTimeLimit = 10000;


9."Breaking Indentation."
USE:
public class CommentWidget extends TextWidget {
       public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
      
       public CommentWidget(ParentWidget parent, String text) {
              super(parent, text);
       }
      
       public String render() throws Exception {
              return "";
       }
}

INSTEAD OF:

public class CommentWidget extends TextWidget
{
       public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
      
       public CommentWidget(ParentWidget parent, String text){super(parent, text);}
       public String render() throws Exception {return ""; }
}


References:
Robert C Martin - Clean Code: A Handbook of Agile Software Craftsmanship

No comments:

Post a Comment