Опытные программисты рассматривают систему как историю, которую они должны рассказать, а не как программу, которую нужно написать. Они используют средства выбранного ими языка программирования для конструирования гораздо более богатого и выразительного языка, подходящего для этого повествования. Частью этого предметно-ориентированного языка является иерархия функций, которые описывают все действия, выполняемые в рамках системы. В результате искусной рекурсии эти действия формулируются на том самом предметно-ориентированном языке, который они определяют для изложения своей маленькой части истории.
Эта глава была посвящена механике качественного написания функций. Если вы будете следовать этим правилам, ваши функции будут короткими, удачно названными и хорошо организованными. Но никогда не забывайте, что ваша настоящая цель — «рассказать историю» системы, а написанные вами функции должны четко складываться в понятный и точный язык, который поможет вам в этом.
Листинг 3.7. SetupTeardownIncluder.java
>package fitnesse.html;
>import fitnesse.responders.run.SuiteResponder;
>import fitnesse.wiki.*;
>public class SetupTeardownIncluder {
> private PageData pageData;
> private boolean isSuite;
> private WikiPage testPage;
> private StringBuffer newPageContent;
> private PageCrawler pageCrawler;
> public static String render(PageData pageData) throws Exception {
> return render(pageData, false);
> }
> public static String render(PageData pageData, boolean isSuite)
> throws Exception {
> return new SetupTeardownIncluder(pageData).render(isSuite);
> }
> private SetupTeardownIncluder(PageData pageData) {
> this.pageData = pageData;
> testPage = pageData.getWikiPage();
> pageCrawler = testPage.getPageCrawler();
> newPageContent = new StringBuffer();
> }
> private String render(boolean isSuite) throws Exception {
> this.isSuite = isSuite;
> if (isTestPage())
> includeSetupAndTeardownPages();
> return pageData.getHtml();
> }
> private boolean isTestPage() throws Exception {
> return pageData.hasAttribute("Test");
> }
> private void includeSetupAndTeardownPages() throws Exception {
> includeSetupPages();
> includePageContent();
> includeTeardownPages();
> updatePageContent();
> }
> private void includeSetupPages() throws Exception {
> if (isSuite)
> includeSuiteSetupPage();
> includeSetupPage();
> }
> private void includeSuiteSetupPage() throws Exception {
> include(SuiteResponder.SUITE_SETUP_NAME, "-setup");
> }
> private void includeSetupPage() throws Exception {
> include("SetUp", "-setup");