<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Software Sunshine Blog</title>
	<atom:link href="https://software-sunshine-blog.de/feed" rel="self" type="application/rss+xml" />
	<link>https://software-sunshine-blog.de</link>
	<description>Blog für nachhaltige Softwareentwicklung</description>
	<lastBuildDate>Fri, 15 Mar 2019 02:13:33 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.3</generator>
	<item>
		<title>What Is TCR?</title>
		<link>https://software-sunshine-blog.de/eng-tcr-vs-tdd</link>
					<comments>https://software-sunshine-blog.de/eng-tcr-vs-tdd#comments</comments>
		
		<dc:creator><![CDATA[Manfred Sprenzel]]></dc:creator>
		<pubDate>Tue, 12 Mar 2019 18:45:20 +0000</pubDate>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[TCR]]></category>
		<category><![CDATA[TDD]]></category>
		<guid isPermaLink="false">https://software-sunshine-blog.de/?p=1668</guid>

					<description><![CDATA[<p>TCR was recently introduced by Kent Beck as a new programming method. The method is currently being traded as a successor to Test Driven Development (TDD). This article describes how TCR was developed and what the difference is between TCR and TDD. The advantages and disadvantages of both methods are compared and own ideas are discussed.</p>
<p>Der Beitrag <a rel="nofollow" href="https://software-sunshine-blog.de/eng-tcr-vs-tdd">What Is TCR?</a> erschien zuerst auf <a rel="nofollow" href="https://software-sunshine-blog.de">Software Sunshine Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>TCR was recently introduced by Kent Beck as a new programming technique. TCR is currently being traded as a successor to Test Driven Development (TDD). This article describes how TCR was developed and what the difference is between TCR and TDD. The advantages and disadvantages of both techniques are compared and own ideas are discussed.</p>



<h2 class="wp-block-heading">Preliminary Remarks on the English Version</h2>



<p>This blog is addressed primarily to a German-speaking audience. The blog post &#8222;Was ist TCR?“ (&#8222;What is TCR?&#8220;) was also very often clicked from countries that are not German-speaking. That&#8217;s why I make an exception and offer an English translation. Since I am a German native speaker, it is likely that the translation is not perfect. </p>



<h2 class="wp-block-heading">History of Test Driven Development</h2>



<div class="wp-block-media-text alignwide"><figure class="wp-block-media-text__media"><img fetchpriority="high" decoding="async" width="400" height="400" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F.jpeg" alt="" class="wp-image-1308" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F.jpeg 400w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F-150x150.jpeg 150w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F-300x300.jpeg 300w" sizes="(max-width: 400px) 100vw, 400px" /></figure><div class="wp-block-media-text__content">
<p class="has-large-font-size"><a href="https://en.wikipedia.org/wiki/Kent_Beck" target="_blank" rel="noreferrer noopener" aria-label="Kent Beck (opens in a new tab)">Kent Beck</a></p>



<p>is a legendary software pioneer. He is one of the authors and first signatories of the Agile Software Development Manifesto. He is the founder of Extreme Programming (XP) and a rediscoverer of Test Driven Development (TDD).</p>
</div></div>



<p>Beck once read the following in an ancient book about programming:</p>



<div class="wp-block-media-text alignwide" style="grid-template-columns:32% auto"><figure class="wp-block-media-text__media"><img decoding="async" width="320" height="240" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/A1471E35-E2D0-453C-BF6A-4DA76F3860BD.jpeg" alt="" class="wp-image-1374" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/A1471E35-E2D0-453C-BF6A-4DA76F3860BD.jpeg 320w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/A1471E35-E2D0-453C-BF6A-4DA76F3860BD-300x225.jpeg 300w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="wp-block-media-text__content">
<p>&#8222;Tape&#8220; here does not mean magnetic tapes. These are the tapes that were used to send the output to a <a href="https://en.wikipedia.org/wiki/Teleprinter" target="_blank" rel="noreferrer noopener" aria-label="teleprinter (opens in a new tab)">teleprinter</a> as a printer.</p>
</div></div>



<p>As an assert() method, the two perforated strips were probably placed on top of each other and held against the light to be checked.</p>



<p>Kent Beck wrote the first xUnit framework in Smalltalk and is considered to be the founder of the modern TDD. </p>



<h2 class="wp-block-heading">History of Test &amp;&amp; Commit || Revert</h2>



<p>Now he has discovered a whole new workflow. He calls it TCR and many believe the  technique will soon replace TDD. Again the spark came from the outside. Kent Beck had just introduced the programming technique &#8222;test &amp;&amp; commit&#8220;. Here the code is checked in immediately each time after the tests have been successfully executed. The programmer &#8222;Oddmund Strømmer&#8220; had the criticism that for reasons of symmetry in failing tests the code had to be removed again (revert), i.e. &#8211; &#8222;test &amp;&amp; commit || revert&#8220;. Beck hated this idea, but he was obsessed with trying it out. That&#8217;s how TCR came into existence.</p>



<p>So the idea of TCR is that the changes are committed as soon as a new test is green. However, if the test fails, the code is restored to its original state. On September 28, 2018 the article &#8222;<a rel="noreferrer noopener" label="test &amp;&amp; commit || revert (opens in a new tab)" href="http://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864" target="_blank" class="broken_link">test &amp;&amp; commit || revert</a>&#8220; was published. Thus introduced the new programming technique officially for the first time.</p>



<p>Of course, the idea of deleting code that has just been written is absurd. But for me it&#8217;s also absurd to check in a tiny piece of code every time. How do such ideas emerge?</p>



<p>To answer that question, you have to do a little more research. </p>



<h2 class="wp-block-heading">Birth of a New Idea</h2>



<p>During the time on Facebook, which lasted until February 2018, Beck began to think about how 100,000 developers could work simultaneously on the same system. Facebook&#8217;s processes were very complex and resulted in unpredictable delays. After leaving Facebook, he returned to Smalltalk. In a project about the syntax tree for the bytecode compiler, he realized that tree transformations were very closely related to scaling issues.</p>



<p>
<a title="AlterVista [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/)]" href="https://commons.wikimedia.org/wiki/File:Game_of_life_torus_100_100_1500.gif">
<img decoding="async" alt="Game of life torus 100 100 1500" src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Game_of_life_torus_100_100_1500.gif" style="width: 200px; margin-right: 15px; margin-bottom: 15px; border: 2px black solid;" align="left"></a><a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" target="_blank" rel="noreferrer noopener" aria-label="Conways Game of Life (opens in a new tab)">Conways Game of Life
</a> inspired him to think that information could spread in a similar way. What if every pixel was a programmer and every change to a pixel was a change to a program? How are these state changes related to the transformations of a syntax tree? 
</p>



<p>Some years ago Beck worked with Thiago Hirai on the code editor <a rel="noreferrer noopener" aria-label="Prune (opens in a new tab)" href="https://www.facebook.com/notes/kent-beck/prune-a-code-editor-that-is-not-a-text-editor/1012061842160013/" target="_blank">Prune</a>. Surprisingly, it was found that about 100 operations are sufficient to cover all common modification variants that are syntactically correct. A few transformations should therefore be sufficient to keep a program in a &#8222;correct&#8220; state. Merge conflicts, such as renaming the same variables to different names, are thus easy to recognize.</p>



<h3 class="wp-block-heading">Limbo<br></h3>



<figure class="wp-block-image"><img decoding="async" width="600" height="462" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B25343F7-621C-4670-8B60-C107DBE290E8.png" alt="Limbo - How low can you go" class="wp-image-1583" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B25343F7-621C-4670-8B60-C107DBE290E8.png 600w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/B25343F7-621C-4670-8B60-C107DBE290E8-300x231.png 300w" sizes="(max-width: 600px) 100vw, 600px" /><figcaption>How low can you go</figcaption></figure>



<p>This is how the idea of Limbo was born. Limbo is also associated in the English language with keeping something floating. Limbo is live, shared programming in which the focus of the following two principles is constantly kept in balance:</p>



<ol class="wp-block-list"><li>Everyone works on the same executable program, which is represented by a syntax tree.</li><li>No one is allowed to cause problems for others (including the users).</li><li></li></ol>



<p></p>



<p>Tiny changes to the code base spread permanently along the syntax tree, as in Conway&#8217;s Game of Life and like living organisms.</p>



<p>Many questions are still open and there is still no tool that couples directly to the syntax tree. Changes would then only be possible as tree conversions. Limbo is currently still a thought experiment &#8211; a learning exercise.</p>



<p>To get practical experience, Beck encouraged his fans to experiment with GIT and source editors. He just wanted to see what Limbo feels like and what incentives it creates. He created Limbo on the cheap tour. He describes the use of GIT in the article &#8222;Limbo on the Cheap&#8220; with the pun &#8222;(ab)using GIT</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Rather than have tree transformations zipping around modifying the program, we chose to use Git. Both pairs cloned the same remote repository. Then we ran the following shell script:<br><br>while(true);<br> do<br> git pull &#8211;rebase;<br> git push;<br> done;</p><p><br>How would we make sure we didn’t break each others’ code? We wouldn’t propagate changes unless all the tests pass. After every change, we ran this script:<br><br>test &amp;&amp; git commit -am working<br><br>The “test” script builds the system, runs the tests, and only returns 0 if all the tests pass. (We actually reverted if the tests failed, but that is a tale for a<a href="https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864" class="broken_link"> different article</a>.) </p><cite> <br>Kent Beck &#8211; Limbo on the Cheap </cite></blockquote>



<h2 class="wp-block-heading">TCR vs. TDD</h2>



<p>That brings me back to the beginning of the story. The idea of the programmer Oddmund Strømmer led to the GIT command being changed to &#8222;test &amp;&amp; commit || revert&#8220;. That&#8217;s how TCR was born. If a test is not successful, the just written code will be deleted. Thus all tests remain permanently green. By the way, Beck thinks that activating the undo function is cheating.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="800" height="400" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820.jpeg" alt="" class="wp-image-1448" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820.jpeg 800w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820-300x150.jpeg 300w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820-768x384.jpeg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><figcaption>Illustration by Kent Beck</figcaption></figure>



<p>For TDD a test is always written first and then productive code. The first test must always be a failing test. Syntax errors are also included. For example, a function that does not yet exist is already used as an assert parameter. This state is called &#8222;red&#8220;. The next step is to implement exactly enough productive code for the test to run successfully. It is therefore a change of state to &#8222;green&#8220;. If necessary, a code &#8222;refactor&#8220; for clean code follows. The rule is: &#8222;First make it work then make it right&#8220;. Such a cycle should only last a few minutes.</p>



<p>A typical beginner&#8217;s misconception with TDD is that the tests are formulated in such a way that a large amount of productive code has to be written to fulfill them. You do too many steps at once. This goes beyond the recommended time frame for a cycle. But even worse, the intermediate steps are untested. If the resulting productive code does not turn green unexpectedly during testing, you don&#8217;t know which intermediate step caused it. You have to work with the debugger again. The use of a debugger is always a symptom of not having understood the TDD technique properly.</p>



<p>Unlike TDD, TCR forces small steps. Who wants to risk the loss of a large amount of code? As an educational approach this is very welcome.</p>



<p>TDD has no instructions or recommendations for checking in code. A software developer who checks in code with syntax errors is considered as a codebreaker. A codebreaker causes problems for others in the team. This is especially the case, if the codebreaker checks in code shortly before the end of the workday, and is then no longer available. In order to be able to continue working, a solution must be found very quickly. This is often solved with a revert. At TDD you are already a codebreaker if any test becomes red. Therefore a local build run should always be executed before checking in, which recompiles all test suites and executes all tests. </p>



<p>This usually takes as long as there is time to drink a cup of coffee.</p>



<p>Typically, merging code (merging) leads to conflicts that lead to errors or cannot be resolved. The larger the amount of code and the less often the main branch is checked in, the larger and more problematic these conflicts become. With TCR, this problem can practically no longer occur. I cannot accept the excuse that it takes too long to run all the tests. Only the tests that are affected by the code changes have to be executed. Otherwise a nightly build is adequate.</p>



<h3 class="wp-block-heading">TDD Is Dead, Long Live TCR</h3>



<p>Is TCR now the new TDD? Should you learn TDD at all, or should you switch to TCR immediately? In a French blog I already read the headline &#8222;<a rel="noreferrer noopener" aria-label="TDD est mort longue vie TCR(Link) (opens in a new tab)" href="https://blog.zenika.com/2018/12/03/tdd-est-mort-longue-vie-tcr/" target="_blank">TDD est mort longue vie TCR?</a>“. (Google translation:  &#8222;<a rel="noreferrer noopener" aria-label="TDD is dead, long life TCR? (opens in a new tab)" href="https://translate.google.com/translate?hl=en&amp;sl=auto&amp;tl=en&amp;u=https%3A%2F%2Fblog.zenika.com%2F2018%2F12%2F03%2Ftdd-est-mort-longue-vie-tcr%2F" target="_blank">TDD is dead, long life TCR?</a>“ sic!).</p>



<p>No, TCR, unlike TDD, will not have any practical relevance. At least not in the currently practiced form. TCR is only an experiment for the future Limbo. The misuse of GIT causes many practical problems. GIT was never designed to check in code in tiny pieces. The commit protocols can hardly be used to document a code history.</p>



<p>Even without GIT, the TCR workflow currently performs even worse than TDD. Two benefits mentioned above are currently in contrast to serious problems. The main downside of pure TCR is that you can no longer see what mistakes you have made. </p>



<p>A Test-First method at TDD, with an initial failing test, guides the programmer like a guide beam to the target. Of course TDD is not an automatism to solve problems, as sometimes the impression is given. However, TDD is very helpful in focusing to the problem. You always have the next step to the solution in mind. TDD is directed towards the future solution. TCR, on the other hand, is always oriented towards the present.</p>



<p>Another downside of TCR compared to TDD is that it tempts you to do the tests after implementing the productive code. As long as you don&#8217;t do tests and as long as you don&#8217;t make syntax errors, everything is checked in. If you do the tests beforehand, they are the ones that destroy the code. If, on the other hand, you later write the test for buggy production code, the test is deleted instead of the bad implementation. </p>



<h3 class="wp-block-heading">False Negative</h3>



<p>This leads directly to the most serious downside of TCR. What if at the beginning of a TDD cycle, instead of the expected failing test, a green signal suddenly appears? </p>



<div class="wp-block-media-text alignwide" style="grid-template-columns:49% auto"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="256" height="307" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/466D6C50-6982-4FBD-AD17-C055DF61BF89-e1548631703624.jpeg" alt="TCR entgleist" class="wp-image-1468"/></figure><div class="wp-block-media-text__content">
<p>Then something goes terribly wrong. Red alert! The test threatens to derail. The worst mistake you can make with TDD are defective tests with false negative results.</p>



<p>To reduce this danger, we follow the advice of Kent Beck: „<em>Never write a single line of code unless you have a <strong>failing</strong> automated test.“</em> ( Highlighting by me.)</p>
</div></div>



<p>I strongly recommend: Do not use TCR for commercial software development.</p>



<h2 class="wp-block-heading">Hybrid TDD/TCR</h2>



<p>I don&#8217;t know how GIT can help you to keep the &#8222;rules of the game&#8220; and avoid the risk of false negative tests. My idea to solve these problems is a kind of hybrid TCR. A combination of TDD and TCR.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="625" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-1024x625.jpg" alt="" class="wp-image-1510" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-1024x625.jpg 1024w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-300x183.jpg 300w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-768x468.jpg 768w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-960x585.jpg 960w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR.jpg 1520w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The developers work as usual with their local repository and run TDD. Each time a TDD test turns green, this triggers a TCR background process on the shared code. Almost always these tests would have to turn green just as successfully and thus lead to a final commit. At the same time, this background process ensures that the repository on the local workstation is synchronized with the current shared code. </p>



<p>In exceptional cases, a test fails even though it was successful locally. This can only occur if a conflict has occurred in the meantime. Developers receive a signal saying: &#8222;An immediate conflict resolution is required!&#8220; </p>



<p>A positive educational effect of TCR is thus also present, because conflict prevention is the fundamental aim. The conflict frequency is the lower and the conflict solutions are the easier the smaller the TDD cycles are.</p>



<p>Such a hybrid solution cannot simply be implemented via a GIT command. However, the effort required to implement it is much less than the effort required to implement Limbo.</p>



<h2 class="wp-block-heading">The Forthcoming Limbo</h2>



<p>Limbo&#8217;s a great idea. But a lot of effort is needed to make it a reality. Since each programming language has its own syntax, a separate Limbo must be created for each supported programming language. Actually, even a specially tailored development system is required, which supports collaborative editing to create graphical user interfaces. It would be easier to create a new programming language and development environment especially for Limbo. But then you have an acceptance problem.</p>



<p>I assume Kent Beck&#8217;s Limbo will be realized one day. TCR does not have to be included. An optimal Limbo development system only offers tree transformations that are syntactically <strong>and</strong> semantically correct. Tests and productive code are thus created practically in parallel.</p>



<p>The idea of Limbo should then also consider other requirements such as code reviews. Suppose we had a tool similar to Google Docs and we used it to collaboratively write a story in natural language. Suppose there was a group of proofreaders in addition to the group of text writers. They prevent a text from containing syntactic or semantic errors and becoming visible to everyone in this tool. Is the final text really good? Actually there should be another group. Editors who, on another level, only allow the satisfactory text to pass through. This corresponds to a code review. In addition, there could be another group that decides at the next level which parts of the story are so good that you can earn money by publishing them. </p>



<p>n my opinion Limbo should implement such a pipeline for different code layers. In a metaphorical sense this would be a kind of three-dimensional Game of Life.</p>



<p>Limbo has a promising future, but it doesn&#8217;t start tomorrow.</p>



<h3 class="wp-block-heading">Update from 22 February 2019</h3>



<p>There is a very interesting contribution by Thomas Deniffel, who also showed a <a rel="noreferrer noopener" aria-label="presentation (opens in a new tab)" href="https://github.com/tom-010/tcr_presentation" target="_blank">presentation</a> about TCR on 21. February at the Munich Meetup. In the medium article &#8222;<a href="https://medium.com/@tdeniffel/all-downsides-and-open-questions-of-tcr-885bfee27146" target="_blank" rel="noreferrer noopener" label="All Downsides and Open Questions of TCR (opens in a new tab)" class="broken_link">All Downsides and Open Questions of TCR</a>&#8220; which is still open, downsides and open questions are listed which he encountered in his workshops and discussions. He does not do this because he wants to discredit TCR. On the contrary, he is committed and very open-minded towards TCR and Limbo. I also think it is very constructive to address problems openly. Some of the downsides mentioned there have already been mentioned in this blog post. But most of it is new or differently presented. IMHO: It&#8217;s worth looking for solutions. Limbo has the potential to trigger a second revolution in sustainable software development and TCR is the avantgarde.</p>



<hr class="wp-block-separator"/>



<p><strong>Original article:</strong> <a href="https://software-sunshine-blog.de/tcr-vs-tdd">Was ist TCR?</a> </p>
<p>Der Beitrag <a rel="nofollow" href="https://software-sunshine-blog.de/eng-tcr-vs-tdd">What Is TCR?</a> erschien zuerst auf <a rel="nofollow" href="https://software-sunshine-blog.de">Software Sunshine Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://software-sunshine-blog.de/eng-tcr-vs-tdd/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Was ist TCR?</title>
		<link>https://software-sunshine-blog.de/tcr-vs-tdd</link>
					<comments>https://software-sunshine-blog.de/tcr-vs-tdd#respond</comments>
		
		<dc:creator><![CDATA[Manfred Sprenzel]]></dc:creator>
		<pubDate>Sun, 27 Jan 2019 02:00:12 +0000</pubDate>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[TCR]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[falsch negativ]]></category>
		<category><![CDATA[Kent Beck]]></category>
		<category><![CDATA[Limbo]]></category>
		<category><![CDATA[Nachhaltige Softwareentwicklung]]></category>
		<guid isPermaLink="false">https://software-sunshine-blog.de/?p=1299</guid>

					<description><![CDATA[<p>TCR wurde von Kent Beck vor Kurzem als neue Programmiermethode vorgestellt. Die Methode wird derzeit als Nachfolger von Test Driven Development (TDD) gehandelt. Dieser Artikel beschreibt wie TCR entstanden ist und was der Unterschied zwischen TCR und TDD ist. Es werden die Vorteile und Nachteile der beiden Methoden gegenübergestellt und es werden eigene Ideen zur Diskussion gestellt.</p>
<p>Der Beitrag <a rel="nofollow" href="https://software-sunshine-blog.de/tcr-vs-tdd">Was ist TCR?</a> erschien zuerst auf <a rel="nofollow" href="https://software-sunshine-blog.de">Software Sunshine Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h4 class="wp-block-heading">English Translation: <a href="https://software-sunshine-blog.de/eng-tcr-vs-tdd">What Is TCR?</a></h4>



<p>TCR wurde von Kent Beck vor Kurzem als neue Programmiertechnik vorgestellt. TCR wird derzeit als Nachfolger von Test Driven Development (TDD) gehandelt. Dieser Artikel beschreibt wie TCR entstanden ist und was der Unterschied zwischen TCR und TDD ist. Es werden die Vorteile und Nachteile der beiden Arbeitstechniken gegenübergestellt und es werden eigene Ideen zur Diskussion gestellt.</p>



<h2 class="wp-block-heading">Entstehung von Test Driven Development</h2>



<div class="wp-block-media-text alignwide"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="400" height="400" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F.jpeg" alt="" class="wp-image-1308" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F.jpeg 400w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F-150x150.jpeg 150w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/0ED74C57-6584-4382-87E8-B77139DBC09F-300x300.jpeg 300w" sizes="auto, (max-width: 400px) 100vw, 400px" /></figure><div class="wp-block-media-text__content">
<p class="has-large-font-size"><a href="https://de.wikipedia.org/wiki/Kent_Beck" target="_blank" rel="noreferrer noopener" aria-label="Kent Beck (opens in a new tab)">Kent Beck</a></p>



<p>ist ein legendärer Software-Pionier. Er ist einer der Autoren und Erstunterzeichner des Manifests für agile Software-Entwicklung. Er ist Begründer von Extreme Programming (XP) und er ist Wiederentdecker von Test Driven Development (TDD).</p>
</div></div>



<p>In einem uralten Buch über Programmierung las Beck einst das Folgende:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>… you take the input tape, manually type in the output tape you expect, then program until the actual output tape matches the expected output.<br></p><cite>Unbekannte Quelle</cite></blockquote>



<div class="wp-block-media-text alignwide" style="grid-template-columns:32% auto"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="320" height="240" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/A1471E35-E2D0-453C-BF6A-4DA76F3860BD.jpeg" alt="" class="wp-image-1374" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/A1471E35-E2D0-453C-BF6A-4DA76F3860BD.jpeg 320w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/A1471E35-E2D0-453C-BF6A-4DA76F3860BD-300x225.jpeg 300w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="wp-block-media-text__content">
<p>Mit „tape” sind hier nicht etwa Magnetbänder gemeint. Es sind die <a rel="noreferrer noopener" aria-label="Lochstreifenbänder (opens in a new tab)" href="https://de.wikipedia.org/wiki/Lochstreifen" target="_blank">Lochstreifenbänder</a>, die dazu dienten die Ausgabe an einen Fernschreiber als Drucker zu leiten. </p>
</div></div>



<p>Als Assert-Methode legte man vermutlich die beiden Lochstreifen übereinander und hielt sie zur Überprüfung gegen das Licht.<br></p>



<p>Kent Beck schrieb das erste xUnit-Framework in Smalltalk und gilt damit als der Gründer des modernen TDD. </p>



<h2 class="wp-block-heading">Entstehung von test &amp;&amp; commit || revert</h2>



<p>Jetzt hat er einen ganz neuen Workflow entdeckt. Er nennt ihn TCR und viele glauben diese Technik wird TDD bald ersetzen. Wieder kam der zündende Funken von außen. Kent Beck hatte gerade die Programmiermethode „test &amp;&amp; commit&#8220; eingeführt. Hierbei wird der Code jedes Mal sofort eingecheckt nachdem die Tests erfolgreich ausgeführt worden sind. Der Programmierer „Oddmund Strømmer” hatte den Einwand, dass man aus Gründen der Symmetrie bei Failing-Tests den Code dann wieder entfernen müsse (revert), also -„test &amp;&amp; commit || revert&#8220;. Beck hasste diese Idee, trotzdem war er versessen darauf es auszuprobieren. So entstand TCR.<br></p>



<p>Die Idee von TCR ist also, sobald ein neuer Test grün ist, werden die Änderungen committed. Schlägt aber der Test fehl, wird der Code wieder in den Ausgangszustand zurückversetzt. Am 28. September 2018 erschien der Artikel „<a rel="noreferrer noopener" label="test &amp;&amp; commit || revert (opens in a new tab)" href="http://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864" target="_blank" class="broken_link">test &amp;&amp; commit || revert</a>”. &nbsp;Darin wurde die neue Programmiermethode erstmals offiziell vorgestellt.</p>



<p>Natürlich ist die Vorstellung, gerade eben geschriebenen Code wieder zu löschen absurd. Für mich ist aber ebenso absurd, bei einem winzigen Stückchen Code jedes Mal einzuchecken. Wie entstehen solche Ideen? <br></p>



<p>Um diese Frage zu beantworten, muss man etwas weiter ausholen. </p>



<h2 class="wp-block-heading">Anfänge einer neuen Idee</h2>



<p>Während der Zeit bei Facebook, die bis Februar 2018 ging, begann Beck darüber nachzudenken, wie 100.000 Entwickler gleichzeitig am selben System zusammenarbeiten könnten. Die Prozesse bei Facebook waren sehr umständlich und führten zu unvorhersehbaren Verzögerungen. Nach seinem Ausscheiden bei Facebook &nbsp;konzentrierte er sich wieder auf Smalltalk. Bei einem Projekt, bei dem es um den Syntaxbaum für den Bytecode-Compiler ging, erkannte er, dass Baumtransformationen sehr eng mit den Fragen zur Skalierung zusammenhängen.<br></p>



<p>
<a title="AlterVista [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/)]" href="https://commons.wikimedia.org/wiki/File:Game_of_life_torus_100_100_1500.gif">
<img decoding="async" alt="Game of life torus 100 100 1500" src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Game_of_life_torus_100_100_1500.gif" style="width: 200px; margin-right: 15px; margin-bottom: 15px; border: 2px black solid;" align="left"></a><a href="https://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens" target="_blank" rel="noreferrer noopener" aria-label="Conways Game of Life (opens in a new tab)">Conways Game of Life
</a> inspirierten ihn zu dem Gedanken, dass sich auf ähnliche Weise Informationen ausbreiten können. Was ist wenn jeder Pixel ein Programmierer wäre und wenn jede Änderung eines Pixels eine Änderung eines Programms wäre? Wie hängen diese Zustandsänderungen mit den Transformationen eines Syntaxbaumes zusammen? 
</p>



<p>Beck arbeitete vor einigen Jahren mit Thiago Hirai an dem <a rel="noreferrer noopener" aria-label="Code Editor Prune  (opens in a new tab)" href="https://www.facebook.com/notes/kent-beck/prune-a-code-editor-that-is-not-a-text-editor/1012061842160013/" target="_blank">Code Editor Prune</a>. Es zeigte sich überraschenderweise, dass das circa 100 Operationen ausreichen, um alle gängigen Änderungsvarianten, die syntaktisch korrekt sind, &nbsp;abzudecken. Wenige Transformationen sollten also genügen, um ein Programm in einem „korrekten” Zustand zu belassen. Merge-Konflikte wie zum Beispiel das Umbenennen derselben Variablen in verschiedenen Namen sind damit leicht zu erkennen.<br></p>



<h3 class="wp-block-heading">Limbo<br></h3>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="600" height="462" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B25343F7-621C-4670-8B60-C107DBE290E8.png" alt="Limbo - How low can you go" class="wp-image-1583" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B25343F7-621C-4670-8B60-C107DBE290E8.png 600w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/B25343F7-621C-4670-8B60-C107DBE290E8-300x231.png 300w" sizes="auto, (max-width: 600px) 100vw, 600px" /><figcaption>How low can you go</figcaption></figure>



<p>Es entstand so die Idee von Limbo. Limbo wird in der englischen Sprache auch damit assoziiert, ewas in der Schwebe zu halten. Limbo ist live, shared programming, bei dem der Schwerpunkt der beiden  folgenden Prinzipien ständig im Gleichgewicht gehalten wird:</p>



<ol class="wp-block-list"><li>Jeder arbeitet an dem selben lauffähigen Programm, welches durch einen Syntaxbaum repräsentiert wird. </li><li>Niemand darf anderen (einschließlich der Anwender) Probleme bereiten.</li></ol>



<p>Winzige Änderungen der Codebasis verbreiten sich permanent entlang des Syntaxbaumes, so wie bei Conways Game of Life und wie bei einem lebenden Organismus.<br></p>



<p>Noch sind viele Fragen offen und noch gibt es kein Tool, welches fix an den Syntaxbaum ankoppelt. Änderungen wären dann nur noch als Baumumwandlungen möglich. Limbo ist derzeit noch ein Gedankenexperiment &#8211; eine Lernübung. <br></p>



<p>Um praktische Erfahrungen zu sammeln, ermutigte Beck seine Fans mit GIT und Quelltexteditor zu experimentieren. Eigentlich wollte er nur sehen, wie Limbo sich anfühlt und welche Anreize es schafft. Er schuf Limbo auf die billige Tour. Die Verwendung von GIT beschreibt er im Artikel  „<a rel="noreferrer noopener" href="https://medium.com/@kentbeck_7670/limbo-on-the-cheap-e4cfae840330" target="_blank">Limbo on the Cheap</a>&#8220; mit dem Wortspiel „(ab)using GIT”</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Rather than have tree transformations zipping around modifying the program, we chose to use Git. Both pairs cloned the same remote repository. Then we ran the following shell script:<br><br>while(true);<br> do<br> git pull &#8211;rebase;<br> git push;<br> done;</p><p><br>How would we make sure we didn’t break each others’ code? We wouldn’t propagate changes unless all the tests pass. After every change, we ran this script:<br><br>test &amp;&amp; git commit -am working<br><br>The “test” script builds the system, runs the tests, and only returns 0 if all the tests pass. (We actually reverted if the tests failed, but that is a tale for a<a href="https://medium.com/@kentbeck_7670/test-commit-revert-870bbd756864" class="broken_link"> different article</a>.) </p><cite> <br>Kent Beck &#8211; Limbo on the Cheap </cite></blockquote>



<h2 class="wp-block-heading">TCR vs. TDD</h2>



<p>Damit bin ich wieder am Anfang der Geschichte. Die Idee des Programmierers Oddmund Strømmer führte nämlich dazu, dass das GIT Kommando abgeändert wurde zu „test &amp;&amp; commit || revert”. So entstand TCR. Ist ein Test nicht erfolgreich, so führt dies zum Löschen des gerade eben geschriebenen Codes. Somit bleiben alle Tests permanent grün. Das Betätigen der Undo-Funktion hält Beck übrigens für Schummeln. <br></p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="800" height="400" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820.jpeg" alt="" class="wp-image-1448" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820.jpeg 800w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820-300x150.jpeg 300w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/B89D815A-92ED-4E94-8CC0-425C10F7C820-768x384.jpeg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><figcaption>Grafische Darstellung von Kent Beck</figcaption></figure>



<p>Bei TDD wird immer zuerst ein Test geschrieben und dann erst produktiver Code. Der erste Test muss immer ein Failing-Test sein. Auch Syntaxfehler zählen dazu. Beispielsweise wird eine noch nicht vorhandene Funktion bereits als Assert-Parameter verwendet. Dieser Zustand heißt „red”. Als nächstes wird genau soviel Produktivcode implementiert, dass der Test erfolgreich durchläuft. Es ist also eine Zustandsänderung auf „green”. Falls nötig folgt nun ein Code „refactor“ für Clean Code. Das Motto lautet: „First make it work then make it right”. Solch ein Zyklus sollte nur wenige Minuten dauern.</p>



<p>Ein typischer Anfängerfehler bei TDD ist, dass man die Tests so formuliert, dass für ihre Erfüllung eine große Menge produktiver Code geschrieben werden muss. Man macht dabei zuviele Schritte auf einmal. Das sprengt den empfohlenen Zeitrahmen für einen Zyklus. Aber noch schlimmer ist dabei, dass die Zwischenschritte ungetestet sind. Falls so entstandener produktiver Code dann unerwartet beim Test nicht grün wird, weiß man nicht, an welchem Zwischenschritt das lag. Man muss wieder mit dem Debugger arbeiten. Das Verwenden eines Debuggers ist immer ein Symptom dafür, dass man die TDD-Technik noch nicht richtig beherrscht.<br></p>



<p>TCR zwingt im Unterschied zu TDD zu kleinen Schritten. Wer will schon den Verlust eines größeren Happen Codes riskieren. Als erzieherischer Ansatz ist dies sehr begrüßenswert. </p>



<p>TDD macht keine Vorschriften oder Empfehlungen zum Einchecken von Code. Wer als Softwareentwickler Code mit Syntaxfehlern eincheckt, der gilt als Codebreaker. Ein Codebreaker bereitet anderen im Team Probleme. Das gilt erst recht, wenn er kurz vor Feierabend eincheckt und dann nicht mehr erreichbar ist. Um überhaupt weiterarbeiten zu können, muss kurzfristig eine Löung gefunden werden. Das geschieht dann häufig über einen Revert. Bei TDD ist man auch schon ein Codebreaker, wenn irgendein Test rot wird. Daher sollte vor dem Einchecken ein lokaler Build-Lauf ausgeführt werden, der alle Test-Suites erneut compiliert und alle Tests ausführt. </p>



<p>Das dauert in der Regel solange, dass die Zeit dafür reicht, einen Kaffee zu trinken.</p>



<p>Typischerweise kommt es beim Zusammenführen von Code (Merge) zu Konflikten, die zu Fehlern führen oder nicht mehr aufgelöst werden können. Je größer die Menge Code ist und je je seltener in den Haupt-Branch eingecheckt wird, desto größer und problematischer sind diese Konflikte. Durch TCR kann dieses Problem praktisch nicht mehr entstehen. Den Einwand, es dauert zu lange, bis die Tests alle ausgeführt werden, kann ich nicht gelten lassen. Es müssen ja immer nur die Tests ausgeführt werden, die von den Codeänderungen betroffen sind. Ansonsten reicht ein Nightly Build.</p>



<h3 class="wp-block-heading">„TDD ist tot, lang lebe TCR&#8220;</h3>



<p>Ist TCR nun das neue TDD? Soll man überhaupt noch TDD lernen, oder soll man gleich auf TCR umsteigen? In einem französischen Blog las ich schon die Schlagzeile „TDD est mort longue vie TCR?“. (Google Übersetzung: „TDD ist tot, lang lebe TCR“).</p>



<p>Nein, TCR wird im Unterschied zu TDD keine praktische Relevanz erhalten. Zumindest nicht in der gegenwärtig praktizierten Form. TCR ist lediglich ein Experiment für das zukünftige Limbo. Die missbräuchliche Verwendung von GIT verursacht viele praktische Probleme. GIT war nie dafür ausgelegt, Code in winzigen Häppchen einzuchecken. Die Commit-Protokolle lassen sich so kaum noch zur Dokumentation einer Code-Historie nutzen.</p>



<p>Auch ohne GIT schneidet der TCR Workflow im Vergleich zu TDD momentan noch schlechter ab. Den beiden o.g. Vorteilen stehen derzeit noch gravierende Nachteile entgegen. Der Hauptnachteil von reinem TCR ist, dass man nicht mehr sieht, welche Fehler man gemacht hat. </p>



<p>Die Test-First-Methode bei TDD, mit einem anfänglichen Failing-Test, führt den Programmierer wie ein Leitstrahl zum Ziel. Natürlich ist TDD kein Automatismus zum Lösen von Problemen, wie manchmal der Eindruck erweckt wird. TDD ist jedoch sehr hilfreich beim Fokussieren auf das Problem. Ständig hat man den nächsten Schritt zur Lösung vor Augen. TDD ist auf die künftige Lösung gerichtet. TCR ist dagegen immer nur auf die Gegenwart bezogen.</p>



<p>Ein weiterer Nachteil von TCR im Unterschied zu TDD ist, dass es einen dazu verführt, die Tests nach der Implementierung des produktiven Codes zu machen. Solange man keine Tests macht und solange man keine Syntaxfehler macht, wird alles eingecheckt. Macht man die Tests vorher, wie es sich gehört, dann sind sie es die den Code zerstören. Macht man dagegen im nachhinein einen richtigen Test für fehlerhaften produktiven Code, dann wird der Test anstatt der fehlerhaften Implementierung gelöscht. </p>



<h3 class="wp-block-heading">Falsch negativ</h3>



<p>Das führt nun direkt zum gravierendsten Nachteil von TCR. Was ist, wenn bei Beginn von einem TDD-Zyklus, statt des erwarteten Failing-Tests, plötzlich grün signalisiert wird? </p>



<div class="wp-block-media-text alignwide" style="grid-template-columns:44% auto"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="256" height="307" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/466D6C50-6982-4FBD-AD17-C055DF61BF89-e1548631703624.jpeg" alt="TCR entgleist" class="wp-image-1468"/></figure><div class="wp-block-media-text__content">
<p>Dann läuft etwas ganz entsetzlich schief. Alarmstufe rot! Der Test droht zu entgleisen. Der schlimmste Fehler, den man bei TDD machen kann, sind fehlerhafte Tests mit falsch negativen Resultaten. </p>



<p>Um diese Gefahr zu reduzieren, befolgen wir den Ratschlag von Kent Beck: „<em>Never write a single line of code unless you have a <strong>failing</strong> automated test.“</em> (Hervorhebung von mir.)</p>
</div></div>



<p>Ich empfehle daher, bei kommerzieller Softwareentwicklung TCR vorerst nicht einzusetzen.</p>



<h2 class="wp-block-heading">Hybrides TDD/TCR</h2>



<p>Ich weiß nicht, wie man es mit GIT schaffen will, die „Spielregeln“ einzuhalten und die Gefahr von falsch negativen Tests zu vermeiden. Meine Idee zur Lösung dieser Probleme ist eine Art hybrides TCR. Eine Kombination aus TDD und TCR. </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="625" src="https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-1024x625.jpg" alt="" class="wp-image-1510" srcset="https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-1024x625.jpg 1024w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-300x183.jpg 300w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-768x468.jpg 768w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR-960x585.jpg 960w, https://software-sunshine-blog.de/wp-content/uploads/2019/01/TDD-TCR.jpg 1520w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Die Entwickler arbeiten wie gewohnt mit ihrem lokalen Repository und betreiben TDD. Jedes Mal, wenn ein TDD-Test grün wird, startet automatisch ein Hintergrundprozess, der TCR auf dem shared Code durchführt.  Fast immer müssten dann auch diese Tests ebenso erfolgreich grün werden und dadurch zu einem endgültigen Commit bewirken. Gleichzeitig sorgt dieser Hintergrundprozess dafür, dass das Repository auf dem lokalen Arbeitsplatz mit dem aktuellen shared Code synchronisiert wird. </p>



<p>In Ausnahmefällen schlägt ein Test fehl, obwohl er lokal erfolgreich war. Das kann nur bei einem zwischenzeitlich entstandenen Konflikt vorkommen. Der Entwickler bekommt signalisiert: „Es ist eine sofortige Konfliktlösung erforderlich.“ </p>



<p>Der vorteilhafte erzieherische Effekt von TCR ist damit ebenfalls vorhanden, weil grundsätzlich eine Konfliktvermeidung angestrebt wird. Die Konflikthäufigkeit ist um so geringer und die Konfliktlösungen sind umso einfacher je kleiner die TDD-Zyklen sind.</p>



<p>Eine derartige hybride Lösung lässt sich nicht einfach über ein GIT-Kommando realisieren. Der Aufwand zur Umsetzung ist aber sehr viel geringer als die Realisierung von Limbo. </p>



<h2 class="wp-block-heading">Das zukünftige Limbo</h2>



<p>Limbo ist eine großartige Idee. Zur Verwirklichung sind aber noch viele Anstrengungen erforderlich. Da jede Programmiersprache ihre eigene Syntax hat, muss auch für jede unterstützte Programmiersprache ein eigenes Limbo geschaffen werden. Eigentlich ist sogar ein speziell zugeschnittenes Entwicklungssystem erforderlich, welches das kollaborative Bearbeiten zum Erstellen von grafischen Benutzeroberflächen unterstützt. Einfacher wäre es, eine neue Programmiersprache samt Entwicklungsumgebung speziell für Limbo zu schaffen. Dann hat man aber ein Akzeptanzproblem.</p>



<p>Ich gehe davon aus, dass Kent Becks Limbo eines Tages realisiert wird. TCR muss darin nicht enthalten sein. Ein optimales Limbo-Entwicklungssystem bietet nur die Baumtransformationen an, die syntaktisch <strong>und</strong> semantisch korrekt sind. Tests und produktiver Code entstehen dadurch praktisch parallel. <br></p>



<p>Die Idee von Limbo sollte dann auch noch weitere Anforderungen wie z.B. Code-Reviews berücksichtigen. Angenommen, wir hätten ein Tool ähnlich wie Google Docs und wir würden es dazu verwenden, um kollaborativ eine Geschichte in natürlicher Sprache zu schreiben. Angenommen, es gäbe neben der Gruppe der Texterfasser auch eine Gruppe von Korrektoren. Sie verhindern, dass ein Text der syntaktische oder semantische Fehler enthält und in diesem Tool für alle sichtbar wird. Ist dann der so entstandene Text auch wirklich gut? Eigentlich müsste es dann eine weitere Gruppe geben. Lektoren, die auf einer anderen Ebene nur den zufriedenstellenden Text durchlassen. Das entspricht einem Code-Review. Darüber hinaus könnte es eine weitere Gruppe geben, die auf der nächsten Ebene entscheidet, welche Bestandteile der Story so gut sind, dass man damit auch Geld verdienen kann, wenn man sie veröffentlicht. </p>



<p>Limbo sollte meiner Meinung nach eine solche Pipeline für unterschiedliche Code-Schichten implementieren. Im metaphorischen Sinne wäre das dann eine Art dreidimensionales Game of Life.</p>



<p>Limbo hat Zukunft, aber die beginnt noch nicht morgen.</p>



<h3 class="wp-block-heading">Update vom 22.02.2019</h3>



<p>Es gibt einen sehr interessanten Beitrag von Thomas Deniffel, der am 21.02 auch eine <a rel="noreferrer noopener" aria-label="Präsentation (opens in a new tab)" href="https://github.com/tom-010/tcr_presentation" target="_blank">Präsentation</a> beim Münchner Meetup zum Thema TCR zeigte. In dem jetzt noch offenen Medium-Artikel „<a href="https://medium.com/@tdeniffel/all-downsides-and-open-questions-of-tcr-885bfee27146" class="broken_link">All Downsides and Open Questions of&nbsp;TCR</a>“  werden Nachteile und offene Fragen aufgelistet, die ihm bei seinen Workshops und Diskussionen begegnet sind. Er macht das nicht, weil er TCR schlechtreden will. Im Gegenteil er ist engagagiert und gegenüber TCR und Limbo sehr aufgeschlossen eingestellt. Ich halte es auch für sehr konstruktiv, Probleme offen anzusprechen. Manche dort genannten Nachteile sind auch bereits in diesem Blog-Post angesprochen worden. Das meiste ist aber neu oder anders dargestellt. IMHO: Es lohnt sich, nach Lösungen zu suchen. Limbo hat das Potential, eine zweite Revolution für nachhaltige Softwareentwicklung auszulösen und TCR ist hierbei die Avantgarde.</p>



<hr class="wp-block-separator"/>



<p><strong>Vorheriger Beitrag:</strong> <a href="https://software-sunshine-blog.de/nachhaltige-softwareentwicklung">Besserer Clean Code mit nachhaltiger Softwareentwicklung</a> </p>



<h2 class="wp-block-heading"></h2>
<p>Der Beitrag <a rel="nofollow" href="https://software-sunshine-blog.de/tcr-vs-tdd">Was ist TCR?</a> erschien zuerst auf <a rel="nofollow" href="https://software-sunshine-blog.de">Software Sunshine Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://software-sunshine-blog.de/tcr-vs-tdd/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Besserer Clean Code durch nachhaltige Softwareentwicklung</title>
		<link>https://software-sunshine-blog.de/nachhaltige-softwareentwicklung</link>
					<comments>https://software-sunshine-blog.de/nachhaltige-softwareentwicklung#comments</comments>
		
		<dc:creator><![CDATA[Manfred Sprenzel]]></dc:creator>
		<pubDate>Fri, 28 Dec 2018 20:00:39 +0000</pubDate>
				<category><![CDATA[Architektur]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[Nachhaltige Softwareentwicklung]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Agilität]]></category>
		<category><![CDATA[Carola Lilienthal]]></category>
		<category><![CDATA[Entwurfsmuster]]></category>
		<category><![CDATA[Fragilität]]></category>
		<category><![CDATA[Kevin Tate]]></category>
		<category><![CDATA[KISS]]></category>
		<category><![CDATA[Martin Fowler]]></category>
		<category><![CDATA[Rigidität]]></category>
		<category><![CDATA[Robert C. Martin]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[SOLID]]></category>
		<category><![CDATA[Technische Schulden]]></category>
		<category><![CDATA[Uncle Bob]]></category>
		<category><![CDATA[Up-front design]]></category>
		<category><![CDATA[Zyklenfreie Architektur]]></category>
		<guid isPermaLink="false">https://software-sunshine-blog.de/?p=14</guid>

					<description><![CDATA[<p>Der erste Beitrag in diesem Blog handelt von nachhaltiger Softwareentwicklung. Was sind die Gemeinsamkeiten zu Clean Code und was sind die Unterschiede. Warum geplanten Up-front Design besser ist als evolutionäres? </p>
<p>Der Beitrag <a rel="nofollow" href="https://software-sunshine-blog.de/nachhaltige-softwareentwicklung">Besserer Clean Code durch nachhaltige Softwareentwicklung</a> erschien zuerst auf <a rel="nofollow" href="https://software-sunshine-blog.de">Software Sunshine Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Besserer Clean Code ist mit nachhaltiger Softwareentwicklung möglich. Dieser Beitrag betont andere Aspekte als Robert C. Martin und verdeutlicht, warum geplanten Up-front Design besser ist als evolutionäres.</p>



<h2 class="wp-block-heading">Mein erster Blogbeitrag</h2>



<p>Nun ist es endlich soweit. Mein Blog ist Online. Es kann schon mal losgehen. Es geht in diesem Blog um das Thema <strong>nachhaltige Softwareentwicklung</strong>. Aber warum der Name &#8222;Software Sunshine Blog&#8220;? Das bleibt zunächst noch mein Geheimnis.</p>



<h3 class="wp-block-heading">Nachhaltige Softwareentwicklung ist nicht das gleiche wie nachhaltige Software</h3>



<p>Bei dem Begriff „Nachhaltige Software<u>entwicklung</u>“ ist die Nachhaltigkeit bei der <em>Entwicklung</em> der Software gemeint. Also nicht etwa die Nachhaltigkeit der Software selbst. Somit möchte ich mich eindeutig vom Begriff &#8222;nachhaltiger Software&#8220; (ohne das zweite Substantiv „Entwicklung&#8220;) abgrenzen. Unter diesem Begriff versteht man so eine Art „grüne&#8220; Software. Damit will man vermeiden, den Prozessor zum Heizelement zu machen. </p>



<p>Es geht also um die Nachhaltigkeit bei der Entwicklung von Software und dessen Ergebnis, dem Programm-Quellcode. Es ist der Sourcecode, der nachhaltig sein soll. Er soll auch im weiteren Entwicklungsprozess nachhaltig bleiben. Nachhaltig ist nicht etwa der Uralt-COBOL-Code, für dessen Wartung die Entwickler buchstäblich aus dem Altersheim geholt werden müssen. Das ist das genaue Gegenteil von Nachhaltigkeit, denn hier wurde die längst überfällige Modernisierung versäumt.</p>



<p>Unter Nachhaltigkeit wird allgemein verstanden, dass nicht weniger verbraucht wird wie jeweils nachwachsen kann. Ursprünglich stammt der Begriff aus der Forstwirtschaft. Im Laufe der Softwareentwicklung entsteht normalerweise eine zunehmende Komplexität. Es ist die Ressource „Einfachheit und Klarheit“ (engl. Simplicity), die durch Änderungen und Erweiterungen normalerweise &nbsp;verbraucht wird. Genau diese Simplicity soll nachhaltig erhalten bleiben.</p>



<p>Irgendwo habe ich einmal eine sehr treffende Beschreibung für Simplicity    gelesen:  <em>„Ein System ist nicht dann einfach, wenn man nichts mehr hinzufügen kann, sondern dann, wenn man nichts mehr weglassen kann</em>.<em>&#8222;</em>  (Das Original ist von Antoine de Saint-Exupéry und lautet:  <em>„Perfektion ist nicht dann erreicht, wenn es nichts mehr hinzuzufügen gibt, sondern wenn man nichts mehr weglassen kann.&#8220;</em> &#8211; , Terre des Hommes, III: L&#8217;Avion, p. 60 (1939))</p>



<h3 class="wp-block-heading">Ohne TDD ist nachhaltige Softwareentwicklung nicht möglich</h3>



<p>Man spricht von einer Anhäufung von „<a rel="noreferrer noopener" aria-label="Technical Dept (opens in a new tab)" href="https://de.wikipedia.org/wiki/Technische_Schulden" target="_blank">Technical Dept</a>“ also eine technische Verschuldung, die jede Weiterentwicklung der Software immer schwieriger macht. Die Symptome dieses Problems nennt man <a rel="noreferrer noopener" aria-label="Rigidität (opens in a new tab)" href="https://de.wikipedia.org/wiki/Rigidit%C3%A4t" target="_blank">Rigidität</a> und Fragilität. Rigidität heißt, dass Änderungen übermäßig aufwändig sind. Selbst für kleinste Änderungen werden oft utopisch hohe Aufwandsschätzungen abgegeben. Fragilität, das bedeutet, dass bei Änderungen sehr leicht Fehler entstehen. Meist in Bereichen, die mit der eigentlichen Änderung gar nichts zu tun haben und somit auch nicht getestet werden. Unter Nachhaltigkeit bei Softwareentwicklung wird somit die Bemühung verstanden, Änderungen der Software ohne technische Schulden zu machen. Die Ressource Simplicity bleibt dabei gemäß dem <a rel="noreferrer noopener" aria-label="Unter Nachhaltigkeit wird allgemein verstanden, dass nicht weniger verbraucht wird wie jeweils nachwachsen kann. Ursprünglich stammt der Begriff aus der Forstwirtschaft. Im Laufe der Softwareentwicklung entsteht normalerweise eine zunehmende Komplexität. Es ist die Ressource „Einfachheit und Klarheit“ (engl. Simplicity), die durch Änderungen und Erweiterungen verbraucht wird. Man spricht von einer Anhäufung von „Technical Dept“ also eine technische Verschuldung, die jede Weiterentwicklung immer schwieriger macht. Die Symptome dieses Problems nennt man Rigitität und Fragilität. Rigitität heißt, dass Änderungen übermäßig aufwändig sind. Selbst für kleinste Änderungen werden oft utopisch hohe Aufwandsschätzungen abgegeben. Fragilität, das bedeutet, dass durch Änderungen sehr häufig Fehler entstehen. Meist sogar in Bereichen, die mit der eigentlichen Änderung nichts zu tun haben und somit auch nicht getestet werden. Unter Nachhaltigkeit bei Softwareentwicklung wird die Bemühung verstanden, Erweiterungen ohne technische Schulden zu machen und die Ressource Simplicity gemäß dem KISS-Prinzip zu erhalten, damit künftige Änderungen und Erweiterungen der Software genauso einfach sind, wie am ersten Tag.  (öffnet in neuem Tab)" href="https://de.m.wikipedia.org/wiki/KISS-Prinzip" target="_blank">KISS-Prinzip</a> zu erhalten. Künftige Erweiterungen der Software sollen  genauso einfach sein, wie am ersten Tag.</p>



<p>Die wichtigste Hilfstechnik dabei ist das sogenannte Test Driven Development (TDD). Abgesichert durch sogenannte Unit-Tests, wird der Programmierer dabei in die Lage versetzt, jederzeit Refactorings machen zu können. Das ist Grundvoraussetzung, um überhaupt Clean Code erzeugen zu können. Nach dem Prinzip „First make it work then make it right“ verwandelt der Code sich sukzessive in Clean Code. Durch Unit-Tests verliert der beliebte Programmierspruch „Never change a running system“ erstmals seine Gültigkeit. Das genaue Gegenteil wird nun gefordert. Perfekter Code entsteht nicht durch Planung sondern durch unzählige kleine Verbesserungen. Das ist auch die Arbeitsweise von Malern, Komponisten, Schriftstellern, Steinmetzen, Töpfern, Holzschnitzern, usw. Beim herkömmlichen Programmieren existiert immer die Gefahr, dass mit jeder kleinen „Verbesserung&#8220; neue Fehler eingebaut werden. Mit den Unit-Tests wird nun aber ein Sicherheitsnetz aufgespannt, &nbsp;welches diese Gefahr bannt. Für die traditionelle Rolle des Software-Architekten hat Martin in seinen „Uncle Bob“-Trainingsvideos häufig nur Spott übrig.&nbsp;</p>



<p>Um TDD zu erlernen brauchen Sie einen erfahrenen Coach. Hier kann man vieles falsch machen und hinterher ist die Enttäuschung groß. Sie sollten ihr System so aufsetzen, dass bei jedem Build-Lauf auch alle Unit-Tests kompiliert und ausgeführt werden. Da auf Dauer sehr viele Tests entstehen, ist gute Performance extrem wichtig. Das Ausführen aller Tests sollte insgesamt weniger Zeit kosten als der komplette Build-Lauf. Ansonsten wird TDD sehr schnell als lästig empfunden. Es dürfen keine Implementierungsdetails und keine privaten Methoden getestet werden. Hält man sich nicht daran, dann machen Refactorings auch immer wieder Änderungen an den Tests notwendig. Das wäre dann völlig am Ziel vorbeigeschossen. Genau das muss man vermeiden. Nur wenn man das Programmverhalten ändert, sollen auch die Tests verändert werden.</p>



<h3 class="wp-block-heading">Clean Code ist fast das Gleiche wie nachhaltige Softwareentwicklung</h3>



<p>Es gibt mittlerweile ausgereifte Techniken, um in diesem Sinne nachhaltige Softwareentwicklung zu betreiben. Der Autor Robert C. Martin nennt das Clean Code.</p>



<p>Clean Code ist ein Überbegriff für alles, was hilft technische Schulden zu vermeiden. Ein Programmierer verwendet sehr viel mehr Zeit damit, Code zu lesen als zu schreiben. Dabei ist es immer schwierig, fremden Code zu verstehen. Manche verstehen den eigenen Code nicht mehr, wenn sie ihn eine Weile nicht mehr gesehen haben. Wenn Programmcode sicht nicht aus sich selbst heraus verständlich erklärt, wenn es dazu unzähliger Kommentare bedarf, dann ist er auch nicht clean.</p>



<p>Es geht los mit sauberer Code-Formatierung. Ich hasse es, horizontal scrollen zu müssen. Wenn man beim Lesen das Ende einer Codezeile erreicht hat, weiß und sieht man nicht mehr was am Anfang stand. Zur Einhaltung von Formatierungsregeln, auf die sich das ganze Team geeinigt hat, verwendet man am besten ein Tool. Dieses muss sich in die eigene Entwicklungsumgebung integrieren lassen. Und dann nur Mut, um damit gnadenlos die kunstvollen alten Formatierungen zu zerstören.</p>



<p>Weiter geht es mit der richtigen Namensfindung für Klassen, Methoden, Variablen, etc. Der Code wird dadurch gut lesbar und Kommentare werden überflüssig. Ein Kommentar ist nur dann wirklich notwendig, wenn es ein Defizit im Code gibt.</p>



<p>Methoden und Funktionen sollten auch nur eine einzige Aufgabe erledigen, und sie sollen sie gut erledigen. Dazu reichen in der Regel 3-5 Codezeilen</p>



<p>Nachdem Robert C. Martin die formalen Kriterien für Clean Code abgehandelt hat, geht er ans Eingemachte. Was macht nun inhaltlich guten Clean Code aus? Das wichtigste ist die Einhaltung der <a href="https://de.m.wikipedia.org/wiki/Prinzipien_objektorientierten_Designs#SOLID-Prinzipien" target="_blank" rel="noreferrer noopener" aria-label="Nachdem Robert C. Martin die formalen Kriterien für Clean Code abgehandelt hat, geht er ans Eingemachte. Was macht nun inhaltlich guten Clean Code aus? Das wichtigste ist die Einhaltung der SOLID-Prinzipien. Es würde zu weit führen, diese im Einzelnen zu erläutern. Jeder gute Programmierer sollte sie eigentlich sowieso schon kennen und befolgen. (öffnet in neuem Tab)">SOLID-Prinzipien</a>. Es würde zu weit führen, diese im Einzelnen zu erläutern. Jeder gute Programmierer sollte sie eigentlich sowieso schon kennen und befolgen.</p>



<p>Wenn Sie also nachhaltige Softwareentwicklung betreiben wollen, dann schreiben Sie Clean Code und erzeugen ihn mit TDD.&nbsp;</p>



<p>Alle Prinzipien von Clean Code außer TDD kann man recht sehr gut autodidaktisch erlernen mithilfe der Video-Reihe „Uncle Bob&#8220;. Die Videos sind sehr unterhaltsam und das Englisch von Robert C. Martin ist sehr gut zu verstehen. Schauen Sie doch einfach mal in <a rel="noreferrer noopener" aria-label="Die restlichen Pronzipien von Clean Code kann man recht sehr gut selbst erlernen mithilfe der Vido-Reihe „Uncle Bob&quot;. Die Videos sind sehr unterhaltsam und das Englisch von Robert C. Martin ist sehr gut zu verstehen. Schauen Sie doch einfach mal in das erste Trainingsvideo rein, es ist kostenlos.
 (öffnet in neuem Tab)" href="https://cleancoders.com/episode/clean-code-episode-1/show" target="_blank">das erste Trainingsvideo</a> rein, es ist kostenlos.</p>



<p>Ist nachhaltige Softwareentwicklung nun das Gleiche wie das Erstellen von Clean Code? Fast, aber nicht ganz! </p>



<h3 class="wp-block-heading">„Clean Code“ &#8211; ein unsauberer Begriff&nbsp;</h3>



<p>Mir persönlich gefällt der Begriff „Clean Code“ nicht besonders gut. „Clean“, das klingt nach Wachmittelreklame. Das Wort enthält im Vergleich zu „nachhaltig“ nicht den eigentlichen Zweck. Sehr alt und daher sehr bekannt ist der Begriff „quick and dirty“, wenn in Programmen eine schnelle Lösung eingebaut wird. Eine schnelle Lösung, von der man genau weiß, dass sie die Codequalität verschlechtert. Mit „clean“ assoziiert man also das Gegenteil von „quick and dirty“. Folglich glaubt man, dass gute Codequalität nicht „quick“ zu programieren ist und dass man sehr viel Zeit für die Programmierung benötigt. Das ist falsch. Es gibt etliche Studien, die beweisen, dass mit TDD erstellter Clean Code genauso schnell zu schreiben  ist, wie auf konventionelle Weise erzeugter Code.</p>



<p>Ich bin überzeugt davon, dass bei einem Programmierwettbewerb ein Team gut eingespielter TDD-ler jedes andere Team schlagen würde. Das liegt daran, dass sich bei konventioneller Programmierung kleine Fehler einschleichen, die erst mühsam mit dem Debugger gefunden werden müssen. Bei so einem Wettbewerb würde der Schiedsrichter sehr genau die Korrektheit überprüfen, und wenn er Fehler finden würde, dann müsste das jeweilige Team nacharbeiten. Spätestens dann würde das Team TDD in Führung gehen.</p>



<p>Das zweite Wort bei „Clean Code“ gefällt mir nicht wirklich. Es geht nicht um das Ergebnis „Code“ sondern um den Prozess, und der enthält mehr als nur den Code. Man findet höchst selten den Begriff „Clean Coding“. Häufig wird stattdessen der Begriff  „<a rel="noreferrer noopener" aria-label="Extreme Programming (opens in a new tab)" href="https://de.m.wikipedia.org/wiki/Extreme_Programming" target="_blank">Extreme Programming</a>“ (XP) verwendet, was meiner Meinung nach ein abscheuliches Wording ist.</p>



<p>Der Begriff „nachhaltige Softwareentwicklung“ in genau dem Kontext wie er hier verwendet wird, wurde erstmalig im Jahr 2005 in dem großartigen Buch „<a href="https://www.amazon.de/gp/product/0321286081/">Sustainable Software Development: An Agile Perspective</a>“ von Kevin Tate erwähnt. Frühere Erwähnungen in genau diesem Sinn sind mir zumindest nicht bekannt. Knapp 3 Jahre später erschien das berühmte Buch „Clean Code: A Handbook of Agile Software Craftsmanship“ von Robert C. Martin. Martins Idealvorstellungen von gutem Code sind fast identisch mit denen von Tate. Diese Übereinstimmung ist erklärbar, weil beide Anhänger von XP und agiler Entwicklung sind. Martin hatte Tates Buch zuvor vermutlich nicht gelesen, denn sonst hätte er Tate zitiert. Im Literaturanhang ist Tate jedenfalls nicht erwähnt. Es ist wirklich schade, dass Tate nicht mehr prägenden Einfluss hatte, und sich somit der Begriff „Sustainable Software Development“ nicht durchgesetzt hat.</p>



<h3 class="wp-block-heading">Der Unterschied von nachhaltiger Softwareentwicklung&nbsp;und Clean Code</h3>



<p>Ist nun nachhaltiger Code, so wie ich ihn mir wünsche, das Gleiche wie Robert C. Martins Clean Code? Verwendet dieser Blog nur ein anderes Wording? Nein, es gibt wichtige Unterschiede im Detail.</p>



<p>Ich möchte zunächst die folgende einfache Formel aufstellen:</p>



<p style="text-align:center"><b>Nachhaltiger Code = Clean Code + X</b></p>



<p>Was beinhaltet nun dieses X? Was unterscheidet nachhaltigen Code von Uncle Bobs Clean Code?</p>



<p>Besserer Clean Code ist mit nachhaltiger Softwareentwicklung machbar.</p>



<p>Die Ideale in Bezug auf Design und Architektur sind geringfügig unterschiedlich. Ich habe andere Vorstellungen davon, wie gutes Moduldesign aus der Mikroperspektive zu entwickeln ist. Aus der Makroperspektive setze ich andere Schwerpunkte bezüglich der Systemarchitektur.</p>



<h3 class="wp-block-heading">Nachhaltige Softwareentwicklung aus der Mikroperspektive</h3>



<p>Man hat bei Robert C. Martin manchmal den Eindruck, dass er glaubt, ein Algorithmus entsteht ganz von allein. Alles, was man dazu braucht ist TDD und die Beachtung von bestimmten Refactoring-Regeln. Exemplarisch dafür ist das Lehrbeispiel bei Uncle Bob zur Primfaktorzerlegung. Er möchte das Publikum von TDD überzeugen und zeigt, dass alleine die konsequente Anwendung von TDD quasi automatisch zum Algorithmus „<a href="https://de.m.wikipedia.org/wiki/Sieb_des_Eratosthenes">Sieb des Eratosthenes</a>“ führt. Das Ergebnis ist zwar zugegebenermaßen in Bezug auf Performance noch nicht optimal. Es ist auch nicht genau das, was oben im verlinkten Wikipedia-Beitrag beschrieben ist. Das Erstaunliche ist jedoch, dass alleine aufgrund der Anwendung von Prinzipien ein Algorithmus entstanden ist. </p>



<p>Uncle Bob zeigt dieses Beispiel, nein diesen Zaubertrick, gleich in zwei Videos. Ich war bei einem Code-Dojo dabei, bei dem die Primfaktorzerlegung Gegenstand der Übungsaufgabe war. Es wurde mit Entwicklern durchgeführt, die sehr erfahren bei TDD sind. Sie setzen TDD beinahe alltäglich ein. Bei dieser Übung kam das Team schnell auf Abwege. Über einen längeren Zeitraum entfernten wir uns eher von der Lösung, als dass wir ihr näher kamen. Es entstand ein Phänomen, welches Uncle Bob „Stuck“ nennt. Das ist, wenn man sich festgefressen hat. Wie ein Auto, das im Schlamm festsitzt. </p>



<p>Zugegeben, wir haben aus Unkenntnis auch nicht ganz genau das umfangreiche Regelwerk für gutes Refactoring angewendet, welches Robert C. Martin vorgibt. Ich persönlich glaube, dass TDD extrem hilfreich bei der Entwicklung von Lösungen ist. Sie stellen sich aber nicht von alleine ein. Wenn das so wäre, dann könnte man auch ein Programm schreiben, welches für beliebige Probleme automatisch eine Lösung findet.</p>



<p>Die Mehrzahl aller Programmieraufgaben beinhaltet einfache Probleme, bei denen man einen Lösungsansatz schon im Kopf hat, wenn man mit der Implementierung beginnt. Anders bei sehr schwierigen Problemen: Angenommen Sie bekommen die Aufgabe, den Zeitpunkt von Sonnenauf- und untergang zu berechnen. Als Input bekommen Sie geographischen Koordinaten und ein Tagesdatum. Sie werden sich bei dieser Aufgabe die Zähne ausbeißen, wenn Sie das alleine mit TDD und Refactoring lösen wollen. Selbst, wenn Sie alle zugrundeliegenden astrophysikalischen Gesetze und Konstanten kennen würden, würden Sie mit TDD nicht auf den richtigen Algorithmus kommen. Zumindest nicht in vertretbarer Zeit. </p>



<p>Wie löst man derartige Aufgaben in der Praxis? Man sucht im Internet oder in der wissenschaftlichen Literatur nach einem Algorithmus oder man konsultiert einen Experten. Später, wenn einmal der Algorithmus gefunden ist, wird man bei der Implementierung selbstverständlich TDD einsetzen.</p>



<p>Den überwiegenden Zeitanteil zum Entwickeln von Lösungen, benötigt man in der Praxis weder bei sehr schwierigen Problemen noch bei sehr einfachen Problemen. Das Herausfinden geeigneter Lösungsansätze, das Software-Design ist am aufwändigsten bei mittelschweren Problemen. Gibt es zugleich mehrere Lösungsalternativen, dann kostet die Entscheidungsfindung ebenfalls viel Zeit. Nachhaltige Softwareentwicklung heißt dabei, dass man sich jeweils immer für die einfachste Lösung (Simplicity) entscheidet. Das herauszufinden ist aber meistens nicht einfach (easy).  (Wir haben im Deutschen leider keine unterschiedlichen Worte für „simple“ und „easy“.)</p>



<h3 class="wp-block-heading">Evolutionäres oder geplantes Design</h3>



<p>Nachhaltige Softwareentwicklung betont diesen Moment sehr viel stärker als Clean Code nach Robert C. Martin. Er denkt nur einen kurzen Augenblick über das Design nach und beginnt dann gleich mit TDD. Ich glaube nicht, dass sich gutes und vor allem nachhaltiges Design alleine dadurch einstellt. Auch nicht, wenn dabei alle <a href="https://de.m.wikipedia.org/wiki/Prinzipien_objektorientierten_Designs#SOLID-Prinzipien">SOLID-Prinzipien</a> penibel eingehalten werden.</p>



<p>In dem sehr lesenswerten Artikel „<a rel="noreferrer noopener" aria-label="Is Design Dead (opens in a new tab)" href="https://www.martinfowler.com/articles/designDead.html" target="_blank">Is Design Dead</a>?“ befasst sich Martin Fowler mit der Frage ob wir überhaupt noch Software-Design benötigen. Fowler ist Mitunterzeichner des agilen Manifests, überzeugter Anhänger von Clean Code und als Chefentwickler beim Consulting-Unternehmen&nbsp;ThoughtWorks. Er hat somit jede Menge praktische Erfahrung. Trotzdem oder gerade deswegen outet er sich als Anhänger geplanten Designs. </p>



<p>Im Gegensatz zu Fowler und damit wieder in einer Linie mit Robert C. Martin halte ich sehr wenig von UML. Bei der konkreten Design-Planung, vor allem, wenn sie im Team stattfindet, sind grafische Aufzeichnungen sehr hilfreich. Ein Bild sagt mehr als tausend Worte. Vor allem ist es ein ausgezeichnetes Instrument um die Gehirne aller Diskussionsteilnehmer zu synchronisieren. UML ist hierfür aber viel zu umständlich und zu zeitaufwändig. </p>



<p>Das beste Planungsinstrument ist meiner Meinung nach eine Schultafel. Sie bietet genügend Platz und Korrekturen sind schnell und einfach machbar. Schultafeln sind in Besprechungsräumen eher selten anzutreffen. Man muss sich dann eben mit Whiteboard, Flipcharts oder notfalls mit einem Blatt Papier behelfen. Es geht darum, anderen die eigene Vorstellungswelt mitzuteilen. Jede Kritzelei ist hierbei erlaubt. Verboten sind lange Monologe, weil genaues Zuhören und das Entwickeln von Ideen in der eigenen Gedankenwelt sich gegenseitig ausschließen. Diese Art von Planung lebt im hier und jetzt. Für die Dokumentation und Archivierung kann man zum Schluss ein Foto des Tafelbildes machen. Weitere Aufzeichnungen sind nicht notwendig. Es geht darum ein kohärentes Bild in den Köpfen zu hinterlassen. <br></p>



<h3 class="wp-block-heading">Entwurfsmuster</h3>



<p>Stark auseinander gehen die Meinungen auch hinsichtlich der Verwendung von Entwurfsmustern. Hiermit sind nicht die SOLID-Prinzipien gemeint, sondern jene 23 Entwurfsmuster, die im berühmten Buch „Design Patterns. Elements of Reusable Object-Oriented Software“ der Gang of Four (GOF) beschrieben sind. Robert C. Martin ist ein unbedingter Befürworter von Entwurfsmustern. </p>



<p>Auch mit dem Singleton Pattern hat er keine Probleme. Für viele andere ist das ein absolutes Tabu im Clean Code. Ich persönlich habe dazu auch eine eher pragmatische Einstellung. Es macht Probleme, die man kennen sollte, aber wenn es nicht anders geht, dann darf man es auch einsetzen. Mithilfe von Factory Pattern, kann man den gewünschten Effekt, dass nur eine einzige Instanz existiert, die vielen andern Objekten bekannt sein muss, meistens ebenso gut realisieren. Womit gleich das nächste Pattern angesprochen ist: Das Factory Pattern. Es ist ein unbedingtes Muss für Clean Code. Eine Factory ist ziemlich unproblematisch, solange sie keine zusätzliche Logik bekommt. </p>



<p>Aus meiner Erfahrung muss ich feststellen, dass der Einsatz von Entwurfsmustern häufig dazu führt, dass der Code nicht mehr nachhaltig ist. Es entstehen häufig unnötige Verkomplizierungen. Overengineering ist schlimmer als Copy-And-Paste. Martin Fowler schreibt dazu wörtlich:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The essence of this argument is that patterns are often over-used. The world is full of the legendary programmer, fresh off his first reading of&nbsp;GOF who includes sixteen patterns in 32 lines of code. I remember one evening, fueled by a very nice single malt, running through with Kent a paper to be called &#8222;Not Design Patterns: 23 cheap tricks&#8220; We were thinking of such things as use an if statement rather than a strategy. The joke had a point, patterns are often overused, but that doesn&#8217;t make them a bad idea. The question is how you use them.</p><cite>Martin Fowler, Is Design Dead</cite></blockquote>



<p>Anmerkung: Mit „Kent“ ist <a href="https://de.m.wikipedia.org/wiki/Kent_Beck">Kent Beck</a> gemeint, der TDD wiederentdeckt und diese Technik in der heutigen Form erschaffen hat.</p>



<p>Kevin Tate ist nicht grundsätzlich gegen Pattern aber er ist ebenfalls kritisch eingestellt. Er schreibt dazu unter anderem:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>The use of design patterns can lead to an unhealthy emphasis on up-front design. I have been on projects where people spent too much time trying to analyze a problem so they could try to identify what design patterns would apply. If you aren&#8217;t sure, don&#8217;t use a pattern. Simplicity, as always, should be the primary goal. Chances are, if there is a pattern, there it will emerge. You can always refactor to it later, as in.</p><cite>Kevin Tate, Sustainable Software Development: An Agile Perspective</cite></blockquote>



<p>Exemplarisch für diese Problematik ist Das <a href="https://de.m.wikipedia.org/wiki/Beobachter_(Entwurfsmuster)">Observer Pattern</a>, das in vielen Fällen eine sehr elegante Lösungsmöglichkeit ist. Wichtig beim Einsatz ist, dass es keine Rückkopplung des Observers zum beobachteten Objekt gibt. Damit meine ich folgendes Szenario: Der Observer registriert eine Änderung und benachrichtigt ein anderes Objekt, welches dann eine Zustandsänderung am beobachteten Objekt vornimmt, welches dann wieder dazu führt, dass der Observer eine Veränderung registriert usw. Das ergibt bei positiver Rückkopplung eine Endlosschleife. Derartige Fehler erkennt man normalerweise sofort beim Entwickeln. Das Programm friert ein, oder es gibt im Falle rekursiver Programmierung ein Stack Overflow.</p>



<p>Der Bug überlebt aber häufig, wenn eine negative Rückkopplung vorliegt. In diesem Fall pendelt das System nach mehreren Änderungen irgendwann wieder in eine stabilen Zustand ein. Chaotisch wirkt das ganze, wenn man es im Debugger beobachtet. Es ist nicht der Programmcode, der in diesem Fall komplex ist, sondern das Laufzeitverhalten. Das äußerlich sichtbare Programmverhalten ist aber so wie gewünscht, ansonsten hätte man den Fehler erkannt. Das real existierende Laufzeitverhalten war aber so nie vom Programmierer beabsichtigt.</p>



<p>In meiner langjährigen Berufspraxis habe ich derartiges schon öfters gesehen. Normalerweise analysiere Legacy Code, der mir unbekannt ist, indem ich den Programmablauf im Debugger anschaue. Stoße ich dann auf dieses Phänomen, dann bin ich verloren. Der ursprünglich geplante Programmablauf kann nur noch erraten werden. Bugfixings in derart rückgekoppelten Systemen sind extrem schwierig.</p>



<p>Wie kommt so etwas zustande? In vielen Fällen ist derjenige, der das Observer Pattern eingebaut hat, unschuldig. Verbockt hat es jemand anderes, der irgendwann später und unbedacht die Rückkopplung erzeugt hat. Bei zirkulären Modulreferenzen genügt oftmals eine einzige Zuweisung. Das äußerlich sichtbare Programmverhalten ist wie gewünscht, und im Debugger schaut sich das niemand mehr an. Wie kann man das verhindern? Entweder man verzichtet auf das Observer Pattern, was wirklich schade ist, oder man achtet bei der Coderevision darauf, dass es nur hierarchische Referenzen gibt. Insbesondere in der Nähe von Observer Pattern sollten netzartige Modul- oder Objektstrukturen unbedingt vermieden werden. Ich habe mir sagen lassen, es soll tatsächlich noch Entwickler-Teams geben, die keine Coderevisionen durchführen.</p>



<p>Das Problem von netzartigen Strukturen führt zur Makroperspektive.</p>



<h3 class="wp-block-heading">Nachhaltige Softwareentwicklung aus der Makroperspektive</h3>



<p>In seinen Videos macht sich Uncle Bob regelmäßig über Softwarearchitekten lustig. Er verspottet sie als Wichtigtuer. Robert C. Martin fordert, dass Architekten auf jeden Fall auch programmieren sollen, weil sie sonst den Bezug zur Realität verlieren. Diese Forderung kann ich nur unterschreiben. Auch ich habe die Erfahrung gemacht, dass Softwarearchitekten sich häufig exakt so verhalten, wie sie in den Videos charakterisiert werden. Dennoch ist gute Softwarearchitektur extrem wichtig für nachhaltige Softwareentwicklung. </p>



<p>Das Buch „Clean Architecture A CRAFTSMAN’S GUIDE TO SOFTWARE STRUCTURE AND DESIGN&#8220; von Robert C. Martin beschreibt gegenüber seinen vorherigen Clean Code Buch seine Sichtweise von guter Softwarearchitektur. Für ihn gibt es keinen Unterschied zwischen Design und Architektur. Gute Architektur ergibt sich dann quasi von alleine, wenn alle Prinzipien für gutes Design eingehalten werden und der Code mit TDD erzeugt wurde und somit testbar ist.</p>



<p>Nachhaltige Softwareentwicklung ist nach meinem Verständnis mehr. Obwohl die Grenzen fließend sind, gibt es für mich einen Unterschied zwischen Design und Architektur. Dabei halte ich es für weniger wichtig, wie die Definition formuliert wird. Bedeutend sind die Konsequenzen, die man daraus zieht. Wie schon bei meinem Plädoyer für geplantes Design vertrete ich die Meinung, dass das Architekturmodell aus einer Planung hervorgehen sollte. State of the Art ist das nachfolgend abgebildete  Architekturmodell, welches aus dem „<a rel="noreferrer noopener" aria-label="Domain-driven Design (opens in a new tab)" href="https://de.wikipedia.org/wiki/Domain-driven_Design#Architekturtechniken" target="_blank">Domain-driven Design</a>&#8220; entstammt. </p>



<figure class="wp-block-image"><img decoding="async" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Schichtenarchitektur.svg/898px-Schichtenarchitektur.svg.png" alt=""/><figcaption>Domain-driven Design</figcaption></figure>



<p>Robert C. Martin zieht einen Vergleich heran, um die Unterschiedslosigkeit von Design und Architektur zu begründen. Er sagt: Die Pläne, die ein Architekt eines Gebäudes abliefert, enthalten bereits alle möglichen Design-Details. Der genaue Ort der Lichtschalter, die mögliche Möblierung, das ist alles schon in den Plänen eingezeichnet. Das ist richtig. Nach meinem Verständnis ist Bauarchitektur im übertragenen Sinne keine Softwarearchitektur. Es ist Design. Softwarearchitektur ist weiter übergeordnet. Benutzt man die Metapher, dann ist Softwarearchitektur vergleichbar mit dem Erstellen von Flächennutzungsplänen, Raumordnungsplänen und Bebauungsplänen, bei denen es um die Versorgung und Planung von Straßen, Kanalisation, etc geht. Also: Wie muss eine Software geplant, werden damit alle Plugins harmonisch ineinander greifen können?</p>



<h3 class="wp-block-heading"> Zyklenfreie Architektur </h3>



<p>Das Thema zyklenfreie Architektur wird in dem oben genannten Buch von Robert C. Martin unter dem Kapitel „The Acyclic Dependency Principle&#8220; ADP behandelt. Er traut sich aber nicht die Vorteile von hierarchischen Architekturen anzusprechen. Beim Vorläufer der objektorientierten Programmierung, der strukturierten Programmierung aus den 70er Jahren entstand eine hierarchische Struktur ganz von alleine. Hierarchische Strukturen haben den Vorteil, dass das Gehirn die darin enthaltene Ordnung leicht erfasst. Zyklische Programmstrukturen sind sehr viel schwieriger zu verstehen. Irgendwie dreht man sich beim Versuch Verständnis darüber zu gewinnen, auch immer wieder im Kreis. Natürlich will ich nicht zurück in die 70er Jahre. Plugin-Architekturen lassen sich auch nur realisieren, wenn man die Pfeilrichtung der Abhängigkeiten durch Anwendung des „<a rel="noreferrer noopener" aria-label="Dependency-Inversion-Prinzips (opens in a new tab)" href="https://de.wikipedia.org/wiki/Dependency-Inversion-Prinzip" target="_blank">Dependency-Inversion-Prinzips</a>&#8220; umdreht. Hierbei kommen i.d.R. Interfaces zum Einsatz.</p>



<p>Zyklische Programmarchitekturen sind aus meiner Erfahrung der schlimmste Killer von Nachhaltigkeit. Im großartigen Buch „<a rel="noreferrer noopener" label="Langlebige
 Softwarearchitekturen (opens in a new tab)" href="https://www.dpunkt.de/buecher/13056/langlebige-software-architekturen.html" target="_blank" class="broken_link">Langlebige Softwarearchitekturen</a>&#8220; von Carola Lilienthal zieht sich dieses Thema wie ein roter Faden durch den gesamten Text. Im Kapitel 5.3 zeigt sie, dass aus Untersuchungen hervorgeht, <em>&#8222;dass Menschen dann Wissen gut aufnehmen, es wiedergeben und sich darin zurechtfinden können, wenn es in hierarchischen Strukturen vorliegt&#8220; (Seite 85).</em> Dies bestätigt exakt meine Erfahrungen aus der Berufspraxis. Man sollte also genauestens überlegen, an welchen Stellen klassische Hierarchien sinnvoller sind. Plugin-Strukturen sollten immer auf die eine oder andere Art geordnet sein. Baumartige Strukturen mit geringer Tiefe erleichtern dabei die Abbildung im Kopf.</p>



<p>Zyklen entstehen immer dann unabsichtlich, wenn ein Programmierer sieht, dass eine Methode einer bestimmten Klasse genau das macht, was er an einer anderen Stelle benötigt. Copy-And-Paste kommt nicht in Frage, das ist verpönt. Also wird auf diese Klasse referenziert. Die Methode wird notfalls „public“ gemacht und das Interface wird erweitert. „Problem gelöst“, denkt er. Hätte der Programmierer eine bildhafte Vorstellung der Programmarchitektur im Kopf, dann wüsste er, dass er gerade einen Zyklus geschaffen hat. Im Ergebnis ist das viel schlimmer, als wenn er die Methode mit Copy-And Paste dupliziert hätte. </p>



<p>Eine klare Vorstellung der vorhandenen Programmarchitektur ist das A und O nachhaltiger Softwareentwicklung. Der Programmierer erkennt dann sofort, dass er die benötigte Methode an einen klar definierten anderen Ort umziehen muss. TDD und SOLID alleine verhindern keinen Wildwuchs. Bei großen Zyklen geht die Testbarkeit verloren, und TDD ist nicht mehr möglich. Kleine Zyklen stehen aber nicht im Widerspruch zur TDD. Sie sind zwar beherrschbarer, aber aus gesamtheitlicher Sicht geht die Lesbarkeit verloren.</p>



<p>Jeder, der sich mit nachhaltiger Softwareentwicklung befasst, sollte dieses Buch von Carola Lilienthal gelesen haben. Sie hat über achtzig Softwaresysteme zwischen 30 000 und 15 Mio. Lines of Code (LOC) in Java, C++, C#, ABAP und PHP untersucht. Mit Werkzeugen aus der <a rel="noreferrer noopener" aria-label="statischen Code-Analyse (opens in a new tab)" href="https://de.wikipedia.org/wiki/Statische_Code-Analyse" target="_blank">statischen Code-Analyse</a> erstellte sie Metriken zur grafischen Darstellung von allen Architekturelementen. So entdeckte sie jede Art von Zyklen, auch wenn sie sehr versteckt sind. Mit diesen Werkzeugen ist eine Bewertung der Architektur über den sogenannte &#8222;Modularity Maturity Index&#8220; (MMI) möglich.  In 11 Geschichten aus der Praxis schildert sie die Erfahrungen bei der Wartung und Weiterentwicklung von Systemen mit unterschiedlichen MMI und LOC.  Das Buch ist nicht nur sehr wertvoll für Programmierer sondern auch für  Projektmanager. (Letztere können die technischen Details gerne  überblättern.) Praktiker erfahren im Anhang, welche Werkzeuge benutzt wurden und wie man sie einsetzt. </p>



<p>Jeder Programmierer, der glaubt, dass viele Interfaces ausreichen, um eine nachhaltige Architektur errichten zu können, sollte das Kapitel  7.4  „Interfaces – das architektonische Allheilmittel?&#8220; lesen. Carola Lilienthal erläutert, dass Interfaces oftmals nur die Abhängigkeit zwischen einzelnen Modulen verschleiern.  <em>„Eine echte Modularisierung z.B. im Sinne von fachlichen aufeinander aufbauenden Schnitten oder Microservices wird so nicht erreicht.&#8220; (Seite 131)</em></p>



<h3 class="wp-block-heading">Nachhaltige Softwareentwicklung ist auch ohne Agilität möglich</h3>



<p>Möglich ja, aber mit Agilität geht es besser!</p>



<p>Es gibt die Ausrede, man müsse sich nicht um Clean Code bemühen, weil es im Unternehmen keine agile Vorgehensweise gibt. Das muss auch nicht unbedingt die Schuld der Geschäftsleitung sein. </p>



<p>Es kann sein, dass der Kunde das nicht will. Wie gewohnt aus der Welt der materiellen Produkte, ist etwas Schlüsselfertiges gewünscht. Wenn ich mir ein neues Auto kaufe, verwende ich einen Fahrzeug-Konfigurator, nachdem ich mich für eine bestimmte Marke entschieden habe. Im Endergebnis habe ich dann für mich das beste Preis/Leistungsverhältnis erzielt. Das Fahrzeug wird zu einen festgesetzten Termin geliefert, so wie von mir konfiguriert. Es ist verständlich, dass man sich das auch bei Software so wünscht. Agilität führt anfänglich zu Verunsicherung. Man muss den Kunden die Vorteile von Agilität gut erklären. Nicht jeder Kunde versteht, dass Software etwas ganz anderes als ein materielles Produkt ist. Die Geschäftsleitung möchte den Kunden nicht verlieren und zum Schluss landet man wieder beim Wasserfall-Modell.</p>



<p>In diesem Fall sollte das Projekt ebenfalls mit nachhaltiger Softwareentwicklung umgesetzt werden. Das ist kein Widerspruch. Die agile Vorgehensweise ist möglich und empfehlenswert bei Legacy-Software, deren Code alles andere als Clean Code ist. Agilität ist sogar außerhalb von Softwareentwicklung möglich. Umgekehrt ist Agilität keine notwendige Voraussetzung für Clean Code. Auch wenn sich Agilität und Clean Code hervorragend ergänzen, ist das eine vom anderen in keiner Weise abhängig. Im Gegenteil: Ich behaupte, das klassische Projektmanagement wird über TDD erstmals machbar. Das liegt einfach daran, dass die Reihenfolge der Entwicklung einzelner Bausteine durch TDD keine Rolle mehr spielt. Durch das Aufheben von Abhängigkeiten zwischen den Modulen wird bei der Projektplanung vieles sehr viel einfacher. So können Terminengpässe nun auch durch frühzeitige Personalaufstockung überwunden werden. Es wird auch besser sichtbar, wenn Termine gefährdet sind.</p>



<p>Insgesamt ist aber Agilität bei der Softwareentwicklung trotzdem sehr empfehlenswert. Der gegenwärtige Hype bei agilen Methoden kann sehr schnell wieder in sich zusammenfallen oder durch etwas ganz anderes ersetzt werden. Nachhaltige Softwareentwicklung ist auch nachhaltig an sich und somit von Modeerscheinungen unabhängig.</p>



<hr class="wp-block-separator"/>



<p><strong>Nächster Beitrag:</strong> <a href="https://software-sunshine-blog.de/tcr-vs-tdd">Was ist TCR?</a></p>
<p>Der Beitrag <a rel="nofollow" href="https://software-sunshine-blog.de/nachhaltige-softwareentwicklung">Besserer Clean Code durch nachhaltige Softwareentwicklung</a> erschien zuerst auf <a rel="nofollow" href="https://software-sunshine-blog.de">Software Sunshine Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://software-sunshine-blog.de/nachhaltige-softwareentwicklung/feed</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
