clean code - a&bp cc
Post on 26-Jan-2017
199 Views
Preview:
TRANSCRIPT
Always leave the campgroundcleaner than you found it.
Service?
Processor?
Handler?Manager?
ClassesDriver?
1. public static String testableHtml(PageData pageData, boolean includeSuiteSetup) throws Exception {2. WikiPage wikiPage = pageData.getWikiPage();3. StringBuffer buffer = new StringBuffer();4. if (pageData.hasAttribute("Test")) {5. if (includeSuiteSetup) {6. WikiPage suiteSetup = PageCrawlerImpl.getInheritedPage(SuiteResponder.SUITE_SETUP_NAME, wikiPage);7. if (suiteSetup != null) {8. WikiPagePath pagePath = suiteSetup.getPageCrawler().getFullPath(suiteSetup);9. String pagePathName = PathParser.render(pagePath);10. buffer.append("!include -setup .").append(pagePathName).append("\n");11. }12. }13. WikiPage setup = PageCrawlerImpl.getInheritedPage("SetUp", wikiPage);14. if (setup != null) {15. WikiPagePath setupPath = wikiPage.getPageCrawler().getFullPath(setup);16. String setupPathName = PathParser.render(setupPath);17. buffer.append("!include -setup .").append(setupPathName).append("\n");18. }19. }20. buffer.append(pageData.getContent());21. if (pageData.hasAttribute("Test")) {22. WikiPage teardown = PageCrawlerImpl.getInheritedPage("TearDown", wikiPage);23. if (teardown != null) {24. WikiPagePath tearDownPath = wikiPage.getPageCrawler().getFullPath(teardown);25. String tearDownPathName = PathParser.render(tearDownPath);26. buffer.append("\n").append("!include -teardown .").append(tearDownPathName).append("\n");27. }28. if (includeSuiteSetup) {29. WikiPage suiteTeardown = PageCrawlerImpl.getInheritedPage(SuiteResponder.SUITE_TEARDOWN_NAME, wikiPage);30. if (suiteTeardown != null) {31. WikiPagePath pagePath = suiteTeardown.getPageCrawler().getFullPath(suiteTeardown);32. String pagePathName = PathParser.render(pagePath);33. buffer.append("!include -teardown .").append(pagePathName).append("\n");34. }35. }36. }37. pageData.setContent(buffer.toString());38. return pageData.getHtml();39. }
1. public static String renderPageWithSetupsAndTeardowns(PageData pageData, boolean isSuite) throws Exception {2. boolean isTestPage = pageData.hasAttribute("Test");3. if (isTestPage) {4. WikiPage testPage = pageData.getWikiPage();5. StringBuffer newPageContent = new StringBuffer();6. includeSetupPages(testPage, newPageContent, isSuite);7. newPageContent.append(pageData.getContent());8. includeTeardownPages(testPage, newPageContent, isSuite);9. pageData.setContent(newPageContent.toString());10. }11. return pageData.getHtml();12. }
1. public static String renderPageWithSetupsAndTeardowns(PageData pageData, boolean isSuite) throws Exception {2. if (isTestPage(pageData))3. includeSetupAndTeardownPages(pageData, isSuite);4. return pageData.getHtml();5. }
Small: Never more than 20 lines
Do one thing and one thing only
Only 1 or 2 levels deep
Descriptive names
Avoid 3 parameters
Have no side effects
private String readQwPinCode(String fyon, String item) throws TranslationException { try { FetchQwItemOnCar fetchQwItemOnCar = new FetchQwItemOnCar(); QwOnCarBuf qwOnCarBuf = fetchQwItemOnCar.fetchQwItemOnCar(fyon, item); if(fetchQwItemOnCar.getStatusCode() == FetchQwItemOnCarStatusCode.ATACQ$_SUCCESS && qwOnCarBuf != null) return qwOnCarBuf.getSerieNumber().trim(); else if(fetchQwItemOnCar.getStatusCode() == FetchQwItemOnCarStatusCode.ATACQ$_RNF) return "??????????????????????????????"; else throw new TranslationException("TranslateBuildingInfoItem",
String.valueOf(BuildingInfoConfigConstants.TRANSLATION_EXCEPTION)); } catch (VcomException e) { logger.error(e.getMessage(), e); throw new TranslationException("TranslateBuildingInfoItem",
String.valueOf(BuildingInfoConfigConstants.TRANSLATION_EXCEPTION_VCOM)); } catch (BufferException e) { logger.error(e.getMessage(), e); throw new TranslationException("TranslateBuildingInfoItem",
String.valueOf(BuildingInfoConfigConstants.TRANSLATION_EXCEPTION_VCOM)); }}
Avoid output arguments
Avoid output arguments
appendFooter(s);
public void appendFooter(StringBuffer report)
report.appendFooter();
“Principle of least astonishment”
Avoid output arguments
Throw unchecked exceptions
private String readQwPinCode(String fyon, String item) throws TranslationException { try { FetchQwItemOnCar fetchQwItemOnCar = new FetchQwItemOnCar(); QwOnCarBuf qwOnCarBuf = fetchQwItemOnCar.fetchQwItemOnCar(fyon, item); if(fetchQwItemOnCar.getStatusCode() == FetchQwItemOnCarStatusCode.ATACQ$_SUCCESS && qwOnCarBuf != null) return qwOnCarBuf.getSerieNumber().trim(); else if(fetchQwItemOnCar.getStatusCode() == FetchQwItemOnCarStatusCode.ATACQ$_RNF) return "??????????????????????????????"; else throw new TranslationException("TranslateBuildingInfoItem",
String.valueOf(BuildingInfoConfigConstants.TRANSLATION_EXCEPTION)); } catch (VcomException e) { logger.error(e.getMessage(), e); throw new TranslationException("TranslateBuildingInfoItem",
String.valueOf(BuildingInfoConfigConstants.TRANSLATION_EXCEPTION_VCOM)); } catch (BufferException e) { logger.error(e.getMessage(), e); throw new TranslationException("TranslateBuildingInfoItem",
String.valueOf(BuildingInfoConfigConstants.TRANSLATION_EXCEPTION_VCOM)); }}
Comments
Comments
Don’t write comments
Comments
Unless…– Javadocs in public APIs– “why” comments
public interface Vehicle {double getFuelTankCapacityInGallons();double getGallonsOfGasoline();
}
public interface Vehicle {double getPercentFuelRemaining();
}
final String outputDir =ctxt.getOptions().getScratchDir().getAbsolutePath();
Alternatives:• ctxt.getAbsolutePathOfScratchDirectoryOption();• ctx.getScratchDirectoryOption().getAbsolutePath();
Careful! Don’t cause an explosion of methods
How used?
String outFile = outputDir + "/" +
className.replace('.', '/') + ".class";
FileOutputStream fout = new FileOutputStream(outFile);
BufferedOutputStream bos = new BufferedOutputStream(fout);
How about this then?
BufferedOutputStream bos =
ctxt.createScratchFileStream(classFileName);
Error Handling
• Return codes are bad
• Unchecked exception are not!
• TDD: write your exception handling first• Nullpointers: Do not return or pass null.
Boundaries
Unit Tests
! Write clean test code !
1. Write failing unit test before production code
2. Only write enough test code to fail
3. Only write enough production code to pass the test
4. Repeat
AAA / GivenWhenThen• Arrange• Act• Assert
• Given• When• Then
or vs
F.I.R.S.T.
• Fast
• Independent
• Repeatable
• Self validation
• Timely
Classes should be small
• Avoid too many public methods (God class)
• Hint: class name should concisely describe the class
Single Responsibility Principle
Gather together the things that change for the same reasons
Separate those things that change for different reasonsThe reason we don't put SQL in JSPsThe reason we don't generate HTML in modules which compute resultsThe reason business rules shouldn't know about the database schema
Cohesion
Classes should have a small number of instance variables
Aim for high cohesion A class in which each variable is used by each method is maximally cohesive
When subset of methods depend on subset of instance variables → good sign for an extra class
Results in many small classes
top related