tag:blogger.com,1999:blog-17270318115909753542024-03-06T01:21:28.602+01:00Eventually InconsistentI help your development team become strategically more efficient by aligning them with the business domain they are working in, instead of just focusing on technical solutions.
<p><a href="https://patternapplied.com/en/">patternapplied.com</a></p>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-1727031811590975354.post-85351130302079370582023-10-19T17:48:00.000+02:002023-10-19T19:31:53.576+02:00Pracuję nad swoim kursem online: "DDD/CQRS/ES applied on JVM with Axon Framework"<p><b>💥 </b>Krótkie ogłoszenie:</p><p><br /></p><p><b>Powoli pracuję nad swoim kursem online o nazwie:</b></p><p><span style="color: #14397d; font-family: Arial;"><span style="font-size: 20px; white-space-collapse: preserve;"><b>DDD/CQRS/ES Applied on JVM with Axon Framework</b></span></span></p><p>Jeśli jesteś Programistą, Team Leaderem, lub Architektem i chcesz W KOŃCU wprowadzić</p><b><ul style="text-align: left;"><li><b>Domain-Driven Design</b>,</li><li><b>Command Query Responsibility Segragation</b>,</li><li><b>Event Sourcing</b></li></ul></b><div><p>do Twojego systemu opartego o platformę <b>JVM </b>- zarówno <b>legacy</b>, jak i <b>greenfield </b>- to na pewno będzie to <b>coś dla Ciebie</b>!</p><p>Kurs będzie startował w języku polskim niebawem, a tymczasem...</p><div style="text-align: center;"><span style="font-size: x-large;">Dołącz już dziś do listy oczekujących,<br />a następnie<br /></span><a href="https://cqrsapplied.pl" style="font-size: xx-large;">pobierz darmowy Ebook</a></div><p></p><div style="text-align: center;"><a href="https://cqrsapplied.pl" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1366" data-original-width="1500" height="582" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvBozZVom9rkgHiAVk4CrUhGq6nTmozjV8HMCJ1M0sPVBUCUKREHUs97s6b6MaXfqYqWse4ec2R3_5I82cEOPydDozvrtZoZ10yETYSGTb75VlzxSsZaBSKRhwsJO5tAXX1_58Wq6xRKP0gHxV3esycmTpexKc89sWluC_yskwILSU2EPCzvqXug-af54/w640-h582/4-narzedzia-do-ddd-cqrs-es-na-platformie-java-pdf-okladka.png" width="640" /></a></div><div style="text-align: center;"><p style="text-align: center;"><b><span style="color: #14397d; font-family: Arial;"><span style="font-size: 20px; white-space-collapse: preserve;">"</span><span style="font-size: 20px; white-space-collapse: preserve;">4 narzędzia do DDD/CQRS/ES na platformie Java</span></span><span style="color: #14397d; font-family: Arial; font-size: 20px; white-space-collapse: preserve;">"</span></b></p><div style="text-align: center;"><span style="color: #14397d; font-family: Arial;"><span style="text-align: left;">(* Plus jedno, błędnie za takie postrzegane - BONUS!)</span></span></div><p></p><div><br /></div></div><p>Sprawdź: </p><p><a href="https://cqrsapplied.pl"><span style="font-size: x-large;">cqrsapplied.pl</span></a></p><p>Do zobaczenia niebawem!</p><p><br /></p></div>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-71544718342752987492021-02-04T23:08:00.001+01:002021-02-05T10:03:13.801+01:00The outcome of my 10 unique years of deep dive into DDD/CQRS/ES<p><span style="font-family: Arial; font-size: 11pt; white-space: pre-wrap;">At the beginning of this year, I launched my personal website <a href="https://patternapplied.com">patternapplied.com</a> (for English version <a href="https://patternapplied.com/en/">patternapplied.com/en</a>). </span></p><span id="docs-internal-guid-aebc7618-7fff-acef-d81c-12594d31a270"><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I specialize in Domain-Driven Design, Command Query Responsibility Segregation, Event Sourcing on the JVM platform and <b>with 10 years of experience in that field and the knowledge gathered over this time, I finally feel prepared and ready to share it with a broader audience</b>.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I should have done this a gazillion years ago, but hey… better late than never. </span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial;"><span style="font-size: 14.6667px; white-space: pre-wrap;"><br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL_hUR2BzdIDbAYwueA7BocIRJaFuGptWg4k802V_ufdfinWNaCqL6EwuYjgAVNm3nT9NhGt6gblQ-esr9I3Tkx9jvHwF98t5yxI2Bo-OtlMFfLGFvoYBRdDtoVkDmWCPjck8i0Ql-ERs/s907/pattern-applied.PNG" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="508" data-original-width="907" height="393" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL_hUR2BzdIDbAYwueA7BocIRJaFuGptWg4k802V_ufdfinWNaCqL6EwuYjgAVNm3nT9NhGt6gblQ-esr9I3Tkx9jvHwF98t5yxI2Bo-OtlMFfLGFvoYBRdDtoVkDmWCPjck8i0Ql-ERs/w703-h393/pattern-applied.PNG" width="703" /></a></div><p></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 16pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 15pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="color: #14397d;"><b>The story</b></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I’ve been doing Domain-Driven Design since 2011. During this time I was able to truly dig deep into this topic, since I was working mainly on a single product in an extremely complex and dynamic domain.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Our team was responsible for delivering a new solution (next to the existing one) in the Core Domain of this product. One might say that this was a rewrite of a Legacy System, but it wasn’t. The other part of the system was still profitable. It was just doing things in a less automated and less human-readable way. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">We carefully and strategically decided what to put in the new Core, and what to use from the existing parts. We had to take under consideration all the factors - client’s customizations, reporting, and other complex Subdomains of that system.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In one step I introduced Domain-Driven Design, Command Query Responsibility Segregation, and Event Sourcing together with a new language (Scala) to our Java-based system. It was challenging, but we’ve made it.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I started as a technical leader of a single agile team. After some time, the amount of work was big enough to split the team into two and new people joined us. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Then the time started to shrink. We wanted to launch our product at a specific time of the year, due to the market's conditions. It was clear that we couldn’t make it with those two teams. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The decision was made to put all the company's effort to that project. As it wasn’t enough, we also insourced two additional teams from the outside. As you might guess, it was a fun time.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I ended up as an architect, and finally we were able to deliver the very first version of that product on time.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Hurray!</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Shortly after the release we reduced our team and started to work on paying technical debt, stabilization, and, of course, more features.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Since that time, for a couple of years, I was able to see where DDD/CQRS/ES combo did work, and where it didn’t. We had to withdraw from those concepts in some places, whereas in others it was a perfect fit. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I also had a unique opportunity to see how the system evolved over the years and how decisions that had been made were influencing the future.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 16pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 15pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="color: #14397d;"><b>This is a perspective that cannot be gained in any other way.</b></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">And I offer this unique DDD/CQRS/ES experience in a form of consulting and/or training workshops - online and onsite. I will help your development team become strategically more efficient by aligning them with the business domain they are working in, instead of just focusing on technical solutions.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">My offer is not theoretical - I have already conducted a couple of successful training sessions during my journey. I’ve been there and I’ve done that.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">As a result, I prepared two workshops, which serve as a base. They can be aligned with your team goals and preferences in order to help you the most. <b>We can work together to ensure that these workshops will be tailored to your needs.</b> </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">You can see a brief description of those below.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 16pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 15pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="color: #14397d;"><b>Training Domain-Driven Design Applied</b></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://patternapplied.com/en/trainings/domain-driven-design-applied">Domain-Driven Design Applied</a>.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Learn how to deal with complexity in your business domain.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Discover strategic patterns that will help you find the most valuable parts of your system and build independent teams working on them.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Explore tactical patterns that will facilitate communication between developers and testers with the business.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Apply what you've learned right away, directly in the code.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 16pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 15pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="color: #14397d;"><b>Training CQRS and Event Sourcing Applied with Axon Framework</b></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><a href="https://patternapplied.com/en/trainings/cqrs-event-sourcing-axon">CQRS and Event Sourcing Applied with Axon Framework</a>.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Find out why business events are an ideal solution for information systems.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Use them to automate your business processes in a simple and transparent way for developers and business alike. Meet Axon Framework, which naturally supports Command-Query Responsibility Segregation and Event Sourcing in Java, Scala, and Kotlin.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Take part in a highly interactive workshop and see how to implement CQRS architecture.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 16pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 15pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="color: #14397d;"><b>Contact me</b></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">After 10 years of deep immersion into:</span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; list-style-type: disc; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Domain-Driven Design, Command Query Responsibility Segregation, and Event Sourcing, </span></p></li><li aria-level="1" dir="ltr" style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; list-style-type: disc; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">work as a Team Leader and Software Architect, </span></p></li><li aria-level="1" dir="ltr" style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; list-style-type: disc; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">management of the teams structure and communication…</span></p></li></ul><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">… I know exactly how and where to introduce DDD/CQRS/ES to any new or existing system.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Even a legacy one.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Let’s talk at <a href="https://patternapplied.com/">patternapplied.com</a>!</span></p></span>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-73712722953707233842018-09-04T11:33:00.001+02:002018-09-04T11:33:18.057+02:00Hello SegFault WrocławIt's been 3,5 years since I gave the last public talk...<br />
Way... too... long...<br />
<br />
So it has to change.<br />
And it will!<br />
<br />
I invite you to a really <b>innovative conference</b> for software architects: <a href="http://segfault.events/wroclaw2018/" target="_blank">SegFault Wrocław</a>.<br />
Let's get back to the basics again.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4jMjC3ggLWW7HlXFfDy6JgRcuiEERRB_BauRnBVoY4FTWBFyQjX8duKzJtD1KnNcnrJic0K4hBBtTs2f7pj7vHSsdVBBLcugfFUTdLnS3QxZtYeOt_ZKHfEfdAweqBxsjgD4XThF_V7c/s1600/segfaultKolorZnakLogo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4jMjC3ggLWW7HlXFfDy6JgRcuiEERRB_BauRnBVoY4FTWBFyQjX8duKzJtD1KnNcnrJic0K4hBBtTs2f7pj7vHSsdVBBLcugfFUTdLnS3QxZtYeOt_ZKHfEfdAweqBxsjgD4XThF_V7c/s400/segfaultKolorZnakLogo.png" width="400" /></a></div>
<br />
<br />
I'm going to be speaking about "<a href="http://segfault.events/sites/wroclaw2018/speakers/piotr-wyczesany/" target="_blank">Using Domain-Driven Design in legacy systems</a>".<br />
<br />
There will be some other experienced speakers, with a lot of knowledge gathered while working on <b>production systems</b> (not read from a book), so the event is quite unique.<br />
<br />
I'm looking forward to meeting you there!<br />
<br />
PS.<br />
I will have another announcement soon, so stay tuned...Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-62125431018249030112017-03-02T10:10:00.000+01:002017-03-02T10:16:32.829+01:00DDD Aggregates vs "Life beyond Distributed Transactions"Last week, I attended the <a href="http://sckrk.com/" target="_blank">Software Craftsmanship Kraków</a> meetup, where we discussed <a href="http://www.ics.uci.edu/~cs223/papers/cidr07p15.pdf" target="_blank">"Life beyond Distributed Transactions: an Apostate’s Opinion"</a> article by Pat Helland. Author tries to tackle the problem of almost-infinite scaling of applications. He ignores such issues like high availability on purpose and focuses only on scalability alone. That makes the essay easier to read – even for junior developer.<br />
<br />
Although the author does not say it explicitly, <b>there are a lot of similarities between presented concepts and Aggregates from Domain-Driven Design</b>. Pat's paper was written in 2007, so my wild guess is that he might have been familiar with Eric's book, which was published in 2004. <br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhjckfBC-cYYSPf94JpoJOUh8f1tGo-yC1dUWprlvhW3BqjXv8wiinjGyJVMX86YcPjMVA82Mk-oGEGNL3UiNYqky0lKD6wC3eqEwEh4ABZGn_-KHeo7UP2vX9duByyqre2uavabIFWkQ/s1600/aggregates-vs-life-beyond-distributed-transactions.png" imageanchor="1"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhjckfBC-cYYSPf94JpoJOUh8f1tGo-yC1dUWprlvhW3BqjXv8wiinjGyJVMX86YcPjMVA82Mk-oGEGNL3UiNYqky0lKD6wC3eqEwEh4ABZGn_-KHeo7UP2vX9duByyqre2uavabIFWkQ/s400/aggregates-vs-life-beyond-distributed-transactions.png" width="400" /></a></div>
<br />
Since there are still a lot of questions regarding Aggregate's boundaries (and technical difficulties arising around them) in DDD world, I recommend Pat's article as a complementary reading, which takes more infrastructure-oriented approach and may clarify some things.<br />
<br />
<a name='more'></a><br />
<span style="color: #0b5394; font-size: large;"><b>Layers</b></span><br />
<br />
Pat concentrates on technical aspects of almost-infinite application scaling and takes bottom-up approach by dividing the application into two layers (at least), which differ in their perception of scaling.<br />
<br />
<ul>
<li>The Lower Layer (scale-aware) knows about the fact that there will be more than one machine that the system will run on.</li>
<li>The Upper Layer (scale-agnostic) does not know about it and only uses the lower layer's abstractions.</li>
</ul>
<br />
We can see similar, yet not that concrete division in DDD. Based on the proper Business Domain decomposition, DDD approaches the problem from the other, top-down, side<br />
<br />
<ul>
<li>The Domain Model (scale-agnostic) is the place where business logic resides. It is not aware of the lower system layers and declares interfaces to be implemented.</li>
<li>The Infrastructure code (scale-aware) that provides the implementation of those interfaces in a way, that the system may be deployed on multiple machines, if need to.</li>
</ul>
<div>
<br /></div>
<span style="color: #0b5394; font-size: large;"><b>Pat's Entities vs Eric's Aggregates</b></span><br />
<br />
In the article, author defines Entity as a data being manipulated by the Upper Layer, which has to have a globally (in the system) unique identifier or key. This identifier needs to identify exactly one Entity and the data contained within that Entity. The size of the Entity does not matter as long, as it can fit in one scope of serializability (one machine, or one cluster). The Data in one Entity must be disjoint from the data of the other Entities.<br />
<br />
The Entity may be stored in many shapes: as a SQL records, a document in document database, or anything else that fits (even as an event stream). The Upper Layer does not have to know about that infrastructure concern.<br />
<br />
Does that sound familiar?<br />
<br />
The Aggregates from DDD are identified by unique (in the system) identifier. They may be of any size as long as they cover the true business invariants and nothing more (usually the smaller the better. Their data <a href="http://www.eventuallyinconsistent.com/2013/06/do-your-aggregates-touch-each-others.html" target="_blank">should not leak to the other instances</a> and can be stored in many forms. The Domain Model does not have to know about such infrastructure details.<br />
<br />
<span style="color: #0b5394; font-size: large;"><b>ACID vs BASE Transactions </b></span><br />
<br />
Both, Pat and Eric, aggree that the Entity (or in DDD world, the Aggregate) has to be the boundary of atomicity.<br />
<br />
Pat explicitly says that "a scale-agnostic programming abstraction must have the notion of entity as the boundary of atomicity". Not following that rule will result in a random system inconsistencies, when the large-scale system redeploys the Entity on a different machine. In other words, the changes in the Entity's state have to be performed in an ACID transaction.<br />
<br />
The communication between Entities should be done via messaging, embracing Soft State and Eventual Consistency, as in a BASE transaction. Of course, when you deal with messages, there are some issues to be addressed. Since "exactly-once-in-order delivery" is rarely available in scalable systems, the developers should use "at-least-once delivery" strategy, and deal with redelivery and out-of-order messages by themself. Pat describes a couple of useful patterns to help with that.<br />
<br />
Eric says, that Aggregates guard the true business invariants, so that each change in their state has to be always consistent. Not following that rule may lead to overcomplicated models, which are hard to change and maintain in the long run.<br />
<br />
Since one change in the Aggregate's state should be done in one ACID transaction, the communication between Aggregates should be done in a BASE one. This should not be hard to achieve, once you have the Domain Model right, because most of the business processes are usually eventually consistent anyway. This is explained in the <a href="http://dddcommunity.flywheelsites.com/library/vernon_2011/" target="_blank">"Effective Aggregate Design"</a> essay by Vaughn Vernon.<br />
<br />
<span style="color: #0b5394; font-size: large;"><b>Idempotency</b></span><br />
<br />
Since Pat advocates the "at-least-one delivery" strategy for dealing with messages, the Entity has to cope with message retries and reordering. Of course, this should be achieved via Idempotency, which is described as <i>"the processing of a message when a subsequent execution of the processing does not perform a substantive change to the entity"</i>. This leaves open door for defining what a substantive change is, and it will differ for different systems and Entities.<br />
<br />
There are some operations, that are idempotent by itself, but most of the time we will have to guarantee idempotency by ourselves. The author introduces a new concept to help us with that: Activity. It Is responsible for remembering the history of the interactions of given Entity with the other Entities.<br />
<br />
This history does not have to be full, but it needs to be able to answer the question: "did I process that message already?"<br />
<br />
In DDD words, those Activities should be part of Aggregates, if we want to achieve a scalable system.<br />
<br />
<span style="color: #0b5394; font-size: large;"><b>Complementary reading for DDD practitioners</b></span><br />
<br />
As I stated at the beginning, the Pat's <b>article is a complementary reading for all DDD practitioners</b>, who struggle with defining correct Aggregate boundaries, because of the infrastructure complexity in scalable systems.<br />
<br />
Pat describes the Entities (which in DDD lingo are the Aggregates) from the infrastructure perspective, which itself can give a new insight to some software developers.<br />
<br />
The author also introduces a new concept of dealing with idempotency: Activity. This might be a missing part for many DDD practicioners, since it explicitly shows how to guarantee proper communication between the Aggregates outside of the ACID transaction.<br />
<br />
I enjoyed the essay and I highly recommend it for all Domain-Driven Designers.<br />
<br />
<span style="color: #0b5394; font-size: large;"><b>And what about you, dear reader? </b></span><br />
<br />
Did you find more similarities between the Pat's Entity and the Eric's Aggregate? Or maybe you disagree, and see more differences?<br />
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-51589775425566259812016-09-12T09:30:00.000+02:002016-09-12T09:30:02.637+02:00Two years of domain knowledge crunchingThey say, that experience is something you don't get until just after you need it.<br />
<br />
This is especially true in the field of Software Development. You may learn something from a blogpost, a book, a presentation, or even by talking to a Domain Expert, but you have to get your hands dirty in order to fully understand a concept.<br />
<br />
<h3>
<span style="color: #0b5394; font-size: large;">Enter Smart Projects 1.0</span></h3>
<br />
Couple of days ago, we have released <a href="http://www.xtrf.eu/demo/" target="_blank">version 6.0 of XTRF platform</a> - a very first system that enables almost full automation of translation project management.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRt_bvz-vi7-xNSxzP9ziqGy-30BlqupokFOexlW6tiDNFQKfvthxRL0vGdNar-9Uuv7uPurKGDQbrhopzn-Bx81yssfRiX4vbI1wNc2HAAqujOgjsN9BBE-NbNsulSXOQ1fCz4sigEqo/s1600/xtrf-6.0-party.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRt_bvz-vi7-xNSxzP9ziqGy-30BlqupokFOexlW6tiDNFQKfvthxRL0vGdNar-9Uuv7uPurKGDQbrhopzn-Bx81yssfRiX4vbI1wNc2HAAqujOgjsN9BBE-NbNsulSXOQ1fCz4sigEqo/s400/xtrf-6.0-party.JPG" width="400" /></a></div>
<br />
The platform contains Smart Projects module in version 1.0, which I was developing for the last two years. In this module, we heavily used all the concepts that I was writing about on this blog for couple of years - <b>Domain-Driven Design</b>, <b>Command Query Responsibility Segregation</b>, and <b>Event Sourcing</b> of course - and it is written in <b>Scala</b>.<b> </b><br />
<div>
<br /></div>
The platform itself is not new - it was able to manage translation management projects before - even automate some pieces of work, but it was hard to use and, after all, not good enough for the market.<br />
<br />
In order to expand the market and gain new customers for the XTRF company, the platform required something more - something easier and more efficient to use. They decided to rewrite the heart of the platform - the project management part - the Core Domain.<br />
<br />
<h3>
<span style="color: #0b5394; font-size: large;">Long story short</span></h3>
<div>
<br />
I was leading this project from the very beginning. Back then, I had my team of highly skilled developers and a UX designer, who was outlining the vision of what we were building. </div>
<div>
<br /></div>
<div>
At that time, I was thinking that translation project management domain could not be that hard, and this one team was able to provide production-ready, and what was more important - market-ready solution, in couple of months.</div>
<div>
<br /></div>
<div>
Now, two years later, with peak of 7 development teams and 3 UX designers involved simultaneously in the project, I am much more realistic. </div>
<div>
<br /></div>
<div>
Now I know, that at the very beginning I was right - the domain of translation project management itself was not that hard. The thing I did not realize back then - <b>it was not the Core Domain...</b><br />
<br />
<h3>
<span style="color: #0b5394; font-size: large;">Translation Projects</span></h3>
<br />
Managing translation project is rather simple - you have to find vendors that will translate source files, then you have to arrange schedule, dispatch files, and fill out finances. Additionally, it almost always involves integration with third-party software: Computer-Assisted Translation tools - aka. CAT tools.<br />
<br />
Of course, you can manage all of that without specialized software - with little help of Google Spreadsheets for instance. The only problem is that in this case you have to do everything manually - keeping information about your vendors, sending files and instructions via email, taking care of maintaining translation quality and deadlines by calling vendors by phone, etc.<br />
<br />
To make your life simpler, couple of years ago, XTRF provided a platform to perform all of those tasks in one single system. Much faster and with better results.<br />
<br />
But there was still a lot of work that had to be done by translation Project Manager. Things like searching for vendors, scheduling dates of projects, and others.<br />
<br />
<h3>
<span style="color: #0b5394; font-size: large;">The real Core Domain</span></h3>
<br />
<b>The real game-changer in translation project management domain is automation.</b> I realized that about year ago, after I had crunched enough domain knowledge. </div>
<div>
<br />
The real Core Domain in that field is making automated decisions for translation project manager - so that she does not have to do anything, except for monitoring the progress.<br />
<br />
It took me some time to come up with this conclusion, but, as Alberto Brandolini stated once:<br />
<i>"Software development is a learning process. Working code is a side effect".</i><br />
<br />
So, the learning process took place and the side effect has been <a href="http://www.xtrf.eu/demo/" target="_blank">officially released</a>.<br />
Spread the word!</div>
<div>
<br /></div>
<div>
</div>
Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com3tag:blogger.com,1999:blog-1727031811590975354.post-47788698624971246152014-08-04T09:51:00.000+02:002014-08-04T09:51:09.976+02:00Help! I'm stuck with DDD Modeling! 8 Tips'n'Tricks to move on.I was sitting in front of my laptop with a bunch of paper cards scattered all around me. My desk and my windowsill were covered with printed scenarios on the one side and with handwritten sketches of couple of Models on the opposite one. On the monitor, I was browsing photos of previous Modeling sessions and, from time to time, chatting with my friend - an UX Designer.<br />
<br />
For last couple of days I was doing the Modeling of a very hard part of our Core Domain. I spoke to Domain Experts in different roles, and I was working closely with the UX Designer, who made a lot of research earlier. I run couple of Modeling sessions - both alone and in groups of 2-5 people. I just couldn't figure out a good enough solution.<br />
<br />
I was stuck.<br />
<br />
<h3>
<span style="color: #0b5394; font-size: large;">Do You know that feeling?</span></h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Y95jLB1vXRcLqJpdEUVhxBz6VuhQSpfXETLYFDJ0ytQTb3045AIzI_xNSCLJqU-SvrwiLJHDIjvdbkcnmP6uNRW2_uaXV3HwYWaFkSmHWMD_qIBeDsNNx_DmDOwGqopIzXKVylNGTuA/s1600/broken-bulb-medium.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Y95jLB1vXRcLqJpdEUVhxBz6VuhQSpfXETLYFDJ0ytQTb3045AIzI_xNSCLJqU-SvrwiLJHDIjvdbkcnmP6uNRW2_uaXV3HwYWaFkSmHWMD_qIBeDsNNx_DmDOwGqopIzXKVylNGTuA/s1600/broken-bulb-medium.png" height="400" width="267" /></a></div>
<br />
Have You been in that moment, when you realize, that sometimes Synthesis is not that easy part of the Design process? The moment, when you feel like You are trying to push on a rope? You've done everything correctly, and yet You still cannot find the solution...<br />
<br />
<b>I assume</b>, that You are a good scout, and You did Your homework.<br />
<ul>
<li>You have a Context Map somewhere,</li>
<li>You did some <a href="http://ziobrando.blogspot.com/2013/11/introducing-event-storming.html" target="_blank">Event Storming</a> (by <a href="https://twitter.com/ziobrando" target="_blank">Alberto Brandolini</a>),</li>
<li>You are focused on some specific Subdomain and have abstracted unimportant things,</li>
<li>You have some significant Scenarios in it,</li>
<li>You have some Models that fullfill some of those Scenarios,</li>
<li>You are actively using <a href="http://domainlanguage.com/ddd/whirlpool/" target="_blank">Modeling Whirlpool</a></li>
</ul>
<div>
<br /></div>
<div>
Everything looks good, but it seems like You can always come with another significant Scenario that will break some already created Models... You are clearly missing some concept and you need to do something different to stop spinning your wheels. </div>
<div>
<br /></div>
<div>
You need some...<br />
<br /></div>
<h3>
<span style="color: #0b5394; font-size: large;">Modeling Tips'n'Tricks</span></h3>
<br />
Enter the 8 Tips'n'Tricks that can help You to move on with Modeling activity. I already knew the first 7 and the last one was proposed to me by <a href="https://twitter.com/mathiasverraes/" target="_blank">Mathias Verraes</a> in the Twitter <a href="https://twitter.com/pwyczes/status/494770672422645760" target="_blank">thread</a>. Here You have it, you can take them and use in Your projects.<br />
<br />
<a name='more'></a><br />
<b>If You know any other trick, feel free to post it in the comments.</b><br />
<b><br /></b>
<br />
<h4>
<span style="color: #0b5394;">1. "Gibberish Game"</span></h4>
<div>
Sometimes you cannot agree on some concept with Your friend or You have a feeling that there is too much responsibility attached to one word. Or maybe the responsibility is distributed into couple of unrelated words. Or maybe the word that you are using to describe some concept has rotten and you need something more.</div>
<div>
<br /></div>
<div>
Just try to use completly unrelated word - some giber like "blah" - and use it in sentences to describe some related parts of the Domain. After couple of minutes you will see what true responsibilities are attached to that concept and naming them would be easier.<br />
<br /></div>
<h4>
<span style="color: #0b5394;">2. Paper documents</span></h4>
Ask Your Domain Expert, how would she do all the job, if there were no computer systems involved in the process. What kind of paper documents would she have, who would create them and who would process them. It helps to discover the Data Flow and connections between different actors of the Scenario.<br />
<br />
<h4>
<span style="color: #0b5394;">3. Sketch some UI mocks</span></h4>
<div>
You should ask for help Your UX Designer with this one - You know, that we, developers, are pretty bad at UIs... ;) Draw some simple UIs, and ask Your Domain Expert what data would she need on that screen, why would she need that screen and what kind of decisions to make based on that data. And the key question - where that data would come from.</div>
<div>
<br /></div>
<div>
Note: This one can be tricky, because it may lead You to Modeling application Features instead of true Invariants of the Domain.<br />
<br /></div>
<h4>
<span style="color: #0b5394;">4. Model the unknowing explicitly and proceed - aka "Here be dragons"</span></h4>
<div>
Sometimes You don't need to spend that much time in one place. There may be other parts of the Domain that require Your attention. If You feel like You stuck and this is not that important, try to surround that part with a fence, build some interfaces and put a picture of a dragon there. Then flee... ;)<br />
<br /></div>
<h4>
<span style="color: #0b5394;">5. Enter the Domain Expert role</span></h4>
Try to explain the problem to a third-party, non-technical and non-related to the business person. Then let her ask some questions. Magic can happen!<br />
<br />
<h4>
<span style="color: #0b5394;">6. Play with your subconscious mind</span></h4>
<div>
Do You know how Your brain works? Do You know why you have some great ideas and solutions under the shower? I won't go into details, You can find a lot of it on the internets, but sometimes it is good to let the biology do the job. Just keep asking Yourself the questions about Your problem and do not provide any solutions to those questions. At some unexpected time You may be enlightened - i.e. in the traffic jam. Keep a writing pad in Your pocket.<br />
<br /></div>
<h4>
<span style="color: #0b5394;">7. Drink some beer</span></h4>
<div>
This one is my favourite. But of course - not in your work time, not at your office, and definitely not in the traffic jam. :)</div>
<div>
<br /></div>
<h4>
<span style="color: #0b5394;">8. Remove all constraints</span></h4>
The last but not least - introduced to me by <a href="https://twitter.com/mathiasverraes/" target="_blank">Mathias Verraes</a>:<br />
<i>"Remove all constraints, model the simplest thing that has value, then add constraints back one by one."</i><br />
<i><br /></i>
<br />
<h3>
<span style="color: #0b5394; font-size: large;">Your Tips'n'Tricks</span></h3>
<div>
<span style="color: #0b5394; font-size: large;"><br /></span></div>
If You have any other Tips'n'Tricks, please post them in comments, so that more of us can use them and move on with their, lets call it "Synthesis Paralysis".<br />
<div>
<br /></div>
Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com4tag:blogger.com,1999:blog-1727031811590975354.post-28565840525923614332014-02-17T09:12:00.000+01:002014-02-17T09:12:25.948+01:00Well, hello @Mock - we meet again<div>
</div>
<div>
<span style="background-color: #cccccc; padding: 10px;"><b>tl;dr </b>Since I embraced Domain-Driven Design, I didn't have to use any mock.</span></div>
<div>
<br />
When
in 2011, during Java Developers Day in Kraków, Greg Young stated, that
he does not use mocks, I couldn't believe him. I mean, come on! How do
you test your code that is dependent on other parts of the code? I was
at the very begining of my journey with Domain-Driven Design back
then...<br />
<br />
Couple of days ago, I had to implement something in old
part of the system. This part was developed like most systems were
couple of years ago (and some are still) - with Anemic Entities and
stateless, so called "Services". I didn't want to refactor this whole
spaghetti around that place, so I decided to go with this anemic
approach and "just be good enough".</div>
<div>
<br /></div>
<div>
Since I am a big fan of Test-Driven Development (where it
is valuable), I decided to write some test for this service that I was
about to touch. Suprisingly, there was a test class for this service,
and there were even some not that bad unit tests there. Woohoo, lucky
me!<br />
<br />
I wrote first unit test, run - red of course - so I
implemented some simple solution - green - I added another test - red -
another simple solution - green - I refactored a little - green. Uncle
Bob would be proud!<br />
<br />
Then, the time has come to write some more complex case. I
realized, that I need some additional service to be injected into mine. It was clear to me, that I needed to mock that service in test,
so I wrote </div>
<div>
<pre class="brush:java;">@Mock
private AdditionalService additionalService;</pre>
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglY0thCNYPHO5zBzVzqgUSYtpBhI2yIUEXTsSXvMpmPCEK4rjoAiolbJHD8UdOiX2MwgSbKQZlwbXtpf7zI-KiIoOxsOxxKcJFVa3KHNpWV_DEcIvd3w3OdqEB5aeoZzyROorElkU7seg/s1600/gran-torino-clint-eastwood.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglY0thCNYPHO5zBzVzqgUSYtpBhI2yIUEXTsSXvMpmPCEK4rjoAiolbJHD8UdOiX2MwgSbKQZlwbXtpf7zI-KiIoOxsOxxKcJFVa3KHNpWV_DEcIvd3w3OdqEB5aeoZzyROorElkU7seg/s1600/gran-torino-clint-eastwood.jpg" height="195" width="400" /></a></div>
and it felt weird... :/<br />
<br />
I realised, that I haven't use mocks for a long time. I just didn't have to.<br />
<a name='more'></a><br />
<span style="font-size: large;"><span style="color: #073763;">Testing business logic</span></span> <br />
<br />
In Domain-Driven Design, you aim to model true
invariants. Your goal is to find boundaries inside the model and isolate
business logic from infrastructure. If you succeed, your business logic
is decoupled and highly cohesive. All additional things, that model may
require, should be injected from higher layer - Application Layer,
which is responsible for orchestrating domain scenario, but has nothing
to say about business logic.</div>
<div>
<br />
</div>
<div>
If you do proper modeling, you only want to unit test
business logic, which very striclty defines what is required at the
begining (Given), what action you perform (When), and what are the outcomes
(Then). It is very easy to instantiate small graph of objects (properly
designed Aggregate), and test it in isolation. You don't need to mock
anything. You just test the business logic.<br />
<br />
Of course, you do want to test Application Layer (to
check if everything is properly wired and so on), but then you do not
unit test it. There are higer level tests, that should be executed
against this layer - like acceptance tests. And then, you definitely do
not want to mock anything. :)<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Testing anemic models</span></span><br />
<br />
On the other side, in classic, Anemic approach, you
cannot achieve that. You just have "entities", which are in fact
database records, and services, that heavily execute setters and getters
on those "entities". Those services call other services, and those,
invoke even more getters and setters. There are no clear boundaries, the
coupling is high and cohesion is low.<br />
<br />
As you probably experienced that, this is a situation, where you
have large, unbounded graph of objects, without any encapsulation involved. You manually manipulate it in order to
perform some business logic. If you would like to test some logic, that
runs on top of some part of that graph, you need to either</div>
<ul>
<li>instantiate whole graph, which may be hard and expensive, or</li>
<li>instantiate the part, you need at the moment and mock the surrounding parts </li>
</ul>
<br />
<div>
<span style="font-size: large;"><span style="color: #073763;">This weird <span style="font-family: "Courier New",Courier,monospace;">@Mock</span> feeling</span></span><br />
<br />
We,
software developers, are very good at solving problems. On the other
hand, we are not so good at finding root causes of those problems. When
our graphs of objects grew, we didn't stop to ask why. The problem,
that occured was simple - we couldn't easily test them. So... We have found a
workaround - mocks! Easy workaround... Useful workaround... But
still... A workaround...<br />
<br />
Domain-Driven Design helped me to focus on the
question "why". Whenever I do proper modeling, I end up with design, that
does not require any mocks in order to be tested. That's why I felt
weird, when I had to use <span style="font-family: "Courier New",Courier,monospace;">@Mock</span>.<br />
<br />
</div>
<div>
PS.<br />
I still see the advantage, which mocks give us in some cases - like
dealing with legacy code, or some marginal, weird corner cases - but I may certainly say,
that I don't use them anymore, when I do DDD. I don't need to.</div>
<div class="yj6qo ajU">
<div class="ajR" data-tooltip="Pokaż skróconą treść" id=":t0" role="button" tabindex="0">
<img class="ajT" src="https://mail.google.com/mail/u/0/images/cleardot.gif" /></div>
</div>
Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com4tag:blogger.com,1999:blog-1727031811590975354.post-86756660785989087642014-01-02T09:38:00.001+01:002014-01-02T09:38:43.883+01:002013 summary - books, presentations, trainings, etc.At this part of the year, many people summarize their last twelve
months. So I will.<br />
<br />
This year was really busy for me. Especially the second part
(hence the lack of my activity on blog).<br />
Not to extend, here are the most important things that I achieved
this year, which changed my life, and will be affecting the next one
for sure.<br />
<br />
<div align="CENTER">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmU1G2tj__FkYCUy3HmQ3NYwmos2Jj0QpeYJMCeaH3mopUY1U-oBumW0c_iUQA966iqH-KtiwDEBG60IBozS_9oJBlIXs359IAvouoZG1GmMcP7VWKTiZ4QOEDOXFvjixHNgXQpibGzes/s1600/2013-summary.jpg"><img align="BOTTOM" border="0" height="300" name="graphics1" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmU1G2tj__FkYCUy3HmQ3NYwmos2Jj0QpeYJMCeaH3mopUY1U-oBumW0c_iUQA966iqH-KtiwDEBG60IBozS_9oJBlIXs359IAvouoZG1GmMcP7VWKTiZ4QOEDOXFvjixHNgXQpibGzes/s400/2013-summary.jpg" width="400" /></a></div>
<div align="CENTER">
<br /></div>
<span style="color: #073763;"><span style="font-size: large;">1. Books</span></span><br />
<br />
I read a lot of books this year, but there are three, that
affected me the most<br />
<ul>
<li><div style="margin-bottom: 0cm;">
<a href="http://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577">"Implementing
Domain-Driven Design"</a> by Vaughn Vernon - a must-read for
any Developer/Analyst/Architect/Whoever-builds-software - just after
Eric's <a href="http://www.amazon.com/gp/product/0321125215">"the
Blue Book"</a> (or maybe in the meantime). It clearly describes
what Domain-Driven Design is and how to implement it (duh, the
title). It also gives a little different view at Eric's definitions
- 10 years after his publication - and introduces new concepts, that
community added to DDD, like Domain Events.
</div>
</li>
<li><div style="margin-bottom: 0cm;">
<a href="http://www.amazon.com/gp/product/030746363X">"4
Hour Body"</a> by Tim Ferriss - this is not technical book at
all, but for me it was a game-changer. It is full of concrete ideas
how to master your body - loose weight, gain strength, sleep better
and so on. But the biggest thing was the idea to properly set
goals, measurements and persist in the way to achieve them. A lot
of technical or management people write about the same concepts, but
I was able to grasp them finally, thanks to Tim and this totally
different domain - human body.
</div>
</li>
<li><a href="http://www.amazon.com/The-4-Hour-Workweek-Anywhere-Expanded/dp/0307465357">"4
Hour Workweek"</a> by Tim Ferriss - after finishing "4
Hour Body" and achieving my goals inspired by it, I decided to
dig more into Tim's work - I bought his first book, and took it on
my vacation (I love reading on a beach). Tim also writes how to
settle goals and achieve them, but a little different kind of goals.
The idea of living your life right now and not waiting for
retirement is very tempting... and maybe even possible. I will
experiment and try some more tricks from this book in the upcoming
year.
</li>
</ul>
<br />
<a name='more'></a><span style="color: #073763;"><span style="font-size: large;">2. Presentations </span></span>
<br />
<br />
If you know me, then you probably are aware, that I am consuming a
lot of presentations from different conferences all around the world.
This is a very quick way to learn something new or to decide if I
want to dig into the topic more. I can watch presentation while I am
preparing something to eat and not loose time. We also watch some
presentations once a week in my team at work.<br />
<br />
This year, I watched A LOT of presentations, but there are two
that will have a big impact on my work in the future:<br />
<ul>
<li><a href="https://www.youtube.com/watch?v=8pTEmbeENF4">"The
Future of Programming"</a> by Bret Victor. Great idea, great
performance, and what is the most important - great message. There
is nothing new in IT... Everything was invented more than 30 years
ago. Now, we just rediscover all of those concepts for the second
time. Functional Programming, Actor model, Object-Oriented
Programming (I mean the real one, not the one that most of us is
doing on daily basis) - things like Clojure, Akka, tactical patterns
of Domain-Driven Design are all buzzwords right now, but principles
behind them are much older. We just need to go back to the roots...
<br />
</li>
</ul>
<ul>
<li><a href="http://vimeo.com/68327406">"Make Impacts, Not
Software"</a> by Gojko Adzic. I am pretty confident, that I can
build software right. On the other hand, I am pretty confident, that
I find it hard to build the right thing. Impact Mapping by Gojko
addresses that. He states that we should aim for measurable goals
(did he speak with Tim?) that will change people's behaviors. We
should prepare couple of alternative paths to achieve our goals,
find the simplest one and prove that it is correct in order to
proceed with something more time-consuming to build. Always be
focused on people's behavior change.
<br />
</li>
</ul>
<br />
<span style="color: #073763;"><span style="font-size: large;">3. Professional life</span></span><br />
<br />
This is a blog about IT and I am a Software Engineer, so I also had some success stories on that field.<br />
<ul>
<li><div style="margin-bottom: 0cm;">
I switched job - now I have more
space and can do the software right. My current employer likes to
learn as much as me, and the team is eager to do Domain-Driven
Design.
</div>
</li>
<li><div style="margin-bottom: 0cm;">
I started to learn Scala -
finished Martin Odersky's course on Coursera and it really messed
with my head. I do Scala after hours in my personal project and
maybe will release it in the first quarter of 2014.
</div>
</li>
<li><div style="margin-bottom: 0cm;">
I attended two technical trainings
- one of them was IDDD Tour Poland - led by <a href="https://twitter.com/VaughnVernon">Vaughn
Vernon</a> with great help of <a href="https://twitter.com/ziobrando/">Alberto
Brandolini</a>. The second one was sponsored by my current company
and was led by Sławek Sobótka.
</div>
</li>
<li><div style="margin-bottom: 0cm;">
I contributed to IDDD Tour Poland
- 4-day long workshop about Domain-Driven Design. I helped to
organize it a little, and spoke about Axon Framework during one of
the evenings.
</div>
</li>
<li><div style="margin-bottom: 0cm;">
I started <a href="http://www.meetup.com/DDD-KRK/">Domain-Driven
Design in Kraków (DDD-KRK)</a> meetup - a community that is
gathered around Domain-Driven Design and meets regullary every first
Tuesday of a month.
</div>
</li>
<li><div style="margin-bottom: 0cm;">
I gave lectures at 4 big
conferences in Poland - 33rd Degree, GeeCON, 4Developers and Java
Developers Day. I was speaking about Domain-Driven Design, Command
Query Responsibility Segregation, Event Sourcing, and Axon
Framework.
</div>
</li>
<li>And last, but not least - my friend asked me to give some
training about DDD in his company and after some reluctance, I
finally managed to say "OK, let's do it". So in December I
gave the very first, 2-day-long, training on DDD by me. I received
very positive feedback, so probably will do something with it, in
the next year.
<br />
</li>
</ul>
<br />
<span style="color: #073763;"><span style="font-size: large;">4. Personal life</span> </span>
<br />
<br />
I won't go much into details of my personal life, but there are
two things that I can share and I am happy about them.<br />
<ul>
<li><div style="margin-bottom: 0cm;">
I've lost 10kg in 2 months -
without any workout, while tasting beer at evenings. Probably
without those beers, I would loose it in 1 month, as Tim states in
his book - "4 Hour Body" (see above). Thanks to that I was able to do
some small subset of tricks, that I used to perform, when I was
younger (see the picture). I experienced so called "Minimum
effective dose" on my own, and I think, that this single
achievement will have more influence on my personal and professional
life in the future.
</div>
</li>
<li>I traveled more than ever this year. I visited two seas and
an ocean. I spent some time on continent and on tropical islands. I
experienced 9-hours-long flight and finished one book during that
time. I also took some days and went to the mountains, which I
haven't done for a while. I also bought a bike and started cycling
during the summer.
<br />
</li>
</ul>
<span style="color: #073763;"><span style="font-size: large;">What's next?</span></span>
<br />
<br />
Next is 2014 and, after some mindset changes that I experienced
lastly, I think, it will be a really great year.<br />
I wish that for myself and for all of you!<br />
Happy New Year!<br />
<br />
<br />
<br />
<div style="margin-bottom: 0cm;">
<br /></div>
Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-18455179757714233522013-06-10T11:37:00.002+02:002013-06-10T11:37:55.477+02:00Do your aggregates touch each others' private parts?Most of current programming languages support <a href="http://en.wikipedia.org/wiki/Access_modifiers" target="_blank">access modifiers</a>.
I cannot imagine any contemporary language, which would not allow the
developer to protect access to classes, methods, fields, or functions.
Without them, we would not be able to maintain abstractions and
encapsulation.<br />
<br />
<div style="text-align: left;">
In Java, there are four modifiers: <i>public</i>, <i>protected</i>, <i>default</i>, and <i>private</i>, in C# there is additonal concept of <i>internal</i>, which reffers to assembly, and in Scala, there are possibilities to fine-tune the scope with <i>scoped private</i> and <i>scoped protected</i>
modifiers. Other languages, like C++, or F# for instance, also give us
some possibility to modify access. They may vary from language to
language, but the idea is the same - to protect parts of the code.<span style="font-size: x-small;"><br />(Actually, in C++ there is also a concept of <i>friend</i>, so that other class can get some <i>private </i>access to another class - hence the comment, that in C++ friends can touch each others' private parts... ;) )</span></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyjFVFc5PwmscQcham42z2ZwMO34NPBaX9d8CaAXvK7wb64aB-Bxko7qp9G9SoB7RiNtxw9KaamjPeiCPBS3ML0TMkP5nt5KUSYCcOmVspYblSPCSturAWLZZrN-qC46XIIO_Cbubq2Wk/s1600/private-no-public-medium.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyjFVFc5PwmscQcham42z2ZwMO34NPBaX9d8CaAXvK7wb64aB-Bxko7qp9G9SoB7RiNtxw9KaamjPeiCPBS3ML0TMkP5nt5KUSYCcOmVspYblSPCSturAWLZZrN-qC46XIIO_Cbubq2Wk/s400/private-no-public-medium.jpg" width="540" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
Looking
from the time perspective, I can observe certain regularity. The
default modifier (usualy without any keywords) tends to be more <i>public</i> for younger languages. By this I mean, that default access in older languages (like C++) was ment to be <i>private</i>.
In Java, which is a little more modern language, when You use no access
modifying keyword, You will be able to access that code from the
package. And finally, in very young languages like Scala (and in F#, I
believe), no access modifying keyword means, that the code is <i>public</i>. Why is that? I do not know. I can only guess, but I personally like the Scala way.<br />
<br />
OK, let's go back to Domain-Driven Design...<br />
<br />
<a name='more'></a><br />
<span style="font-size: large;"><span style="color: #073763;">Aggregate </span></span><br />
<br />
An
Aggregate in DDD, from the code perspective, is a tactical pattern
which allows to organize certain functionalities and state, that belong
together. It's main responsibility is to protect invariants and hide
internal structure. This is a very powerfull modeling tool, but
unfortunately the hardest to grasp.<br />
<br />
Aggregate is a
graph of objects (or functions) tightly connected to each other. This
graph is very cohesive and can be accessed from the outside world only
through one defined point - it's root. The Aggregate Root is an Entity
that acts as this root. It has globally unique identity, and provides
API for communicating with the whole Aggregate.<br />
<br />
It may
contain some Entities and Value Objects. Entities have unique identity
inside that Aggregate only and are not supposed to be shared between
Aggregates. Value Objects on the other hand, may be shared between
Aggregates, or may belong to one particular Aggregate only. I will refer
to the latter as Internal Value Objects for the purpose of this blog
post. <br />
<br />
Since Value Objects, which are shared in the
Model with other Aggregates, are not very exciting from this blog
post's perspective, we will leave them for now. More interesting are
Entities and Aggregate's Internal Value Objects, since they are not
visible outside of the graph. Furthermore, if they are so tightly
coupled, they should be located in the same package, right?<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Entities</span></span><br />
<br />
Let's
face this - huge majority of software is currently being written with
Anemic Model - especially in Java world. By Anemic Model, I mean a
model, where so called "entity" with a bunch of properties has only
getters and setters. Some people even dare to name that encapsulation...
I will let that pass... ;) Those "entities", which are actually SQL
database records, are mutated back and forth in some Services, or in
GUI, or wherever our imagination lead us.<br />
<br />
In
Domain-Driven Design, Entities mean much more. They have their behavior,
which is visible to the whole Aggregate, and they actually need
encapsulation. That is why we keep their state <i>private</i> and expose
only significant methods to the Aggregate graph. We should not be able
to access their methods from the outside of the Aggregate. We do not
allow to call them directly.<br />
<br />
Or do we?<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Protecting Entites</span></span><br />
<br />
Well...
I have not seen any code, where Entities and Internal Value Objects
were actually protected from illegal access. Maybe some DDDesigners take
care of that, but I didn't spotted any yet... Anyway, we got used to
anemic entities so much, that we write this "<i>public</i>" keyword before each class definition, regardless if is supposed to be Aggregate Root or normal Entity.<br />
<br />
Without
protection, there is no guarantee, that somebody in the future will not
construct new instance of some Entity without any Aggregate Root. And
it will cause inconsistency. There is also another threat. Somebody may
expose Aggregate's state to the GUI. It may not be that dangerous, but
again - there is no guarantee, that somebody will not call Entity's
methods outside of the Aggregate, causing inconsistency once more.<br />
<br />
As
I wrote before, all Aggregate's classes (and functions if any) should
be located in one package. They are tightly coupled and should be
distributed and accessed together. What is more, the only possibility to
access the Aggregate is through the Aggregate Root, which, for
protection, should be the only <i>public</i> class in the Aggregate's package.<br />
<br />
Of course You may have a lot of small Aggregates, which do
not have any Entities beyond the Aggregate Roots. In that case, You should
not create a package for each of them, but it is definately worth to
consider how the model will grow.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">The rule of thumb</span></span><br />
<br />
So, to summarize - to protect Your model (and Yourself), think about the following rule of thumb, which I created for myself:<br />
<br />
<blockquote class="tr_bq" style="background-color: #eeeeee; padding: 10px;">
Each
Entity (which is not the Aggregate Root) or Value Object (which is not
accessed outside of the Aggregate) should be accessible only by objects
inside of the Aggregate itself, therfore their classes should be located
in the same package and have <i>package private</i> access modifier.</blockquote>
And how do You protect Your Aggregate's internals?<br />
<br />
<br />
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com4tag:blogger.com,1999:blog-1727031811590975354.post-89325337552462019342013-04-23T10:38:00.000+02:002013-04-23T10:38:19.958+02:00Domain-Driven Design in KrakówThe beautiful thing in IT world is, that people are willing to share
their knowledge. That's why we write blogs, speak at conferences and
form local communities.<br />
<br />
There are already couple of
such communities in Kraków. Sometimes I think, that this city is really
the Sillicon Valley of Poland (and maybe even of this part of Europe).
There is <a href="http://www.meetup.com/sc-krk/" target="_blank">SCKRK</a> (Software Craftsmanship in Kraków) for software craftsmen, there are many <a href="http://www.meetup.com/Polish-Java-User-Group/" target="_blank">PJUG </a>(Polish Java User Group) meetings for Java people, <a href="http://kgd.net/">KGD.NET</a> (Kraków's Group for Developers .NET) for .NET people, <a href="http://www.meetup.com/Lambda-Lounge-Krakow/" target="_blank">Lambda Lounge</a> for functional languages enthusiasts, <a href="http://www.meetup.com/Bright-Talks/" target="_blank">Bright talks</a>, <a href="http://www.meetup.com/Krakow-Scala-User-Group/" target="_blank">Kraków Scala User Group</a>, <a href="http://www.meetup.com/datakrk/" target="_blank">DataKRK</a>, <a href="http://hackerspace-krk.pl/" target="_blank">Hacker Space</a>, <a href="http://www.meetup.com/JARCamp/" target="_blank">JAR Camps</a> and many others.<br />
<br />
If you are in Kraków, you can always check what is going on today and come to learn and share some knowledge.<br />
<br />
On
the other hand, there are communities around the world, which are about
Domain-Driven Design in particular. The other day I thought, that maybe
we can do something similar in Kraków... My current company really
liked the idea and decided to become a sponsor - so here we are:<br />
<br />
<a href="http://www.meetup.com/DDD-KRK/" target="_blank">DDD-KRK - meetup for Domain-Driven Designers in Kraków</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.meetup.com/DDD-KRK/" target="_blank"><img border="0" height="300" src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Krak%C3%B3w_-_Drzwi_do_Katedry_na_Wawelu_01.JPG/800px-Krak%C3%B3w_-_Drzwi_do_Katedry_na_Wawelu_01.JPG" width="400" /></a></div>
<br />
<br />
We
are going to meet once a month - the plan is to make it always the
first Tuesday, but the very first meeting was another day and the second
will also be on different day. :) I received many wishes and
congratulations from other communities in other cities. Thanks for that!<br />
<br />
For
the first meeting I prepared a presentation about introduction to DDD,
and then we started a discussion about business value of it. I hope
people enjoyed it. There are some photos on the event page.<br />
<br />
The
second meeting is going to be really great. At May 6th-9th there will
be Implementing Domain-Driven Design workshops with Vaughn Vernon in
Kraków. After the last day (Thu) we will have DDD-KRK meeting and Vaughn
with Alberto Brandolini decided to give some talks to the fresh formed
community. Again, thanks for that!<br />
<br />
So... If you are
reading this and you know something more about DDD, and you are willing
to share your thoughts, and... you know you will be in Kraków someday,
do not hesitate to contact me, and we will figure out how to find you
some audience. ;)<br />
<br />
If you are not that familiar with DDD yet, but you are willing to dig into the topic, join our community - <a href="http://www.meetup.com/DDD-KRK/" target="_blank">become a Domain-Driven Designer</a> and participate in our meetings. Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-44520851681155301402013-03-22T09:38:00.000+01:002013-03-22T09:38:29.984+01:00My 3 cents on 33rd Degree 2013 ConferenceLast week I attended, for the third time, the <a href="http://2013.33degree.org/" target="_blank">33rd Degree Conference</a>.
This time I had an opportunity to give a talk by myself, so I was able
to take another look at the event. I met some old friends and some new
people too. I listened to inspiring talks and to couple of boring too.
We also had some great talk till the late night at the first day. This
was a good event. I only lack some party, like the one, that for
example, usually during <a href="http://12.jdd.org.pl/" target="_blank">Java Developers Day</a> takes place.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgGRZfU1TI0JTMgdC4jYXQXQ3IHPAU-9fwMUgLy74ktVpktaxut3b8wOylU01dYYdf5kwR2bFjYIPNaDKkMwFEMg4NtV6NNkcqLYEnMeHORF40CaJUeYQKuhmnT-28OFfzwY0ZQaGSeRY/s1600/duke-with-guitar.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgGRZfU1TI0JTMgdC4jYXQXQ3IHPAU-9fwMUgLy74ktVpktaxut3b8wOylU01dYYdf5kwR2bFjYIPNaDKkMwFEMg4NtV6NNkcqLYEnMeHORF40CaJUeYQKuhmnT-28OFfzwY0ZQaGSeRY/s1600/duke-with-guitar.png" /></a></div>
<br />
As the <a href="http://www.eventuallyinconsistent.com/2012/03/my-3-cents-on-33rd-degree-conference.html" target="_blank">year ago</a>, I decided to give some <b>subjective</b>
marks for each presentation. And by subjective I mean, that notes were
taken only be me, according to my perception, my knowledge and my sense
only. There was nothing personal in them, so please treat them
appropriately. :) <br />
<br />
<a name='more'></a><br />
<span style="color: #073763;"><span style="font-size: x-large;">The first day</span></span><br />
<br />
The
very first talk was given by Sven Peters from Atlassian. He started
with many truisms (money do not motivate, etc.) and I was afraid, that
he will continue in that manner. Fortunately, he depicted seven ideas
how to improve software teams and even rated them in scale of
feasibility and awesomeness. After all I decided to start with the
middle mark: <b>3/5</b>.<br />
<br />
The next talk was from Dan
North and I was very eager to see him in action. Dan gave very
interesting presentation about... "It depends" :). He was showing some
possibilities and their alternatives - like for example - when to use
TDD, or when not to, or design monolith application, or component-based.
He was very clear about circumstances when use particular concepts that
he mentioned. His main point was "get more options", which I fully
support. That is why I decided to give it the best mark: <b>5/5</b>.<br />
<br />
The
third talk that day was given by Ted Neward and he was talking about
iconoclasm. He gave some examples when people were losing with machines
and then stated that most of our jobs will be replaced by computers.
That is why we need to look from different perspectives - be the man
with an idea. From my point of view, Ted was repeating himself and his
talk was extended a little bit, so some people came out ahead of time
for lunch. The one cool thing from his talk was that each and every
software architecture can be depicted as a box next to another box and
next to cylinder, and whenever somebody introduces another box, or
cylinder, it messes up with people's minds. That is exactly what I can
see, when I talk about CQRS for instance. Anyway, there were some good
and some bad things in that talk, so I decided to give it <b>3/5</b>.<br />
<br />
And
then was the lunch... The food was really tasty, but for heaven's sake -
why this band started to sing so loudly? I couldn't hear my friend, who
was sitting right next to me... And they tried to make us clap during
the meal... And they didn't want to stop when there was absolutely no
response. I appreciate the idea of music during the lunch, but next
time, please choose the <span class="short_text" id="result_box" lang="en"><span class="hps">repertoire and volume more carefully...</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">After
the lunch, the schedule was separated into six tracks. I chose to see
Steffen Krause's talk about Amazon Web Services (AWS). At the beginning
he started with some resources charts. He also tried to give us the
impression, that almost each great company uses AWS, by showing a lot of
logos and spending too much time on them, in my opinion. It could work
well on managers, but I didn't take it. The second part was more
interesting and Steffen showed some AWS availabilities, like scaling,
replicating against many datacenters, Elastic Beanstalk, or Elastic
Black Store. After all I decided to give it the mark <b>3/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
next talk, I attended, was again from Dan North and this one was about
patterns of effective delivery. The very first thing, that Dan outlined
was that patterns work only in a context. Then he presented (among
others) such patterns as "light saber", which is about building
something known from scratch, or "burning ships", which is about
creating deadlines artificially. He also said that learning is the best
when it is needs-driven. I really enjoyed his talk, but it was less
inspiring than previous one, so my mark was <b>4/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">After
short break I decided to see Sławek Sobótka's talk about tests. As
always, Sławek prepared great presentation, which was very carefully
structured and he touched many topics, like software patterns,
Domain-Driven Design and architecture. I had a feeling, that sometimes
there was too many topics mentioned and some people were left behind. On
the other hand, it allowed to look from different angle at testing - in
more holistic way. The most important thing that I took from this talk,
was that tests structure should be in correlation to system
architecture. In the end it was <b>4/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">This
was the last presentation in regular time - there was also one timeslot
reserved for BOF (buffer overflow) talks. I was hoping to attend one of
the presentations, but then the beer arrived and I started to talk with
some of my friends. And so we talked and talked and we finished at 2am
at night... Great evening. :)</span></span><br />
<br />
<span style="color: #073763;"><span style="font-size: x-large;"><span class="short_text" id="result_box" lang="en"><span class="hps">The second day</span></span></span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
very first talk I chose was again about delivery. Baruch Sadogursky was
talking about developing for multi component environment. At the
begining he started with some frameworks and then he moved to talk about
configuration and integration management, which can be run by Chef.
Then on a higher level there can be used Vagrant, which uses Oracle's
Virtual Box, and then on an even higher level there should be some
Continues Integration tool, like Jenkins to run all of it. He stated
that environment should be stored in source control system. Since, for
me, it was really low level topic, I decided to start that day with <b>3/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
second talk I attended was again from Sławek Sobótka. This time he was
talking about modelling techniques taken from Domain-Driven Design. I
always can learn something new from Sławek, so despite I know something
about DDD, I decided to listen to him, and I wasn't disappointed. Sławek
showed some tools for finding the useful model. The most important
thing for me was that if a single domain expert knows pretty much
everyting, then this might be a smell. I learned something useful, so
mark couldn't be different than <b>5/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The third talk was very boring and I had to leave it. I decided to go on the side and polish my talk.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">Then,
after lunch (without the band) there was Venkat Subramaniam's talk
about lambdas in Java 8. I have heard some time ago a funny sentence
that lambdas got so popular thanks to Java, because this is the only
modern language, that doesn't support them. And this is sadly true. In
Java 8 this will change. There are java.util.function.* and
java.util.stream.* packages that will introduce lambdas and utils for
them. Venkat was showing basics of them by writing the imperative code
at the begining and then in a very nice way, step by step, was changing
it into functional. I really enjoyed his presentation, but the topic
wasn't conceptually new for me, so I decided to give it <b>4/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
next talk was from Oliver Gierke from Spring and he was talking about
Spring Data. I knew already about the project, and I used it
succesfully. I even coined the term "<a href="http://www.eventuallyinconsistent.com/2012/04/convention-over-implementation-with.html" target="_blank">Convention over implementation</a>"
some time ago. I just wanted to see what other cool stuff is in the
project. Oliver showed basics of repositories with some running code,
but unfortunately I knew about most of it. The only new thing was the
Eclipse's plugin, which allows for easier interfaces declaration and
validation using Spring Data. In the end I had to give the mark <b>3/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">After
short break I attended Henrik Engström's Akka presentation. I was
interested in the topic, because Akka's actors model can be used as a
tool for modeling Domain-Driven Design's Aggregates. An actor
encapsulates state, behavior and message queue, so it should fit quite
well. Unfortunately I attended Henrik's talk during the last ScalaCamp
in Kraków, so I saw this presentation from Scala point of view. I wanted
to see differences between Scala's and Java's Akka implementation.
There are not so many, so it was basically the same presentation. That
is why I decided to give it <b>3/5</b>.</span></span><br />
<br />
<span class="short_text" id="result_box" lang="en"><span class="hps">The
next talk was from Katrin Hippler and the abstract looked quite
interesting. It was about freelancing and entrepreneurship in general.
The topic was cool, but unfortunately the talk was just a sponsored
speech, and it was not very illuminating nor entertaining. I decided to
give it a mark <b>2/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
last talk that day was given by me, and it was about DDD/CQRS/ES in
practice with Axon Framework. For the first time I saw so many people
that heard about Domain-Driven Design, Command Query Responsibility
Segregation and Event Sourcing in one room. That was pretty amazing.
Thanks for everybody who came, listened and gave me some feedback
(positive and negative, both). Because of that I will be able to polish
my talk and my skills. Thanks again. :)</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">In
the evening I was invited to the speakers dinner. I enjoyed it, but I am
a little affraid about Java future, since I heard when some of our Java
trendsetters started to rhapsodize about Powermock... ;)</span></span><br />
<br />
<span style="color: #073763;"><span style="font-size: x-large;"><span class="short_text" id="result_box" lang="en"><span class="hps">The third day</span></span></span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
third day started with Michał Bartyzel's talk about X-Driven Design and
Y-Driven Development and why those "mental frameworks" won't change
anything. I must admit, that I was sharpening my claws for this talk,
since the abstract clearly shown that the presentation is going to
abolish, among others, DDD (actually in the abstract that was on the
first place). I listened carefully to Michał during presentation, and I
must admit - he was right in stating, that we must concentrate on
solving business problems and we must develop ourselves to gain
necessary experience. Big plus for that. Really. But... there was other
side of the coin - Michał was talking a lot about things, that in my
opinion, he didn't understand, or at least understood only partially.
This is a common issue with DDD - you get the Building Blocks part and
then you think you get the whole DDD concept. Bam! You forget about
bigger picute, and Strategic Design for instance. Don't get me wrong -
there is no problem with that - this is a normal part of learning DDD,
but... that is ok until you start to criticize it in public. The funny
thing was that, what Michał was proposing as opposite to DDD, was in
similar way described by Eric Evans in his book - but again, as they say
- The Blue Book needs to be read at least three times to get it right.
;) I don't blame Michał, there were a lot of clever thoughts in his talk
which I applaud, but you cannot speak in public without understanding
what you are criticizing - that is because people will listen to you and
follow those wrong paths. I would like to give a higher note, but I
can't, so here it goes: <b>1/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">After
that I chose to listen to Oliver Gierke again and this time he was
talking about architecture and why it decays after some time. The main
thing that he stated was, that we are slicing our architecture always
into 3 horizontal layers, which is purely technical approach. Instead we
should try to slice it into vertical slices, which should respond to
business concepts, and then slice each of them separately into 3
horizontal technical layers. This is similar to what DDD is about, so I
really enjoyed the talk. I decided to give the talk a mark of <b>5/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">That
was the end of the multi-track part of the conference. The two
following presentations were given for all attendees. The first was from
Venkat Subramaniam and he was talking about rises and falls of empires.
He was talking about some historical facts, and he was showing the
analogies to software industry. He stated that right now we have a
renaissance of programming languages. He was talking about big changes
in history and big changes in software development world. His talk was
really inspiring and two main statements were to be remembered. The
first one was directed to young developers: learn where you came from,
and the second one was directed to experienced developers: check to see
if we haven't turned into resisters already. I really ejoyed this talk,
and in my opinion it should be the last talk of the conference. Totally <b>5/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">Unfortunately
it wasn't... The last talk was from Hadi Hariri, and his talk was
titled Developers: the Prima Donna's of the 21st century. I have never
heard Hadi before, but I think I will not be eager to see him again.
Sorry. His talk was just boring. He talked about too many things, that
were loosely coupled. He stated many times that we, as developers, are
loosing focus. Well... I think, that Hadi lost his focus at the very
begining of his talk. And in the end - how many times we can analyze bit
by bit The Agile Manifesto? Come on... The closing talk of the 33rd
Degree conference got mark <b>1/5</b>.</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps"><span style="color: #073763;"><span style="font-size: x-large;">Summary</span></span></span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The average mark of presentations was <b>3,37/5</b>,
so lower than the last year. The good part was that there were many
people, which I talked to, between presentations and in the evenings. It
was a real pleasure to meet all of you. :)</span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">The
venue was much bigger, and there were more space for socializing. I
also should mention the food, which was delicious. Whole organization of
the event was perfect and there were no problems with anything, so I
want to thank organizers for their work. Thank you. </span></span><br />
<span class="short_text" id="result_box" lang="en"><span class="hps"><br /></span></span>
<span class="short_text" id="result_box" lang="en"><span class="hps">We should meet next year.</span></span>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com3tag:blogger.com,1999:blog-1727031811590975354.post-6120893766961877252013-02-05T08:57:00.000+01:002013-02-05T08:57:06.032+01:00Axon 2.0 releasedIn the CQRS world people don't like frameworks. People like to
concentrate on the domain and on customer's problems. This is really
great, but in the end you have to write some code to handle command,
load aggregate, or save and dispatch events. Long story short, you need
an infrastructure.<br />
<br />
Although it is not that hard, to
write this code, it is still the code that has to be written, tested,
and maintained. There can also be some tricky places - especially if you
have to distribute the system, or implement sagas. So, why bother with
that, if we can take someting of the shelf, and just use it in our
system? If the framework does his job, is flexible and does not deny
things that we need, I would recommend to use it. It allows us to
concentrate on the business problem. Of course, if you use the right
tool for the job.<br />
<br />
I mention that, because there was a major release of <a href="http://www.axonframework.org/">Axon Framework 2.0</a> couple of days ago. This is a Java open-source framework for CQRS and/or Event Sourcing based applications, but not only. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.axonframework.org/"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOlKygn4EMWTDVshkCz3N61I6uM61KXLax6H3tlha8c_Xn8wgWoVVp1BOfxHzbmP2A5YsArRd_CXRAQD-MG2KjBDrJy1Im9z7FwQrnb9SMj-3j5mhfM0OF_jGVWw69PCfFD-TuMZVL-e8/s1600/axon-logo.png" /></a></div>
<br />
<span style="font-size: large;"><span style="color: #073763;">What we can find in Axon 2.0?</span></span><br />
<br />
I
have been using Axon 1.3 with success, and it really helped me with the
infrastructure. In the 2.0 version, there are some improvements, which
can make this framework even more usable. The new version has added
easier API, performance improvements, out of the box scalability
support, and MongoDB-based event store implementation.<br />
<br />
Let's take a closer look at the framework capabilities.<br />
<br />
<a name='more'></a><br />
<span style="font-size: large;"><span style="color: #073763;">Commands </span></span><br />
<br />
<b>Commands </b>are messages that are sent to a system with an intent of doing something. They are sent to a <b>Command Gateway</b>, and then a <b>Command Bus</b> dispatches them to concrete <b>Command Handlers</b>. There can be some validation, or security check done in some <b>Interceptors</b>. The Command should be executed in some <b>Unit of Work</b>,
which can be implemented over database transaction. Additionally
Command processing may be distributed across many nodes with JGroups.<br />
<br />
Axon
provides interfaces, implementation and annotations for each one of
those concepts. You just need to write your Command classes, and simple
Handler classes with one annotation and that's it.<br />
<br />
There
are some default Interceptors already written - like Interceptor for
JSR 303 Bean Validation. If you need, you can easily write your
Interceptor by implementing one simple interface.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Events</span></span><br />
<br />
As
stated before, Commands are messages with intent of doing something. On
the other hand, after this something is done, another messages can be
produced as a result - <b>Events</b>. They represent a fact.<br />
<br />
In
Axon, you just need to write your own Event classes. All the
infrastructure that is responsible for handling them is there for you.
In previous version (1.3) you had to extend base Event class - in
current version (2.0) you don't have to do it anymore. Because of that,
you can use your Events to integrate with other, non-Axon-based systems
easily.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Domain</span></span><br />
<br />
You should model your domain very carefully. This is the place, where the <a href="http://en.wikipedia.org/wiki/Essential_complexity">essential complexity</a> lays. There are no frameworks that can help you with that. You should spend most of your time in that place.<br />
<br />
Thanks
to Axon, you can actually do it that way. All the infrastructure code
is there for you. The one thing that Axon gives you to help you
struggling with the domain modeling is base <b>Aggregate Root</b> class, which you can extend and get access to some useful methods.<br />
<br />
In the end, if you are using Event Sourcing, you can use <b>Abstract Annotated Aggregate Root</b>
and use annotations on your private methods, that are applying events
and changing the state of the Aggregate. Axon will additionally dispatch
Events to annotated Entities in the Aggregate.<br />
<br />
You
should not change the state of the Aggregate in methods that are not
reacting on Events. This is normal in Event Sourcing. Axon guards you
not to violate this principle, so an inexperienced person won't break
anything.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Repositories</span></span><br />
<br />
Aggregates are stored in <b>Repositories</b>.
You should be able to load Aggregate by id, and save it back. It
doesn't matter if you are using SQL database, flat files, or other noSQL
solution. The persistance technique should be separated from the
concept.<br />
<br />
Axon gives you this separation. You can choose
to use classic JPA-based Repository, or Event Sourced Repository. It
additionally adds possibility to use caching for performance tuning.<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Event Stores</span></span><br />
<br />
If you choose to use Event Sourcing, you need to store effectively your Events in some <b>Event Store</b>.<br />
<br />
Axon gives you an interface for Repository, and a couple of implementations. The simplest implementation is based on<b> flat files</b>, but it is not that powerfull as others. You can also use <b>JPA-based Event Store</b>,
which will create only two tables - for Event entries and for Aggregate
Snapshot entries. For those two solutions, you will need to serialize
your Events. Axon by default uses XStream, but you can choose any other.
The third Event Store is implemented over <b>MongoDB</b>. If you need, you can easily implement any other Event Store on your own.<br />
<br />
When your Aggregates live for a very long time, they can have a quite long history. For performance reasons you can use <b>Aggregate Snapshotting</b> to shorten the time of Aggregate loading.<br />
<br />
Your Events definition may change over the time, so those Event Stores by default give you a possibility to easily write <b>Event Upcasters</b>. It also gives you a support for some advanced conflict resolution when it happens. <br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Event Bus</span></span> <br />
<br />
In CQRS, after Events are generated, they need to be processed to update the query database. They are dispatched to <b>Event Handlers</b>. Those Event Handlers can be located on the same machine, or distributed in a cluster.<br />
<br />
In
Axon you just need to annatote methods of components that are supposed
to listen for Events. You can also choose if you want to process Events
synchronously, or asynchronously.<br />
<br />
If some error occurs,
you can define how to react. Axon can rollback transaction if you are
using any, or it can reschedule the Event and process it again after
some time for you. If you need any other error handling procedure, you
can write it on your own by implementing simple interface. <br />
<br />
If you have distributed environment, Axon gives you support for Spring AMQP.<br />
<br />
Sometimes you need to replay historical Events, and Axon also gives you the support for doing that.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Sagas</span></span><br />
<br />
Sometimes
your transactions need to live longer. You cannot always finish all the
work you need in a single ACID transaction. That is where <b>Sagas</b> come into play. On the other hand, you can use Sagas as a <b>Workflow</b>, or <b>State Machine</b>.<br />
<br />
In Axon, Saga is a special Event Handler that handles the long business transaction. You can use <b>Abstract Annotated Saga</b> as a base class for your Sagas and then just use annotations on your methods that handle Events.<br />
<br />
If you need to take care about time, or deadlines, Axon provides Sagas with <b>Schedulers </b>that can handle time management. You can use <b>Simple Scheduler</b> that uses pure Java implementation, or <b>Quartz Scheduler</b> that is much more powerfull.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Testing</span></span> <br />
<br />
You
should test the code that you write, right? You can do it in a normal
way, with mocks, or something like this, but if you are using Event
Sourcing, you have another possibility. You have a history of Events,
then you execute some Command, and a bunch of Events is generated as a
result. You can test exactly that way with Axon.<br />
<br />
Axon gives you a <b>Given When Then Fixture</b>.
As Given you specify historical set of Events, as When you specify a
Command that is tested, and as a Then you specify full set of Events
that are supposed to be generated. Everything is wired for you, and you
just need to define test scenario with those Events and Command.<br />
<br />
Of course, you should also test your Sagas. There is a special <b>Annotated Saga Test Fixture</b>
for that. As Given you specify a set of historical Event, as When you
specify a single Event, and as Then you specify a desired behavior, or
state change. If you need, you can also mock the time for testing
time-related Sagas.<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Spring support</span></span> <br />
<br />
Those
days, each mature framework in Java world should have some sort of
Spring support. Each of Axon's components can be configured as a Spring
bean. Axon provides also a <b>namespace shortcut</b> for almost everything it has, so the configuration is as short as it has to be.<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Conclusion</span></span> <br />
<br />
Often
you can hear, that frameworks are bad, because people tend to focus on
them and not on the business. I agree. But on the other hand, there is
always some infrastructure code that has to be written to support the
code, that is dealing with business logic. So why not to take framework
of the shelf and just use it? Especially if this framework saves you so
much work and is not very invasive.<br />
<br />
I highly encourage you to try it. You can find it here : <a href="http://www.axonframework.org/">http://www.axonframework.org</a> <br />
<br />
In the end, from my side, I would like to thank creators for such a great work!<br />
Thank you.Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com2tag:blogger.com,1999:blog-1727031811590975354.post-61888342327783935182012-12-11T10:58:00.000+01:002012-12-11T10:58:19.714+01:00Speaking experienceBeen a long time since I last blogged. There were many things happening, which were pulling me away from writing.<br />
<br />
One of those things was an opportunity to share my thoughts with a wider group in public. Recently I gave two talks - one in my company, and a second during <a href="http://www.meetup.com/Polish-Java-User-Group/events/90655552/">JavaCamp #11</a>. The second one was filmed and you can watch it below (in polish).<br />
<br />
The topic was <b>"Changing the mindset - more object-oriented view at the business domain modeling"</b> and it was based on my series of previous blog posts (links below). I briefly introduced audience into Domain-Driven Design, Command Query Responsibility Segregation and Event Sourcing concepts.<br />
<br />
The main thing in my presentation however, was to show how developer's mindset is changing when meets those contemporary techniques. I wanted to <span class="short_text" id="result_box" lang="en"><span class="hps alt-edited">emphasize what questions she starts to ask and what things are becoming more important while she goes step by step over this "rope bridge".</span></span><br />
<br />
Both speeches were well recieved, I think. :) Thanks to all listeners for your time and great discussions during and after the presentation.<br />
<a name='more'></a><br />
<span style="font-size: large;"><span style="color: #134f5c;">Presentation</span></span><br />
<div style="text-align: center;">
<br /></div>
<div class="prezi-player" style="text-align: center;">
<style media="screen" type="text/css">.prezi-player { width: 550px; } .prezi-player-links { text-align: center; }</style><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" height="400" id="prezi_v9lvosve93i3" name="prezi_v9lvosve93i3" width="550"><param name="movie" value="http://prezi.com/bin/preziloader.swf"/><param name="allowfullscreen" value="true"/><param name="allowFullScreenInteractive" value="true"/><param name="allowscriptaccess" value="always"/><param name="wmode" value="direct"/><param name="bgcolor" value="#ffffff"/><param name="flashvars" value="prezi_id=v9lvosve93i3&lock_to_path=1&color=ffffff&autoplay=no&autohide_ctrls=0"/><embed id="preziEmbed_v9lvosve93i3" name="preziEmbed_v9lvosve93i3" src="http://prezi.com/bin/preziloader.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowFullScreenInteractive="true" allowscriptaccess="always" width="550" height="400" bgcolor="#ffffff" flashvars="prezi_id=v9lvosve93i3&lock_to_path=1&color=ffffff&autoplay=no&autohide_ctrls=0"></embed></object><br />
<div class="prezi-player-links">
<a href="http://prezi.com/v9lvosve93i3/changing-the-mindset-more-object-oriented-view-at-the-business-domain-modeling/" title="Changing the mindset - more object-oriented view at the business domain modeling">Changing the mindset - more object-oriented view at the business domain modeling</a> on <a href="http://prezi.com/">Prezi</a></div>
</div>
<div class="prezi-player">
<style media="screen" type="text/css">.prezi-player { width: 550px; } .prezi-player-links { text-align: center; }</style></div>
<br />
<span style="color: #134f5c;"><span style="font-size: large;">Video from JavaCamp #11</span></span><br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="allowfullscreen" frameborder="0" height="281" mozallowfullscreen="mozallowfullscreen" src="http://player.vimeo.com/video/54208442?badge=0" webkitallowfullscreen="webkitallowfullscreen" width="500"></iframe> </div>
<div style="text-align: center;">
<a href="http://vimeo.com/54208442">DDD & CQRS w Javie - Piotr Wyczesany @ JavaCamp #11</a> from <a href="http://vimeo.com/polishjug">Polish Java User Group</a> on <a href="http://vimeo.com/">Vimeo</a>.</div>
<br />
<span style="color: #134f5c;"><span style="font-size: large;">Further links:</span></span><br />
<br />
Changing the mindset series:<br />
<ul>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Changing the mindset - part 1 / 4 - Classic approach</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Changing the mindset - part 2 / 4 - Modeling the Domain</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Changing the mindset - part 3 / 4 - Segregation of Responsibility</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/02/changing-mindset-part-4-4-subtle.html">Changing the mindset - part 4 / 4 - Subtle difference </a></li>
</ul>
<br />
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com2tag:blogger.com,1999:blog-1727031811590975354.post-41050416876232538822012-10-16T10:50:00.002+02:002012-10-16T10:50:57.325+02:00Should tests influence the production code? For a very long time I was told that tests should not influence the
production code. By this I mean, that we should not change our design
only in order to be able to test it. That was quite OK for me, since -
you know - test are only tests - the production code is what matters and
what drives the design. Tests should just shut up and follow. Right?<br />
<br />
Lastly I am <a href="http://blog.8thlight.com/uncle-bob/2012/01/11/Flipping-the-Bit.html">flipping the bit</a>
and diving into TDD and I must say - this is quite an adventure. At the
beginning I was like a babe in the woods. It was not easy to start.
Everything was harder - writing code, designing, thinking... I had to
firstly write a test, and then the code - everything was upside down - I
didn't even have the code to test. Damn! I started to think about
basics again, and that... was really refreshing!<br />
<br />
<span style="color: #0c343d;"><span style="font-size: large;">The Example</span></span><br />
<br />
One
day I was given a task to figure out changes in history lines of some
objects and update the meta-data for each line accordingly - with ids of
objects that were changed. For the simplicity of the example let's
assume, that those objects were rectangles and I was interested only in
their length.<br />
<br />
Let's use an example:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmhJUNeyC8r5lqcqSyWlN870NfCwMa9hpIITS7eP0nq_evKxyfDf8symtypj-w9TEu9vNhtvE8dkerkO9_6TyZch2i_gpHRr5VeptcOozrh-w6_QaUEJtEXfkjVwAXAEFCNlE-rtL9y4/s1600/history-lines.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmhJUNeyC8r5lqcqSyWlN870NfCwMa9hpIITS7eP0nq_evKxyfDf8symtypj-w9TEu9vNhtvE8dkerkO9_6TyZch2i_gpHRr5VeptcOozrh-w6_QaUEJtEXfkjVwAXAEFCNlE-rtL9y4/s1600/history-lines.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEUE60tUPtxsFN_bI-Y7i__hOI0PpeJtlWze2rISBNxDpQqIfH2GImsb9XgfN0ko9QM8uPebzpSzTBf2Sh1dc8A-CygDDnVBQfO95yQNAorJVbRDJzC4_7d4eqbKwNo1kai1Hj-wA0TaY/s1600/history-lines.jpg" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
As
you can see (you have to excuse me my poor Paint skills), the rectangle
A was changed only in the first step (transition from A1 to A2),
rectangle B was not changed at all and rectangle C was changed only in
the second step (transition from C2 to C3). As a result, there should be
the id of the rectangle A in the Line 2, and the id of the rectangle C
in the Line 3.<br />
<br />
The task was not that hard and my very
first thought was to create some meta-data generator that would accept a
list of Lines and update each of them. Sounds easy, doesn't it? <span style="font-size: large;"><span style="color: #0c343d;"> </span></span><br />
<br />
<a name='more'></a><span style="color: #0c343d;"><span style="font-size: large;">Code-first approach</span></span> <br />
<br />
If
I didn't do TDD, I would go and write the code first - iterate through
the Line list, then in each one iterate through all rectangles and for
each of those find matching one in previous Line. Then I would compare
them and update the meta-data. Plus some corner cases - handling one
Line only, or something similar.<br />
<br />
It would probably take
me some time to write - iterate through two collections, find matching
rectangles in previous Line, and then the comparison. After that - I
would write tests - prepare data set up for the scenario - a lot of
objects, a lot of mocking, and some verification. Probably this test
would be quite big. Enough to say, that my objects were much more
complex, than simple rectangles. ;)<br />
<br />
However I tried to
write the test first and it was just a pure pain... Creating so many
rectangles, mocking so many other involved objects and thinking about
the future code that I was going to write... This approach was just not
testable at all... I took a break.<br />
<br />
<span style="font-size: large;"><span style="color: #0c343d;">Test-first approach</span></span><br />
<br />
After
couple of minutes I returned to the problem and started to think what
was wrong. I figured out, that there were just too many responsibilities
in that <i>not yet existing </i>code. <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> was broken even though not a single line was written. That made me thinking.<br />
<br />
After
short time I discovered some implicit concept - a Comparison Pair. I
was trying to compare whole Lines, where I only required comparing pairs
(A1-A2, A2-A3, B1-B2, B2-B3, C1-C2, and C2-C3). So I started to change
my design in my head.<br />
<br />
First - I had to split those
Lines into Comparison Pairs, and then for each of those Comparison Pairs
generate the meta-data. I created interfaces for those two
responsibilities and mocked them in tests, which were simple, readable
and were covering all paths. My generator was just delegating the work
to those interfaces. <br />
<br />
Then I created tests for
splitting Lines into Comparison Pairs - again smoothly - followed by
implementation. And the same for comparing those Pairs.<br />
<br />
<span style="color: #0c343d;"><span style="font-size: large;">So they should, or should not?</span></span><br />
<br />
And
we are back to the original question - should tests influence the
production code? If you are doing TDD, then you don't have a choice.
Your tests shape your design - just like in my example.<br />
<br />
If
you are not doing TDD and writing your code first, then you may
encounter some problems with testing it later. (Of course if you are not
writing tests, then you won't have any problems - right? ;) ) When the
code is hard to test, you can do one of following things:<br />
<ul>
<li>give up and do not test</li>
<li>do the nasty work and write this huge and unpleasant test</li>
<li>add some helping methods in the code with this "awesome" annotation - <span style="font-family: "Courier New",Courier,monospace;">@TestOnly</span></li>
<li>refactor the code so that it would be testable</li>
</ul>
The first two approaches do not influence the production code,
but are leaving the code and tests in a mess. The third influences, but
in a really ugly way - this annotation is a code smell. The last one
also influences the code, but in a good way - makes the design better.<br />
<br />
So
to summarize - I think, that tests should influence the production
code. They make the design better. They are helping with finding
implicit concepts and following <a href="http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29">SOLID</a> principles. Do you agree?Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-74937909088621667772012-08-13T10:58:00.001+02:002012-08-13T10:58:59.716+02:005 reasons why we (still) do not like patterns in the heart of softwareWe like Design Patterns. They make complicated things simpler. Our
brains are designed to tackle complexity with them. It is easier to
describe something with words "it's like that one thing that you know,
but with some differences" than describing it completely from scratch.<br />
<br />
All
frameworks that we use are full of Patterns and we understand them very
well. Decorator here... Chain of responsibility there... Oh, and some
old, nasty, huge and extremely overloaded Singleton over there - yup, we
use it too... Piece of cake. This is our (developers) well known
Domain. We are Domain Experts on that territory and we feel confident
there.<br />
<br />
<span style="font-size: large;"><span style="color: #0c343d;">The reality</span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.sxc.hu/pic/m/m/mu/muresan113/650828_one_way_rusty_sign.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.sxc.hu/pic/m/m/mu/muresan113/650828_one_way_rusty_sign.jpg" /></a></div>
<br />
But
guess what - this is not the Domain that we are dealing with on daily
basis (unless we are working on frameworks of course :P ). Our Domain,
which we are struggling with, is about the business that runs our
company. We don't need those mentioned Decorators and stuff.<br />
<br />
At
a glance, it looks like we can just live with some simple bags for
data, called entities, mapped to database tables (the Anemic Model). I
personally like to<span class="short_text" id="result_box" lang="en"><span class="hps alt-edited"> </span></span>call them <span class="short_text" id="result_box" lang="en"><span class="hps alt-edited">humorously </span></span>Records - the great pattern that is borrowed from Turbo Pascal. I think, that <a href="http://art-of-software.blogspot.com/2008/07/z-pamitnika-zdomenowanego-modelarza-1.html">Sławek mentioned about it</a> couple of times (in polish). ;)<br />
<br />
<a name='more'></a>So,
our entities have a bunch of getters and setters, they are managed by
some Services/Managers/OtherFancyCalledStuffMakers without explicit
boundaries, and eventually everything is connected to everything. We
have beautiful and tasty spaghetti monster in our Version Control System
and not a single pattern is in use in this "boring" Domain Model.<br />
<br />
From
the other side - isn't that great when it comes to talk about Patterns?
We can push all this stupid Domain related stuff off to the side, call
it "data" and go back to our safety zone. And once we are there - oh yes
- we can finally talk about our well known Design Patterns! We can
argue about differences between MVC and MVVM and our company's business
model lays over there - alone in some dark package greatly called
"domain". Probably quite sick because of his anemia...<br />
<br />
<div style="color: #0c343d;">
<span style="font-size: large;">Why this happens?</span></div>
<br />
Why we are letting the Model to rust in a such way? I can think of about five reasons.<br />
<br />
<div style="color: #0c343d;">
<b><span style="font-size: small;">1. We are not aware that we are missing Patterns in the Model</span></b></div>
We
were taught to use Turbo Pascal's Records in Java, or C# and we did not
even think that this may be wrong. But guess what - You are reading
this, so You are now aware! ;)<br />
<br />
<b><span style="color: #0c343d;"><span style="font-size: small;">2. We do not know Patterns </span></span></b><br />
We cannot apply something, that we do not know. So here is the solution: read Eric Evans' book - <a href="http://www.amazon.com/gp/product/0321125215">Domain Driven Design: Tackling Complexity in the Heart of Software</a> - there are a lot Patterns for Modeling the Domain (<a href="http://en.wikipedia.org/wiki/Domain-driven_design#Building_blocks_of_DDD">Building Blocks</a>). <br />
<br />
<div style="color: #0c343d;">
<b>3. We do not want to dig into the business Domain to find those Patterns</b></div>
We
are software developers. That means we are creating software - this is
our Domain and we do not want to change our speciality. But just think
about it - after months of dealing with some specific business, we <span class="short_text" id="result_box" lang="en"><span class="hps">unintentionally
begin to understand it... We actually dig into it - like it, or lump
it, but once you are aware, You should start thinking what is good for
Your project...</span></span><br />
<br />
<div style="color: #0c343d;">
<b><span class="short_text" id="result_box" lang="en"><span class="hps">4. "Nah... It won't work for us."</span></span></b></div>
<span class="short_text" id="result_box" lang="en"><span class="hps">This
kind of thinking usually means, that You got used to doing things in
Turbo Pascal's way. You like Your comfort zone. Introducing Domain
Driven Design (DDD) requires changing the mindset and behaviors. (Of
course, there is a possibility, that Your Domain is so straightforward,
that simple CRUD will do the trick, but I think most of us struggle with
bigger systems.) So stop looking for excuses!</span></span><br />
<br />
<b style="color: #0c343d;">5. "No, and that's final!" </b><br />
Well...
If You are such an ignorant, then nothing will help You... You will
eventually burn in hell. Just keep Your dirty hands far away from my
codebase, and we will both be happy. ;) <br />
<br />
PS.<br />
Can You think of any other reason why we still do not like Patterns in the Domain?Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-44806990675512310552012-07-10T14:44:00.000+02:002012-07-10T14:44:47.416+02:007 lessons learned from launching my DDD/CQRS/ES startupIt's been a month and a half since I wrote the last blog post. This
time it was not because I am lazy (although in general I am), but quite
the opposite. I was very busy with launching my startup application
written after hours at home with my brothers.<br />
<br />
For the
couple of last weeks, there was the Euro 2012 Cup in Poland and Ukraine,
and everybody around me was crazy about the football those days. On the
other side, couple of months ago I started to practice <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Domain Driven Design</a> with <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Command Query Responsibility Segregation with Event Sourcing</a>. I combined those two and launched my startup as a Facebook application written in this style: "<a href="https://apps.facebook.com/typer-football/">Typer</a>" (at this moment only in Polish).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY77EpMuX99RixOBLGftSV0JN7nPcslo72Xb5WBALYNRyN9eBp7v_Bh6a-i8AXeus1eEqKZPmQQe2fC-IwSUl6yZ4WTAyr7UA0pCyy9A7vMbZS7wtrepmti22An9BTQy-ctmeBpYg3qFs/s1600/final.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY77EpMuX99RixOBLGftSV0JN7nPcslo72Xb5WBALYNRyN9eBp7v_Bh6a-i8AXeus1eEqKZPmQQe2fC-IwSUl6yZ4WTAyr7UA0pCyy9A7vMbZS7wtrepmti22An9BTQy-ctmeBpYg3qFs/s400/final.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHn2-YrXU-94M-L2G4nRY9eyVem57bfEMdkVxWDiTiX2SvkJ1P4TJYgWkT9R546OoCl1ToJijDadjM5u8FeSngCApKhAngYI_WTrD1bCP_59whQmyBTlWF5j2I2npbjDBy4oZiDM0l8Ok/s1600/avatar.jpg" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<span style="color: #073763; font-size: large;">What were my goals?</span><br />
<br />
From the <b>personal perspective</b>,
I wanted to give people some opportunity to have fun - to type scores
in their own groups, compete with each other and find out who is the
best football specialist.<br />
<br />
From the <b>business perspective</b>, I wanted only to generate some traffic and see if it can be profitable in the future.<br />
<br />
From the <b>development perspective</b>, I wanted to practice DDD/CQRS/ES, since I do not have enough possibilities to do it on daily basis.<br />
<br />
From the <b>management perspective</b>, I wanted to learn how to use my time effectively, and how to lead my small team.<br />
<br />
<span style="color: #073763; font-size: large;">Did I succeed?</span><br />
<br />
I
did! Maybe I wasn't able to achieve 100% of goals that I set up, but I
am proud of what I did and I am much smarter now. I want to share my
thoughts with you, so here I present my 7 lessons learned:<br />
<br />
<a name='more'></a><br />
<span style="color: #073763; font-size: large;">1. So you think you are Agile?</span><br />
<br />
From
the very beginning, when I started to work as a professional software
developer, I was told to be Agile. During my career, I saw a couple of
implementations of that, but none of them was even close to the Real
Startup Agility, which I had to adopt during that project. In all
companies that I worked for (small and medium companies, large
corporations, and even my own company for some time) there was and still
is a lot of classic waterfall approach.<br />
<br />
During this
project, I had so extremely limited time resources (working after
hours), and so hard deadline (the start of the Euro 2012) that I had to
use the Pareto Rule on the Pareto Rule itself. I saw how prioritization
and choosing right solutions in right places is extremely important.<br />
<br />
For
example - I did not have the rankings recalculation functionality when
the first match was started. I was finishing it during the first minutes
of the match and I released it after the first half. But it was
conscious decision. Other things were more important before the
beginning of the first match.<br />
<br />
During those four weeks I
released eight versions on my application. The only way to do it faster
is to implement some continuous delivery mechanism.<br />
<br />
So to summarize: <b>If you didn't run a startup on your own, you probably are not that Agile as you think you are</b>. ;)<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">2. DDD/ES domain model is the easiest to test.</span></div>
<br />
If you are willing to <a href="http://blog.8thlight.com/uncle-bob/2012/01/11/Flipping-the-Bit.html">flip the bit</a>,
and start doing Test Driven Development, start it on Event Sourced
Domain Model. This is the best way to see how valuable TDD is. The idea
is simple - structure your test cases in this way:<br />
<ul>
<li>Given - a list of events</li>
<li>When - a command</li>
<li>Then - a list of events</li>
</ul>
Thanks to that, you will be able to generate test scenarios (with the <a href="http://www.eventuallyinconsistent.com/2012/01/2011s-mindfucks.html">toString() method on events and commands</a>), and you will see how easy it is to model the domain by starting from test scenarios.<br />
<br />
<b>I did not have any bug in the domain model for the whole time</b>
- although I had some minor bugs in UI, and a bigger one in the
security, which is fixed now (but screw it - it was a startup). ;) <br />
<br />
<span style="color: #073763; font-size: large;">3. You don't have to be DDD/CQRS/ES'ed everywhere.</span> <br />
<br />
Modeling the Domain is a hard job. It requires much more intellectual power than <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">classic, anemic approach</a>. But guess what! You don't have to do it everywhere. Sometimes the biggest value is not in the Model.<br />
<br />
When
I started working on the security module, I planned to do it fully
DDD/CQRS/ES'ed. But after spending a lot more time than I actually
planned on that, I had to revise my approach. <b>The Model was not the most valuable thing in that place</b>
- the OAuth2 algorithm was. I dropped my fancy Model and rewrite it in
the simplest possible way to support the algorithm. And I moved on.<br />
<br />
<span style="color: #073763; font-size: large;">4. The CQRS's Read Model is extremely flexible.</span><br />
<br />
The
Read Model can be dropped and completely rebuilt from events. This
gives you a lot of possibilities. If you model your Domain right, and
define Events correctly, you will be able to mess with the UI as much as
you want. You will be able to improve the UX by generating better views
and you won't need to write complex updaters. Just re-run all events
and voilà!<br />
<br />
As <a href="https://twitter.com/yreynhout/status/218697646498525185">Yves Reynhout twitted once</a>, I grasped the domain well. <b>My commands didn't have to change, but the UX was updated couple of times.</b><br />
<br />
<span style="font-size: large;"><span style="color: #073763;">5. You probably won't end up with the Context Map drawn at the very beginning.</span></span><br />
<br />
When
we (me and my team) decided to do this startup, we created a Vision
Document. And according to that Vision we started to draw the <a href="http://abdullin.com/journal/2012/4/14/software-war-starts-with-a-map-context-map.html">Context Map</a>.
At the very beginning it looked very promising - seven Bounded Contexts
with good boundaries. After a couple of iterations we realized, that
this Context Map needs to be corrected here, erased there and some
Bounded Contexts needs to be joined.<br />
We also had to cut a lot from the final functionality, to be on time.<br />
<br />
Maybe this approach (top-down) should be taken in the really big projects,<b> but for startup you should go quite the opposite - start small and then evolve (bottom-up).</b><br />
<br />
<span style="font-size: large;"><span style="color: #073763;">6. Fail faster.</span></span><br />
<br />
We
didn't test our UX against real users before we launch. We had to
incorporate some UI changes in the later phase, when it was a little bit
more expensive. There are so many ways to create cheap prototype and
get the feedback from users. Paper cards for example are great example.
We should have taken them under consideration.<br />
<br />
If
something is painful, do more of it. We had some problems with
deployment at the very beginning. We tested most of the process and
automated it as much, as we were able to. So that, when we were
releasing, no problems occurred. And we were releasing quite often on
that short period of time. I am starting to think that <a href="http://simon-says-architecture.com/2012/01/03/the-automated-deployment-story/">Continuous Delivery</a> can be very interesting thing, that may improve your Agility.<br />
<br />
When you are doing something, <b>seek for the possibilities to fail safely as fast as you can</b>.
(I am not talking about searching for excuses!) If you see, that
something may go wrong, go down that path and explore it. It is much
safer (and cheaper) to do it early.<br />
<br />
<span style="color: #073763; font-size: large;">7. You need great people.</span> <br />
<br />
Last,
but not least - people are the most important piece of that puzzle. It
is easy to read, listen and watch presentations about methodologies,
techniques and all that stuff. But at some point, you will have to
implement all of them (or some part). And you need skilled and motivated
team to achieve that.<br />
<br />
<b>So big up for all of you, who helped me with that: </b>DEV (my bros, <a href="http://www.linkedin.com/pub/wojciech-wyczesany/54/8b2/591">Wojtek</a> and <a href="http://www.linkedin.com/pub/krzysztof-wyczesany/54/912/576">Krzysiek</a>), UI (<a href="http://www.cinthor.wer.pl/">Marcin</a>), OPS (<a href="http://www.linkedin.com/profile/view?id=12868691">Bartek</a>), UX consultations (<a href="http://desimply.com/">Marcel</a>), and of course my biggest supporter - Ania. ;)Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-84215593004544213942012-05-18T21:47:00.000+02:002012-05-19T11:51:18.199+02:00Event Sourcing is like Vector Graphics<div style="background-color: #f3f3f3; text-align: right;">
<span style="font-size: x-small;">I want to emphasize at the outset, that I am not an expert in graphics. </span></div>
<div style="background-color: #f3f3f3; text-align: right;">
<span style="font-size: x-small;">I just have some basic knowledge, but based on that I was able to coin this parallel.</span></div>
<br />
I assume, that you have some basic knowledge about <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Event Sourcing and CQRS</a>, but if you don't please refer to <a href="http://cqrs.wordpress.com/documents/cqrs-and-event-sourcing-synergy/">this definition</a> or <a href="http://www.viddler.com/v/dc528842">watch Greg Young's mindblowing 6,5h long classes</a> (if you already do have some knowledge, watch this video anyway - it is worth your time).<br />
I also assume that you have some very basic knowledge about <a href="http://en.wikipedia.org/wiki/Vector_graphics">Vector Graphics</a> and <a href="http://en.wikipedia.org/wiki/Raster_graphics">Raster Graphics</a>.<br />
<br />
What
is an Event? Stop for a moment and think. Probably you will come up
with an answer, that an Event is an Aggregate's state change which
occurred. And this is a very good answer indeed.<br />
Guess what. Vectors can depict the state change too! So Events may be treated as Vectors, right?<br />
<br />
Below
I will write down some similarities that Event Sourcing has with Vector
Graphics, and 3rd Normal Form databases have with Raster Graphics.<br />
<br />
<div style="color: #073763;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdUxvfyA_G6GvsYDw9KMh6oIviYV86StgEui7I92QQtrc1z8Tg6tdJnlMhYfqX7MVZdKIqJRjG4vkt7ExpXApQJlpUWG34X5DqYRuExFy7jI4tZJ3FKxf-JgB8RL3HIpjoyL6EDBNJJng/s1600/raster_eye.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdUxvfyA_G6GvsYDw9KMh6oIviYV86StgEui7I92QQtrc1z8Tg6tdJnlMhYfqX7MVZdKIqJRjG4vkt7ExpXApQJlpUWG34X5DqYRuExFy7jI4tZJ3FKxf-JgB8RL3HIpjoyL6EDBNJJng/s1600/raster_eye.jpg" /></a></div>
<span style="font-size: large;">1. Scaling up.</span></div>
In
Vector Graphics you can scale up the image and it won't lose the
quality. The same is with Event Sourcing based application - you can
easily scale them up without losing the quality of the code and design.<br />
Have
you ever scaled up a completely consistent, built on top of 3rd Normal
Form database application? It looks just as scaled up Raster Graphics
based image - let's just <i>say "ugly"</i>. ;)<br />
<br />
<a name='more'></a><div style="color: #073763;">
<span style="font-size: large;">2. Breaking into smaller.</span></div>
You
can take some parts of Vector Graphics based image, and put them in
another Vector Based image. Same with Events - you can break some module
(Bounded Context) into two and take out all Events for particular
Aggregate.<br />
Have you ever tried to break the SQL database with an army of FK constraints? Or copy something out of Raster Graphics image?<br />
<br />
<span style="color: #073763; font-size: large;">3. Coupling.</span><br />
In
Vector Graphics when you modify one object, the others are not touched.
The same is true with Event Sourcing - only one Aggregate is changed.<br />
Have
you tried to change the SQL database schema? It is like drawing on a
Raster Graphics based image without layers. It requires a lot of
precision -another way you may end up with a real mess...<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">Tools.</span></div>
You may disagree - we have Hibernate and Envers - we have Photoshop and Gimp.<br />
Yes,
we have - those are great tools, that make working with 3rd Normal Form
databases and Raster Graphics based images a lot easier.<br />
But from
the other side, they are hard to learn, hard to work with (when really
big scale is the key) and they have some serious limitations.<br />
<br />
So, I am leaving you with this metaphor. Do you see any other similarities? Or maybe differences? Let's discuss. ;)Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com2tag:blogger.com,1999:blog-1727031811590975354.post-8799555982324995342012-04-23T18:14:00.000+02:002012-04-23T18:14:05.699+02:00Convention over implementation with Spring DataI think that most of us are familiar with the term "<a href="http://en.wikipedia.org/wiki/Convention_over_configuration"><i>Convention over configuration</i></a>", but just to remember (from wikipedia):<br />
<blockquote class="tr_bq" style="background-color: #f3f3f3;">
<i>The phrase essentially means a developer only needs to specify
unconventional aspects of the application. For example, if there's a
class Sale in the model, the corresponding table in the database is
called “sales” by default. It is only if one deviates from this
convention, such as calling the table “products_sold”, that one needs to
write code regarding these names.</i><br />
<i>When the convention implemented by the tool you are using matches
your desired behavior, you enjoy the benefits without having to write
configuration files. When your desired behavior deviates from the
implemented convention, then you configure your desired behavior.</i></blockquote>
For
example, the maven project structure uses convention - where our source
files, test source files and resources should be placed in order to be
compiled, tested and packaged automatically. We save a lot of time, and
create potentially less bugs, just by following this simple convention.
Of course, if we need something special, we can always overwrite it in a
way that we need.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxD3pNGWAUcPbfCDLQohyphenhyphenzW9Xs9z30dZsQb_uOiaT7RzmoNbvMeF3bOaqOMzU4IIC_TYZSst5gSGSH33DJHIxiKBqfCSuevBidpSEPxmIZcvRctXLnUxVQ68PNMghdQFWT5V711G_s8o0/s1600/hammock.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxD3pNGWAUcPbfCDLQohyphenhyphenzW9Xs9z30dZsQb_uOiaT7RzmoNbvMeF3bOaqOMzU4IIC_TYZSst5gSGSH33DJHIxiKBqfCSuevBidpSEPxmIZcvRctXLnUxVQ68PNMghdQFWT5V711G_s8o0/s320/hammock.jpg" width="320" /></a></div>
<br />
But this is only about configuration... I would like to extend it a little bit and talk about <b>convention over implementation</b>
(my own term - at least I haven't seen it anywhere else yet ;) ). So
that we could write less code to achieve more, do it faster and with
higher quality. I am lazy after all...<br />
<br />
<a name='more'></a><br />
<span style="color: #0c343d; font-size: large;">Common code</span> <br />
<br />
The
most common piece of code, that developers write is the Database Access
Object (DAO), sometimes also called Repository (for me it is not
exactly the same, but it is another topic). Let's say that we have some
entity called <span style="font-family: "Courier New",Courier,monospace;">MatchView</span>
and it contains some fields with getters and setters. We want to be
able to save it, load it by id, and search for entities by some criteria
- probably with some sorting and/or paging involved.<br />
<br />
So
each and every time we are manually creating the interface and
implementation of it (usually for JPA, or Hibernate). This interface may
look like this:<br />
<br />
<pre class="brush:java;">public interface MatchViewDao {
void saveOrUpdate(MatchView matchView);
MatchView findById(UUID matchId);
OurInHousePageableList<Matchview> findMatchesForTeam(
UUID teamId, OurInHousePageAndOrderingInfo pageAndOrdering);
}
</pre>
<br />
Of course we have to write the implementation of it that uses JPA, or Hibernate manually - and we cannot forget about <span style="font-family: "Courier New",Courier,monospace;">OurInHousePageableList</span> and <span style="font-family: "Courier New",Courier,monospace;">OurInHousePageAndOrderingInfo</span>. A lot of code that has to be written, tested and maintained, isn't it?<br />
<br />
<span style="color: #0c343d; font-size: large;">Don't write this code</span><br />
<br />
Guys from <a href="http://www.springsource.org/spring-data">Spring Data</a>
have done their homework. They gave us the possibility to use only the
interface, which has to follow some very simple conventions and it will
be wired "<i>automagically</i>" - without writing the code actually.<br />
<br />
Spring
Data is an umbrella project which addresses the access to data in
general. It supports relational databases, document databases, key-value
stores, data grids and other.<br />
<br />
We can use one of
general interfaces, extend it and we will be able to access our data
without writing a line of code for it. For most cases it provides
everything that we need and of course if we need something special, we
can always write it by ourselves (for example some very sophisticated
in-memory searches).<br />
<br />
We can save entity, load it by id, load all entities, and load sorted pages of data. But the best thing is that <b>you can specify which fields should be used to create query - only by the method name convention</b>. And you can of course make this query pageable too.<br />
<br />
Speaking about paging - we don't need to write our in-house solutions for queries. It is provided in the framework.<br />
<br />
So let's return to our example. The interface definition could look like this:<br />
<br />
<pre class="brush:java;">public interface MatchViewDao
extends PagingAndSortingRepository<MatchView, UUID> {
Page<MatchView> findByTeamId(UUID teamId, Pageable pageAndOrdering);
}
</pre>
<br />
All methods from super interfaces are inherited and what's more - we added new method. That method will query all <span style="font-family: "Courier New",Courier,monospace;">MatchView</span> entities that have a value of field <span style="font-family: "Courier New",Courier,monospace;">teamId</span>
equal to the given one as argument, and return specified page as the
result. And we achieved it through following simple convention -
property expression in the method name. We can add more fields to the
method name and combine them with logical operators.<br />
<br />
<br />
The last step is to create the bean in spring context.
The easiest way is to do that through a special namespace. It may look
like this:<br />
<br />
<pre class="brush:java;"><beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemalocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="some.package.with.repositories">
</repositories>
</beans:beans>
</pre>
<br />
We can adjust it in many ways - exclude whole
subpackages, exclude classes by some filters, or configure them
manually. And of course you need to configure your data source. ;)<br />
<br />
We can access the data and we don't have to write a single line of code - isn't that brilliant?<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Where to use it?</span></span><br />
<br />
Wherever
you can! It saves time, developers write less buggy code (that normally
would have to be tested and maintained), and of course it is fun.<br />
<br />
Personally, I find it extremely useful to use it on the Read Side of <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">CQRS</a>. After all we are not supposed to need anything more fancy here.<br />
<br />
On the Write Side we may find it usable, but only if we are not using Event Sourcing for Aggregates.<br />
<br />
I think you can easily see that in <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Anemic Models</a> it can also be very handy. ;) <br />
<br />
If you also find it useful and want to learn something more, I encourage you to view <a href="http://www.infoq.com/presentations/Spring-Data-JPA-Repositories-Done-Right">this presentation</a>, and give me a comment on how and why would you use it.<br />
<br />
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com7tag:blogger.com,1999:blog-1727031811590975354.post-76525009544263725952012-03-25T14:59:00.000+02:002012-03-30T20:37:45.670+02:00My 3 cents on 33rd Degree Conference<br />
One of the best conferences for Java masters in Poland has ended. The <a href="http://2012.33degree.org/">33rd Degree</a>.<br />
I've been on the previous one and I really enjoyed it. Totally 5/5.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2012.33degree.org/images/diuk.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2012.33degree.org/images/diuk.png" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
However, this year was a little different. I also liked it, but I think it
could be better. Some speakers were inspiring, some were boring. ;)<br />
And some were talking about things that I already know... Maybe I should
read less? ;)<br />
So to shortly sum it up - there was not a single <a href="http://www.eventuallyinconsistent.com/2012/01/2011s-mindfucks.html">mindfuck</a>
during this edition. And that's a pity.<br />
<br />
I decided to give <b>subjective </b>marks for each presentation that I
attended and here they are:<br />
<span style="color: #073763; font-size: 18pt;"></span><br />
<a name='more'></a><span style="color: #073763; font-size: 18pt;">The first day </span><br />
<br />
The very first talk was from Rafi Krikorian from Twitter. I enjoyed his talk
and the story behind this enormous application. I didn't know that it is built
on top of Ruby... I gave this talk a mark of <b>4/5</b>.<br />
<br />
After a short break Ken Sipe gave a presentation about Complexity of
Complexity. It was good, but I didn't learn anything new. However maybe it was good to recall some things and I gave a mark of <b>4/5</b>.<br />
<br />
As a third speaker, Venkat Subramaniam appeared. Everybody that knows
Venkat, also knows how enthusiastic he is on a stage. ;) It was pleasure to
listen to him, however the topic was not so interesting for me and I gave a
mark of <b>3/5</b>.<br />
<br />
After the lunch break, the sessions were divided into 5 tracks. I chose to
attend to presentation called "Build trust in your build to deployment
flow". I shouldn't... It was boring and I know Artifactory already... <b>1/5</b>
this time unfortunately...<br />
<br />
The next divided session didn't look like anything interesting was there, so
I went to see presentation about node.js. I did not expect anything breaking
and I wasn't wrong. However I learned that servers can also be built in
JavaScript. I gave a mark of <b>3/5</b>.<br />
<br />
After that, I joined the presentation of Wojciech Seliga from Atlassian
about taming the automated test beast. That was a very good presentation.
Wojciech talked about their problems with the duration of their tests in JIRA.
It looks like the project that I am working currently in my work place, has the
same problems and the future doesn't look good... ;) Their biggest problem was testing
the GUI, and their solution was to introduce Page Object Pattern to avoid
testing graphical components. We will try. Overall mark: <b>4/5</b>.<br />
<br />
At the end of the day, there was a <a href="http://en.wikipedia.org/wiki/Birds_of_a_feather_%28computing%29">BoF</a>
session and I joined the talk about the customers. That was absolutely the best
part of the day. We had a very good talk with many ideas how to approach the
customer. The most important thing from this session is to remember, that the
customer always knows what he wants, but not always knows what he needs. And
our job is to find it out. Overall mark of <b>5/5</b>.<br />
<br />
<span style="color: #073763; font-size: 18pt;">The second day</span><br />
<br />
After the first day I was a little bit disappointed, however the second day
started really good. Barry O'Reilly gave a brilliant talk about Agile, Lean and
Startup practices. Basically, he claims that Startup practice is the next Agile
and it should be introduced within corporations. I wrote whole page of notes
during his talk. Totally <b>5/5</b>.<br />
<br />
The second presentation I attended to was from Matthew McCullough about
economic games in software projects. Another brilliant talk. I really enjoyed
it. The most important thing that I will remember from his talk is The menu
trick. Again <b>5/5</b>.<br />
<br />
The third presentation was from Sławomir Sobótka. I was looking forward to
see his talk about soft skills for software specialists. The presentation was
based on the <a href="http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition">Dreyfus
Model of Skill Acquisition</a> which I know very well, but Sławek presented
many aspects of it - even some biological reasons for some things. And again I
had to give a mark of <b>5/5</b> for the third time in a row.<br />
<br />
After the lunch break, I attended again for Sławek's presentation. This time
he was speaking about programming techniques that underlie the modern software
engineering. I really admire how Sławek hide the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Domain Driven Design</a> concepts
in this talk. Unfortunately I know the topic and I didn't learn anything new,
so my mark for this talk is <b>3/5</b>.<br />
<br />
The next presentation was originally supposed to be presented by Jarek
Pałka, but he couldn't make it. I regret that, since I was looking forward to
see his talk. Maybe another time. ;) Ken Sipe substituted his talk and gave a
nice presentation about web security. I know most of it, but I didn't know
that some NoSQLs can be sensitive for SQL injections. Nothing special, so I gave
<b>3/5</b> mark.<br />
<br />
After that I attended to Nathaniel Schutta's presentation about designing
for mobile. This presentation opened my eyes for the mobile market. I wasn't
aware of the amount of devices that people buy... I will have to rethink many
things after this talk. The best thing that I will remember from this talk is
to design for the mobile first, and then for the desktop. Totally <b>5/5</b>.<br />
<br />
The last thing at this day was the <a href="http://en.wikipedia.org/wiki/Birds_of_a_feather_%28computing%29">BoF</a>
session about beautiful failures. The topic looked interesting and after
yesterday's BoF session I was looking forward for another brilliant
brainstorm... I regret that speakers gave a regular presentation, which was
actually quite boring, instead of a free talk of attendees. This BoF was
actually the beautiful failure indeed. Unfortunately I had to give a mark of <b>2/5</b>.<br />
<br />
<span style="color: #073763; font-size: 18pt;">The third day</span><br />
<br />
Since
the talk about mobile design from Nathaniel during the first day was
so great, I decided to see what else he can say.
Unfortunately the half of his talk was the same as previous day... He
was talking about differences between mobile native and web apps and
gave some good
examples, but nothing more. So I gave the talk a mark of <b>3/5</b>.<br />
<br />
The second talk I attended was from Ken Sipe again and this time he talked
about MongoDB. I really like this database for the Read side in <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">CQRS</a>, and Ken
gave some good thoughts on using it for scaling the application. Unfortunately
there were not many of them, which I wouldn't know, so my note was <b>3/5</b>.<br />
<br />
The next talk was from the Uncle Bob himself and I really wanted to see him
live. He was speaking about the three laws of Test Driven Development. And he
was veeery expressive (shooting lasers and stuff). :) He was talking about the
way that tests should be organized to run fast. His 241 Fitnesse tests run in
less than a minute... I was shocked. Also, he asked if each of us would deploy
the build just because all tests are green. I enjoyed his talk so my mark
couldn't be different than <b>5/5</b>.<br />
<br />
After the lunch, all tracks were merged into one big track for all - just
like at the beginning of the first day. We had no possibility to choose what
presentation we want to attend, so I was a little bit scared after I saw,
that the next talk was from Natchaniel Schutta again. I remembered that half of
his second presentation was similar to the one from the previous day. I was
afraid that he can do the same for this talk. I was wrong
actually and he gave a really good talk about code craft. I gave a mark of <b>4/5</b>.<br />
<br />
The next talk was from Jurgen Apello. I knew his name, but I don't know
where from. The talk was very good, and it was even not so visible, that he is
talking about his book. Maybe I will buy it, since his points were very
interesting - especially his metaphor about the dancing with the system. The
mark couldn't be different than <b>5/5</b>.<br />
<br />
The very last talk was from Uncle Bob again. I love his style of
presenting, but his talk about demanding professionalism did not introduce
anything new... How many times we can hear, that code is the design? Maybe some
people should hear that, but for me it was less than I expected. So the mark
for the final talk was <b>3/5</b>.<br />
<br />
<span style="color: #073763; font-size: 18pt;">Summary</span><br />
<br />
The average mark for the presentations is <b>3.75/5</b>, so not so good.
Additionally there was no presentation that would change my point of view at
anything drastically. Maybe the mobile design idea will mature in my head after
some time. However, I expected more.<br />
<br />
As I said at the beginning - maybe I should read less? ;)<br />
<br />
From the organizational point - everything was perfect; however I really
hate the hotel that the conference was taking place... There was absolutely no
place during breaks, and queues to toilettes were enormous... But other things
were great - even the internet connection, so big thanks to organizers!<br />
<br />
I am looking forward for the next year's edition!<br />
<br />
<br />
<br />
<div class="MsoNormal">
<br /></div>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com4tag:blogger.com,1999:blog-1727031811590975354.post-69945784883268673272012-02-22T22:36:00.000+01:002012-03-30T20:32:08.385+02:00CQRS vs DDD popularityLet's imagine a situation. You are a person that has some time and
wants to learn something new. You have two options briefly presented:
Domain Driven Design on the one hand and Command Query Responsibility
Segregation on the other. What would you choose?<br />
<br />
(Before
you start reading below, understand that I compare those two concepts
only theoretically and I am not taking under consideration how they
interact with each other) <br />
<br />
For me it would be pretty straightforward - DDD of course. Why? I will explain below.<br />
<br />
However
for most people that I have met I see the opposite... I still cannot
fully understand why, but let's try to investigate a little...<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">What Google says? </span></span> <br />
<br />
I
made some quick investigation in the Google Trends. I typed "cqrs" and
"domain driven design". When I typed "ddd" or "command query
responsibility segregation" the results were unreliable.<br />
<br />
We can see that DDD was first and at the very beginning it was more popular than CQRS ever. But then it started to fall down.<br />
<br />
On the other hand, CQRS gains the momentum. It looks like in the middle of the previous year it overtook DDD.<br />
<br />
<table style="display: inline;"><tbody>
<tr><td style="padding: 0 0 0 0; white-space: nowrap;"><b>domain driven design</b> </td><td><table cellspacing="0" class="bar" height="4" style="width: 70px;"><tbody>
<tr><td bgcolor="4684ee" style="display: block;"><br /></td></tr>
</tbody></table>
</td><td>1.00</td></tr>
</tbody></table>
<table style="display: inline;"><tbody>
<tr><td style="padding: 0 0 0 0; white-space: nowrap;"><b>cqrs</b> </td><td><table cellspacing="0" class="bar" height="4" style="width: 26px;"><tbody>
<tr><td bgcolor="dc3912" style="display: block;"><br /></td></tr>
</tbody></table>
</td><td>0.38</td></tr>
</tbody></table>
<div id="graphcontainer" style="overflow: hidden; width: 580px;">
<img height="260" src="http://www.google.com/trends/viz?q=domain+driven+design,+cqrs&date=all&geo=all&graph=weekly_img&sort=0&sa=N" width="580" /></div>
<span style="color: #073763; font-size: large;"></span><br />
<a name='more'></a><span style="color: #073763; font-size: large;">Community</span><br />
<br />
There are two main mailing groups for those topics:<br />
<ul>
<li><a href="http://tech.groups.yahoo.com/group/domaindrivendesign/">http://tech.groups.yahoo.com/group/domaindrivendesign/</a> - it was founded on Sep 27, 2002 (wow! I didn't expect that...) It has almost 4000 members at the moment and 22957 messages.</li>
<li><a href="http://groups.google.com/group/dddcqrs">http://groups.google.com/group/dddcqrs</a> - the first message is from Jul 23, 2010. It has 1331 members and <span style="color: #333333;">7643 messages.</span></li>
</ul>
<span style="color: #333333;">It looks like the DDD community is bigger,
but on the dddcqrs list there is much more messages lastly. Maybe
because it grapples the DDD topic a little bit.</span><br />
<br />
<span style="font-size: large;"><span style="color: #073763;">The learning curve </span></span><br />
<br />
<span style="color: #333333;">OK, so let's return to the primary question. Why people prefer CQRS topic over DDD?</span><br />
<br />
CQRS
is really nothing complicated in the very basics. You take Read
operations and Write operations and separate them into completely
different stacks. You implement them independently and the only one
complex thing that you can face is switching your mindset from ORM to
Event Sourcing (if you decide to use it)... Of course other more
complicated things come in time - scaling, transaction boundaries, etc. -
but the learning curve is smooth and rises evenly.<br />
<br />
With
DDD, on the other hand, it's not easy to start... You have to
understand all Building Blocks. You have to understand what Ubiquitous
Language is, and why it is so important. You also should read <a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">The Blue Book</a> at least three times (as they say). ;)<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Habits</span></span><br />
<br />
We are not so Agile as we think we are. Introducing <a href="http://www.eventuallyinconsistent.com/2012/02/changing-mindset-part-4-4-subtle.html">change to our mindset</a>
requires a great effort. We, as developers, got used to modeling Anemic
Entities and name it greatly: The Model. We like working with them.
After all, we used them for so many years... And our code still works!
But let me ask here - how hard is to change something in it, or to
introduce a new developer to the project? And what about customer
satisfaction?<br />
<br />
In CQRS you don't have to change your
modeling techniques. You still can have Anemic Entities and it will
work. Your years of experience won't be wasted.<br />
<br />
In DDD you have to admit - "<i>yes, I was an Anemic Modeler. I didn't care about boundaries, responsibilities and implicit concepts. It was so much easier.</i>"- Our ego may suffer at the beginning...<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Where we look for complexity?</span></span><br />
<br />
We
tend to work with so many frameworks. We like them. If we have some big
problem, it usually turns out that we misused some of them. We like
spending time in fighting with configurations and browsing source code
of open source libraries. We are only developers after all - we like to deal with frameworks, not with business...<br />
<br />
In CQRS we can still do this same. We can focus on Hibernate, Spring, or some web framework.<br />
<br />
DDD
however concentrates on the heart of the problem - on the Domain. We
have to leave frameworks a little behind and start to think about Real
Business Problems. <br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Return of Investment</span></span><br />
<br />
It
looks like if we adopt CQRS (in whichever form) we will be able to
easily scale our system out, browse through history and other cool
stuff. The outcome comes very fast. We have some results almost at hand.<br />
<br />
With
DDD this time is much longer and you won't observe results on the first
sight. The true benefit comes when people starts to understand the
Domain. When they get involved into modeling exercises. When they start
communicate easily with Domain Experts. The project can get the real
momentum after some time. And this time can be painful.<br />
<br />
<span style="color: #073763;"><span style="font-size: large;">Conclusion </span></span><br />
<br />
We are lazy. :) Admit it. At least good developer should be. ;)<br />
Once
we learn something we want to see the result as fast as possible. Like a
kid. I am guessing that this is the reason why we tend to get more
excited and see bigger benefits from CQRS than from DDD.<br />
<br />
But
when we are creating really complex systems, we should be looking a
little further. And I would definitely go for learning DDD first, since
this is a long-time investment, that will have bigger ROI after all. And
maybe because I really like modeling... ;)<br />
<br />
And what do you prefer to try first: CQRS or DDD?<br />
<br />
PS<br />
At
this moment I see the biggest outcome from using them both. CQRS makes
DDD much much cleaner. And if you introduce Event Sourcing to them, they
literally kick ass. ;)Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com4tag:blogger.com,1999:blog-1727031811590975354.post-11703182145144397182012-02-06T23:37:00.000+01:002012-03-30T20:32:19.927+02:00Changing the mindset - part 4 / 4 - Subtle differenceThis is the last article out of the series about changing the mindset. At the beginning we took the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Classic approach</a>, and then we introduced three important concepts (in the order):<br />
<ol>
<li>Domain Driven Design (<a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Modeling the Domain</a>)</li>
<li>Command Query Responsibility Segregation (<a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Segregation of Responsibility</a>)</li>
<li>Event Sourcing (<a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Segregation of Responsibility</a>)</li>
</ol>
In the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">previous part</a> we separated our Read and Write Models. We also applied Event Sourcing as a persistence mechanism for Aggregates. We also equipped the Aggregate with behavioral methods only, and got rid of getters. <br />
<ol>
</ol>
Everything
looks really nice. The Model is clean, verbose, and everything is
explicit (as for such a small example). We have one data store for the Write side, and we
don’t have to care about distributed transactions. We can even easily provide historical data.<br />
<br />
However, if you paste the last piece of code from the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">previous part</a> to your IDE, you will see that there are many warnings on the fields – <i>"never read locally"</i>. You can ignore them and proceed, but you can stay for a moment and think why they appear.<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">The "aha" moment!</span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjODvsaoriBRawk7RweTy8-80dvhqbaRoydCVKouh68DmI9JabbpwPBPVShmUup4EsYrLo026UlTSbe1UYkNc29TDgdecg8gZp_UKjnn7Xt-T0k__yMgAEFBvHLMKrnD92QhaiSL50su6E/s1600/bulb-out-of-the-box.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjODvsaoriBRawk7RweTy8-80dvhqbaRoydCVKouh68DmI9JabbpwPBPVShmUup4EsYrLo026UlTSbe1UYkNc29TDgdecg8gZp_UKjnn7Xt-T0k__yMgAEFBvHLMKrnD92QhaiSL50su6E/s320/bulb-out-of-the-box.jpg" width="320" /></a></div>
<br />
<br />
It dawned on me the one day when I was really sleepy. I was making some coffee, while my brain was in <a href="http://www.youtube.com/watch?v=0BxckAMaTDc">the nothing box</a>. And somehow the idea came to my mind - why do I need all those fields?<br />
<br />
<br />
<a name='more'></a>It
looks like we had them on the very beginning, when we were mapping them
directly to SQL columns. We needed them to be persisted and we
were loading them with each query, but their only purpose was to be
shown. They were not used by any business logic. I shall repeat that: they were not used by any business logic...<br />
<br />
It was not clear until now…<br />
<br />
Actually
we don’t need them in our model! We need to keep only the properties that
will be used in making business decisions. The data that they are holding
is stored – in serialized Events (and later in the Read Model), but we
don’t need them in the Write Model any more.<br />
<br />
So finally our code may look like this:<br />
<br />
<pre class="brush:java;">public class Match extends AggregateRoot {
private UUID id;
private Date matchDate;
private boolean finished;
public Match(UUID id, Team homeTeam, Team awayTeam) {
apply(new MatchCreatedEvent(id, homeTeam.getId(), awayTeam.getId());
}
private void handle(MatchCreatedEvent event) {
this.id = event.getId();
this.finished = false;
}
public setupMatchDate(Date matchDate) throws MatchAlreadyFinishedException {
if (finished) {
throw new MatchAlreadyFinishedException();
}
apply(new MatchDateSetUpEvent(id, matchDate);
}
private void handle(MatchDateSetUpEvent event) {
this.matchDate = event.getMatchDate();
}
public finishWithScore(Score score, Date finishDate)
throws MatchFinishedBeforeStartException, MatchAlreadyFinishedExcepion {
if (matchDate == null || finishDate.before(matchDate)) {
throw new MatchFinishedBeforeStartException();
}
if (finished) {
throw new MatchAlreadyFinishedException();
}
apply(new MatchFinishedEvent(
id, finshDate, score.getHomeGoals(), score.getAwayGoals());
}
private void handle(MatchFinishedEvent event) {
this.finished = true;
}
}</pre>
<br />
<span style="font-size: large;"><span style="color: #073763;">The Questions</span></span><br />
<br />
So, how our mind has changed during introducing new concepts to our code?<br />
<br />
We
started with Classic Approach, when we modeled the simplest anemic
classes and mapped them with Hibernate. We didn't care about the
Language or any actions that can be taken on the objects. Actually what
we created, was a Database Schema and we mapped it one-to-one to the
Classes. Although I would call them Records (yup, like in Pascal). We
cared about Nouns only, and at this moment we were not even aware of that at
all. To create the model, we were asking mainly: <b>"What?"</b><br />
<br />
The next
step we took was to take care of Verbs. We started to think what we can
do with our model. We looked at the Language that is used in the Domain
and explicitly modeled it. We started to use this Language as a part of
the code itself. Objects started to expose behavior described by Domain
Experts. In addition to <b>"What?"</b> we started to use <b>"Why? What it does? What is the responsibility of this term?"</b><i>.</i><br />
<br />
However, there
were some aspects that we didn't like - we had leaky
abstraction, since next to those behavioral methods we had
internals-revealing getters. So we decided to separate Model to Read and
Write. Thanks for that we were able to think about Model behavior and
data presentation in other places. We even separated data stores to
optimize their schemas for their purposes. We introduced next questions: <b>"What we want to show? Where we want to show it?"</b><i>.</i><br />
<br />
Then
we introduced the concept of an Event. The Write side was publishing
them as a result of actions. So after each behavioral method we were
able to say what kind of Events should be raised. We started
to think more about processes. We started to think more about business questions: <b>"What changes given behavior should imply? How to name them? How the business process looks like?"</b>.<br />
<br />
We started to dig into the business Domain deeply and express it directly in the code. Without paper documentation (do I hear <i>"Agile"</i>?). After all we finished with explicitly defined Business Processes, and something more: cleaner code. Extremely cleaner! <br />
<br />
<span style="color: #073763; font-size: large;">Do You see it?</span> <br />
<br />
Of
course there can be many other ways to model this
simple Domain, but I wanted to show how the code is changed when
introducing new concepts to it.<br />
<br />
Take a step back dear Reader, and look
at the code from previous parts. Compare each version. Can you see some
more differences? ;)<br />
<br />
And what do you think
about this mindset change? Did you experience it yet? If yes, then in what way?
In similar, or different order? Or maybe completely another way?<br />
<br />
Or maybe you are still at the very first step and you start designing the new functionality of your <i>highly-complicated-and-extremely-expensive-new-cool-application</i> from designing some Pascal records?<br />
<br />
<hr />
<br />
Changing the mindset series:<br />
<ol>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Changing the mindset - part 1 / 4 - Classic approach</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Changing the mindset - part 2 / 4 - Modeling the Domain</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Changing the mindset - part 3 / 4 - Segregation of Responsibility</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/02/changing-mindset-part-4-4-subtle.html">Changing the mindset - part 4 / 4 - Subtle difference</a></li>
</ol>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com2tag:blogger.com,1999:blog-1727031811590975354.post-87855414717680555612012-01-23T22:28:00.000+01:002012-03-30T20:33:31.400+02:00Changing the mindset - part 3 / 4 - Segregation of ResponsibilityIn the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">previous part</a>
we created quite verbose object oriented Model of our Domain. The Domain itself is extremely simple, but try to imagine your Model, which
you are working on day by day, that would be so explicit. Wouldn't be
easier to understand it? Whatever you can do on an object, you do it
directly through methods, which names and arguments, comes strictly from
the Domain Language. And even those objects' names come from this
Language too. Well, this is just OOP done right, isn't it?<br />
<br />
There
is actually one issue with that approach. We want to show some of the
data to the user. And if so, then we have to expose internals. So in
addition to our well-crafted, encapsulating behavior methods, we have leaky getters...<br />
<br />
<span style="font-size: large;"><span style="color: #073763;">Clean the model</span></span><br />
<br />
Let's
do something that may look a little strange for the first time. Remove
those getters. For a moment don't think about the View. Doesn't the
Model look pure and clean without them? It has only behavior as a boundary.<br />
<br />
So,
how to generate the View? First of all we have to note, that we may
have many Views (screens) looking at the same data from different
angles. In classic (anemic) approach we would have one Model and many,
many SQL joins. But we can do something different - something more
explicit.<br />
<br />
We can create another, second Model strictly
optimized for each single View. What is more - we can store those Views
in some document database (NoSQL), so our reads can become really fast. I
won't go into the details with their implementation, since they are fairly simple
anemic-like classes created for each particular View.<br />
<br />
So
we will have the Write side (modeled in terms of Ubiquitous
Language, with strong boundaries definition), and the Read side (modeled
as classic anemic entities highly optimized for particular Views). Both sides will be fully separated and responsible for different user actions.<br />
<br />
Probably
you are wondering - how to feed those Views with data? If we are using
single SQL database, we can just create database views and map them to
View classes with some ORM. But if we use many data storages, then
we have to make something different. <br />
<span style="color: #073763; font-size: large;"></span><br />
<a name='more'></a><span style="color: #073763; font-size: large;">The Past Simple tense</span><br />
<br />
There
is another approach, which gives us a lot more opportunities. After each
method call in Domain Objects we will generate one or more
Events that describe a state transition, and send them to the
Event Bus. They should be named in Past Simple tense and tell what
happened (not what will happen, and not what might). They are
supposed to be relatively small, with no business logic - only state
changes.<br />
<br />
Here are the simplest implementations of aggregate’s methods:<br />
<br />
<pre class="brush:java;">@Entity
@Table(name=”matches”)
public class Match extends AggregateRoot {
@Id
private UUID id;
@Embedded
private Team homeTeam;
@Embedded
private Team awayTeam;
@Basic
private Date matchDate
@Basic
private Date finishDate
@Embedded
private Score score;
public Match(UUID id, Team homeTeam, Team awayTeam) {
this.id = id;
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
apply(new MatchCreatedEvent(id, homeTeam.getId(), awayTeam.getId());
}
public setupMatchDate(Date matchDate) throws MatchAlreadyFinishedException {
if (finishDate != null) {
throw new MatchAlreadyFinishedException();
}
this.matchDate = matchDate;
apply(new MatchDateSetUpEvent(id, matchDate);
}
public finishWithScore(Score score, Date finishDate)
throws MatchFinishedBeforeStartException, MatchAlreadyFinishedExcepion {
if (matchDate == null || finishDate.before(matchDate)) {
throw new MatchFinishedBeforeStartException();
}
if (this.finishDate != null) {
throw new MatchAlreadyFinishedException();
}
this.finishDate = finishDate;
this.score = score;
apply(new MatchFinishedEvent(id, finshDate,
score.getHomeGoals(), score.getAwayGoals());
}
}</pre>
<br />
As you can see, there are three Events (<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">MatchCreatedEvent</span></span>, <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">MatchDateSetUpEvent</span></span>, and <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">MatchFinishedEvent</span></span>) that will be applied to the Aggregate through the method <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">apply()</span></span>from the base class (<span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">AggregateRoot</span></span>). It will take care to replay all those Events on the Event Bus after the end of the transaction. <br />
<br />
On the other side of the Bus, there will be an <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">EventHandler</span></span>
that will be waiting for those Events and populate the View Model.
It is worth to notice, that Events are sent after the transaction on
the Write side finishes. We have to understand that the View side may not be
consistent for all the time with the Write side, but eventually it will...<br />
<br />
Additionally, if our Read side is generated out of Events,
then we need to store those Events in some persistent Event Store… We
can for example serialize them into documents, so hello NoSQL
again. The side effect is that we will have the duplication of data on
the Write side – in regular SQL database, and in Event Store. And those stores has to be consistent all the time...<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">Throw away the database!</span></div>
<br />
If
we have two sources of data in our Write side, than we can really fast
get into troubles – we don’t want to support distributed transaction,
don’t we? So we need to get rid of one of those databases.<br />
<br />
Our choice is… Yes, you guessed it - the SQL database. Delete it!<br />
<br />
Scary, isn’t it? ;)<br />
<br />
But stop for a moment and imagine – no more problems with mappings, joins, queries, database optimization…<br />
<br />
<div style="clear: both; text-align: center;">
<a href="http://cache.ohinternet.com/images/0/0a/Feelsgoodmangreen.jpg" style="margin-left: 1em; margin-right: 1em;" target="_blank"><img border="0" height="320" src="http://cache.ohinternet.com/images/0/0a/Feelsgoodmangreen.jpg" width="295" /></a></div>
<br />
It
can be done, however we have to make some assumptions. Our Aggregates have to be loaded from Events that they produced in the past, so we have
to change something in our Model.<br />
<br />
First of all, we need to
create appropriate methods for handling Events. Those methods will be
called by a <a href="http://domaindrivendesign.org/node/123" target="_blank">Repository</a>
that load the Aggregate (I won’t go much into the details how
Repository should be organized, since it is quite a big topic), and should not be exposed to the outside world. Moreover
we need to remove any property changes from the business
methods, so that we don't repeat ourselves. And in the end, we may (and
want)
remove ORM annotations. <br />
<br />
So our code can look like this:<br />
<br />
<pre class="brush:java;">public class Match extends AggregateRoot {
private UUID id;
private Team homeTeam;
private Team awayTeam;
private Date matchDate
private Date finishDate
private Score score;
public Match(UUID id, Team homeTeam, Team awayTeam) {
apply(new MatchCreatedEvent(id, homeTeam.getId(), awayTeam.getId());
}
private void handle(MatchCreatedEvent event) {
this.id = event.getId();
this.homeTeam = new Team(event.getHomeTeamId());
this.awayTeam = new Team(event.getAwayTeam());
}
public setupMatchDate(Date matchDate) throws MatchAlreadyFinishedException {
if (finishDate != null) {
throw new MatchAlreadyFinishedException();
}
apply(new MatchDateSetUpEvent(id, matchDate);
}
private void handle(MatchDateSetUpEvent event) {
this.matchDate = event.getMatchDate();
}
public finishWithScore(Score score, Date finishDate)
throws MatchFinishedBeforeStartException, MatchAlreadyFinishedExcepion {
if (matchDate == null || finishDate.before(matchDate)) {
throw new MatchFinishedBeforeStartException();
}
if (this.finishDate != null) {
throw new MatchAlreadyFinishedException();
}
apply(new MatchFinishedEvent(
id, finshDate, score.getHomeGoals(), score.getAwayGoals());
}
private void handle(MatchFinishedEvent event) {
this.finishDate = event.getFinishDate();
this.score = new Score(event.getHomeGoals(), event.getAwayGoals());
}
}</pre>
<br />
As you can see, we have now a really nice looking
Aggregate that exposes only behavior, is Event Sourced and doesn’t have
any ORM annotations. <br />
<br />
To load this Aggregate from our
Event Store, the Repository loads all Events that were applied to this
particular Aggregate, and then applies them on the instance of the
Aggregate in order they were generated. One may argue, if this may be slow (after all we can have hundreds of Events for a single instance), but we can always make a Snapshot of the current Aggregate state, and replay only Events that were generated after the Snaphot had been taken.<br />
<br />
After loading the Aggregate, we can execute behavioral
methods on it. They will generate more Events, which will be added to
previous ones, stored. And after the transaction ends, they will be propagated
to the View side and our view model will be updated. Eventually…<br />
<br />
Oh, and one more thing - how hard would it be to give the user some historical data
from some specified point of time? If we have everything stored as a
sequence of Events... Well, I will leave this up to you, dear Reader to
consider. ;)<br />
<br />
<hr />
<br />
Changing the mindset series:<br />
<ol>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Changing the mindset - part 1 / 4 - Classic approach</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Changing the mindset - part 2 / 4 - Modeling the Domain</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Changing the mindset - part 3 / 4 - Segregation of Responsibility</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/02/changing-mindset-part-4-4-subtle.html">Changing the mindset - part 4 / 4 - Subtle difference</a></li>
</ol>
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com2tag:blogger.com,1999:blog-1727031811590975354.post-82034622115603559122012-01-16T23:35:00.000+01:002012-03-30T20:28:58.421+02:00Changing the mindset - part 2 / 4 - Modeling the DomainIn the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">previous part</a> we created Anemic Entity <span style="font-family: "Courier New",Courier,monospace;">Match</span> which was connected to another Anemic Entity <span style="font-family: "Courier New",Courier,monospace;">Team</span>, and they both were ruled by a Service <span style="font-family: "Courier New",Courier,monospace;">MatchService</span>.
We had a bunch of getters and setters in them, which could
be executed from any place that we can imagine. We didn't have any behavior
in our domain objects.<br />
<br />
As I previously said, it can be
a very good approach... Of course, if you are writing your code in C
or Pascal... ;) After all - doesn't those, so called, Entities look like structures
or records? And please do not tell me, that getters and setters are
encapsulating the state...<br />
<br />
If we consider ourselves to be
Object Oriented Programmers, than we have to start thinking differently.
It is not enough to make our objects out of data. We have to teach them
how to act.<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">Where to start?</span></div>
<br />
OK,
so we want to start changing the way we think to more Object Oriented, but where should we begin? If we cannot just define the data and put it into
structures, where to search for the clues?<br />
<br />
The answer is closer than we think. We use it day by day. It is our language. And more specifically - so called <a href="http://domaindrivendesign.org/node/132">Ubiquitous Language</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsvtO0qDBs2PrX-nPx_FxYfIxpBpkA6t0IsllyxuOMS0E826kGO9gWWdynep5_TVht0P1Xjqa_eV29PimZ41gv6AQVCBYbLDvHUSvJhUPeviW5WqIW30LF0Sx5yQQ1VLCJOhkTChqYQMw/s1600/communication.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsvtO0qDBs2PrX-nPx_FxYfIxpBpkA6t0IsllyxuOMS0E826kGO9gWWdynep5_TVht0P1Xjqa_eV29PimZ41gv6AQVCBYbLDvHUSvJhUPeviW5WqIW30LF0Sx5yQQ1VLCJOhkTChqYQMw/s320/communication.jpg" width="320" /></a></div>
<br />
We
have to examine the words that we are using to describe Processes that
takes place in Modeled Domain. We should talk to people, who have the
deepest knowledge about the Domain. They are called <a href="http://domaindrivendesign.org/node/107">Domain Experts</a> and they are extremely important for the Modeler.<br />
<br />
For
the purpose of this series, let's assume that our Domain Expert gave
us the deepest knowledge about the Domain in the previous post. Let's
take a closer look at it.<br />
<br />
<br />
<a name='more'></a><br />
<span style="color: #073763;"><span style="font-size: large;">Words, words, words...</span></span><br />
<br />
Here is the Domain description from the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">previous post</a> with highlighted words that we will use to model our classes.<br />
<blockquote class="tr_bq" style="background-color: #f3f3f3;">
We
have two <b>teams</b> that will play the <b>match</b>. We don’t know the <b>date of the
match</b> at the moment of <b>defining it</b>, but we know which <b>teams will play
against</b> each other. We can later <b>setup the match date</b>, but it can be
done only <b>until the match is finished</b>. We can <b>once finish the match with a
score</b>, but it <b>cannot be finished before its start</b>.<br />
<br />
The
end user wants to see the <b>match</b>: <b>team names</b> that play, <b>match date if is
set</b>, <b>match finish date and score if match was finished</b>.</blockquote>
As
you can see I highlighted mostly nouns and verbs. As you may guess, I
will use nouns to create classes, and verbs to create methods. Of
course, it doesn't have to be always like that. Sometimes from verbs,
or adjectives, or other parts of speech we can derive classes as well.<br />
<br />
Since we are working on the <b>match</b>, I will use this word as a name of an <a href="http://domaindrivendesign.org/node/88">Aggregate</a>. The Root Entity of this Aggregate will be a class called <span style="font-family: "Courier New",Courier,monospace;">Match</span>. It will hold references to other objects aggregated in the <b>match</b>.
It will also expose it's behavior to the outside world, but will not
expose it's internals (at least not for modification at this point).<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Match</span> can be <b>defined </b>- created - and during this process we need to pass two <b>team names</b>,<b> </b>which will play against each other. We could leave them as simple <span style="font-family: "Courier New",Courier,monospace;">String</span> values, but we want to make things more explicit, so we will create a <a href="http://domaindrivendesign.org/node/135">Value Object</a> called <span style="font-family: "Courier New",Courier,monospace;">Team</span>. It will contain the <b>team's name</b> and nothing more. Notice, that we don't need any id in this class. We care only about the value that this object contains - <b>team's name</b>. We don't want to be able to change <b>team's name</b> - that is why the class has to be immutable.<br />
<br />
We can <b>setup the match date</b>, so we will create a method on <span style="font-family: "Courier New",Courier,monospace;">Match</span> that can do that. It may be done only <b>until the match is finished</b>, so we have to explicitly model the exceptional situation during this process.<br />
<br />
In the end we can <b>finish the match</b> and it must be done <b>with a score</b>. So it looks like we have to create another Value Object for holding the <b>score</b>. It will be a parameter to a method that can <b>finish the match</b>. However this method may not be executed if the match end date was <b>before the start date</b>. Also, we cannot <b>finish the match</b> more than <b>once</b>.<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">Teach them how to act! </span></div>
<br />
In the <a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">previous part</a>
we had this Anemic Model, but we want to change it to match closer what our Domain Experts say.<br />
<br />
The first step is to create classes for <span style="font-family: "Courier New",Courier,monospace;">Team</span> and <span style="font-family: "Courier New",Courier,monospace;">Score</span> Value Objects. We may end with something like this:<br />
<br />
<pre class="brush:java;">@Embeddable
public class Team {
private String id;
// constructor + getter
}
@Embeddable
public class Score {
@Basic
private int homeGoals;
@Basic
private int awayGoals;
// constructor + getters
}</pre>
<br />
Now take a look at the <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">Match</span></span>
class. Since it is an Aggregate Root, it will have own lifecycle,
own unique id, and own behavior exposed the world. This behavior will
depict the Transaction boundaries. That means, we should get rid of setters, because they give the ability to change the state outside of the Transaction.<br />
<br />
Since <span style="font-family: "Courier New",Courier,monospace;">Score</span>, <span style="font-family: "Courier New",Courier,monospace;">Team</span> and <span style="font-family: "Courier New",Courier,monospace;">Date</span>
classes are immutable, we can leave getters to those fields (at least
for now) - after all we need to generate the View somehow, right?<br />
<br />
<pre class="brush:java;">@Entity
@Table(name=”matches”)
public class Match extends AggregateRoot {
@Id
private UUID id;
@Basic
private Date matchDate
@Basic
private Date finishDate;
private Team homeTeam;
private Team awayTeam;
private Score score;
public Match(UUID id, Team homeTeam, Team awayTeam) {
this.id = id;
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
}
public setupMatchDate(Date matchDate) throws MatchAlreadyFinishedException {
if (finishDate != null) {
throw new MatchAlreadyFinishedException(<wbr></wbr>);
}
this.matchDate = matchDate;
}
public finishWithScore(Score score, Date finishDate)
throws MatchFinishedBeforeStartExcept<wbr></wbr>ion, MatchAlreadyFinishedExcepion {
if (matchDate == null || finishDate.before(matchDate)) {
throw new MatchFinishedBeforeStartExcept<wbr></wbr>ion();
}
if (this.finishDate != null) {
throw new MatchAlreadyFinishedException(<wbr></wbr>);
}
this.finishDate = finishDate;
this.score = score;
}
// getters
}</pre>
<br />
Notice that we also got rid of the <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">Service</span></span>. Data and behavior are in one place - in the Domain Objects. We have no longer dummy data structures, but actually Object Oriented Model.<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">Those getters…</span></div>
<br />
If at this point you start to consider exposing getters as a code smell, then congratulations - you are on the right track! After all, if the model is more complicated, and we have more Entities in the Aggregate, exposing them through getters may lead to changing them outside of the root and Transaction boundaries. And this may lead to real data corruption.<br />
<br />
From the other side, we need to generate the View, and we cannot do this without accessing the data.<br />
<br />
Try to figure out, how would you deal with this problem. Any ideas? ;)<br />
<br />
<hr />
<br />
Changing the mindset series:<br />
<br />
<ol>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Changing the mindset - part 1 / 4 - Classic approach</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Changing the mindset - part 2 / 4 - Modeling the Domain</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Changing the mindset - part 3 / 4 - Segregation of Responsibility</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/02/changing-mindset-part-4-4-subtle.html">Changing the mindset - part 4 / 4 - Subtle difference</a></li>
</ol>Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-66500570794001573842012-01-11T22:23:00.001+01:002012-03-30T20:28:44.842+02:00Changing the mindset - part 1 / 4 - Classic approachThere are a lot of materials how to model Aggregates and Entities in <a href="http://www.dddcommunity.org/" target="_blank">Domain Driven Design</a>. There are also a lot of materials how to manage your Event Stores, when you are applying <a href="http://cqrs.wordpress.com/" target="_blank">Command Query Responsibility Segregation</a> with <a href="http://martinfowler.com/eaaDev/EventSourcing.html" target="_blank">Event Sourcing</a>. And definitely there are a lot of materials how to combine those ideas together.<br />
<br />
However,
I cannot find any articles about the way that developer’s mindset (and
his code) is being changed when he tries to leave the Anemic Domain
approach and goes into the deep with all the concepts mentioned above.<br />
<br />
So
let’s take a closer look at it. I will provide an example and try to
depict how my mindset was changed when I was adding new things to my
code. I will use a very simple domain and model it in the easiest
possible way, so as not to obscure the picture.<br />
<br />
This is the first article out of four that I will write in the nearest future, so stay tuned.<br />
<br />
One can debate if my approach to modeling the domain is the best, but for this series, I think, is good enough. ;)<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">The example domain</span></div>
<div style="color: #073763;">
<br /></div>
Let’s
think for a moment about very simplified domain for a football match.
For you guys – on the other side of the ocean – it's... ...still a football match
(<a href="http://www.youtube.com/watch?v=AbAIbYqrn_4" target="_blank">it's not a soccer</a> - deal with it!). ;)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaU6L7K3GF3SkynM8kzU-ABnyZbLbPZnAQL_TfgV2O4k6Kgj68KHNad7iOa8XE0vFBgOIMoLNyEruoMhpcaWRInH5HySzenFVbb_Uwp_VjJ294bqeG7fP4tMRv2EUoIkdR8vSjmwf7lYE/s1600/football-field.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaU6L7K3GF3SkynM8kzU-ABnyZbLbPZnAQL_TfgV2O4k6Kgj68KHNad7iOa8XE0vFBgOIMoLNyEruoMhpcaWRInH5HySzenFVbb_Uwp_VjJ294bqeG7fP4tMRv2EUoIkdR8vSjmwf7lYE/s320/football-field.jpg" width="320" /></a></div>
<br />
We
have two teams that will play the match. We don’t know the date of the
match at the moment of defining it, but we know which teams will play
against each other. We can later setup the match date, but it can be
done only until the match is finished. We can once finish the match with a
score, but it cannot be finished before its start.<br />
<br />
The
end user wants to see the match: team names that play, match date if is
set, match finish date and score if match was finished.<br />
<br />
<a name='more'></a><span style="color: #073763;"><span style="font-size: large;">How would You start to model this domain? </span></span> <br />
<br />
Stop here for a moment and imagine you are the person which is about to do this.<br />
<br />
Before
you continue reading, try to answer those simple questions below. Try
to catch your first thoughts and then, compare them with my approach.<br />
<ol>
<li>How would you start? </li>
<li>What would be the first thing that you model out? </li>
<li>How would it be related to the database? </li>
<li>How would you model user actions that can be taken?</li>
<li>Would you even care about it when modeling the domain? </li>
</ol>
You can take a piece of paper and sketch your solution before proceeding. Just for practice. ;)<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">The Anemic Model</span></div>
<br />
The
first thing that comes to mind for experienced developer - who doesn’t
know how fancy things can be ;) – is to create Anemic Entities mapped
with Hibernate and a Service for managing them. It can be something like
this:<br />
<br />
<pre class="brush:java;">@Entity
@Table(name=”teams”)
public class Team {
@Id
private String name;
// getters + setters
}
@Embeddable
public class Score {
@Basic
private int homeGoals;
@Basic
private int awayGoals;
// getters + setters
}
@Entity
@Table(name=”matches”)
public class Match {
@Id
@Type(type="org.hibernate.type.UUIDCharType")
private UUID id;
@Column(updatable=false, insertable=false)
private String homeTeamId;
@ManyToOne
private Team homeTeam;
@Column(updatable=false, insertable=false)
private String awayTeamId;
@ManyToOne
private Team awayTeam;
@Basic
private Date matchDate;
@Basic
private Date finishDate;
private Score score;
// getters + setters
}
public interface MatchService {
void createMatch(UUID matchId, String homeTeamId, String awayTeamId);
void setupMatchDate(UUID matchId, Date matchDate)
throws MatchAlreadyFinishedException;
void finishMatchWithScore(
UUID matchId, int homeGoals, int awayGoals, Date finishDate)
throws MatchFinishedBeforeStartException, MatchAlreadyFinishedExcepion;
}</pre>
<br />
As we can see, we have quite normal, classic
Anemic Entities with private fields and public setters/getters. They are
ruled by the <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">MatchService</span></span> and we can pray that nobody else will modify their fields from other places in the system...<br />
<br />
We have even some <span style="font-family: "Courier New",Courier,monospace; font-size: small;">@ManyToOne</span> annotations that join our <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">Matches</span></span> with <span style="font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">Teams</span></span>.<br />
<br />
We
also have probably some Unit Tests for the Service that will check if
correct fields are set during service method calls, and if exceptions
are thrown correctly. It’s far less likely, that we will have Unit Tests
checking if fields that we don’t want to set, are actually not set during those
invocations, but who would care… Right? ;)<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">It still works</span></div>
<br />
As
you can imagine, this approach can work perfectly fine. There are A LOT
of services modeled in this manner and they are profitable.<br />
<br />
However,
I think that after some time, without changing the mindset, the code
above can be modified so many times, that it will become simply
unreadable. The service implementation can have even thousands of lines.
There is so much implicity inside, that in a moment there can be no
one, who will understand the model.<br />
<br />
In upcoming posts I will try to change this code, step by step, to make it more explicit and more maintainable.<br />
<br />
So how about your model? Is it similar?<br />
<br />
<hr />
<br />
Changing the mindset series:<br />
<ol>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-1-4-classic.html">Changing the mindset - part 1 / 4 - Classic approach</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-2-4-modeling.html">Changing the mindset - part 2 / 4 - Modeling the Domain</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/01/changing-mindset-part-3-4-segregation.html">Changing the mindset - part 3 / 4 - Segregation of Responsibility</a></li>
<li><a href="http://www.eventuallyinconsistent.com/2012/02/changing-mindset-part-4-4-subtle.html">Changing the mindset - part 4 / 4 - Subtle difference</a></li>
</ol>
<br />
<br />
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com0tag:blogger.com,1999:blog-1727031811590975354.post-48090124594448032082012-01-02T20:19:00.001+01:002012-03-30T20:28:08.719+02:002011's mindfucksDo you know what mindfuck is? Quoting the <a href="http://www.urbandictionary.com/define.php?term=mindfuck" target="_blank">urban dictionary</a>:<br />
<blockquote class="tr_bq">
<i>An idea or concept that shakes one's previously held beliefs or assumptions about the nature of reality.</i></blockquote>
I like this definition, but I would widen it a bit. This idea or concept doesn't have to be based on held beliefs nor assumptions. It can also broaden the horizon by introducing something completely new. However this has to really change one's perceiving of the reality. Once you see it, you will not be able to miss it again.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfgrQ7NrNJb9MCgmWClTv1SCkRtdIr__6uQPPF2u8NQVzCKXghGkYVVWgBM6jBCgvkvyIjscvAODPGUPIhFwLfK6GoM4Ev2uSveWjXsrlFUlPzt3OFElIpnQSKfKHi6xbfg_oFUlXBARM/s1600/mindfuck.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfgrQ7NrNJb9MCgmWClTv1SCkRtdIr__6uQPPF2u8NQVzCKXghGkYVVWgBM6jBCgvkvyIjscvAODPGUPIhFwLfK6GoM4Ev2uSveWjXsrlFUlPzt3OFElIpnQSKfKHi6xbfg_oFUlXBARM/s400/mindfuck.jpg" width="400" /></a></div>
<br />
The 2011 has gone and it is a part of the past right now. It is a good moment to stop for a while and look backwards to see what has happened during the last twelve months.<br />
<br />
There were two people who messed up in my head in the previous year. I met both on conferences in my home city, Kraków (Cracow).<br />
<br />
The first person was Linda Rising. I haven't heard about her before, but she gave such a great prelection on the <a href="http://2011.33degree.org/" target="_blank">33rd Degree</a>, that I decided to dig deeper with her work and I don't regret it. <br />
<br />
The second person was Greg Young. I knew him from many publications, videos and podcasts. I was hoping to learn something new and exciting, and I wasn't dissapointed. His workshops during <a href="http://www.11.jdd.org.pl/en" target="_blank">JDD11</a> were really mindblowing.<br />
<br />
<a name='more'></a><div style="color: #073763;">
<span style="font-size: large;">The Power of Retrospection</span></div>
<br />
Linda Rising is a world wide known consultant on Agile, Patterns, Retrospectives and others. During the 33rd Degree conference she was talking about Retrospectives. She was speaking very precisely and with great passion. I really enjoyed her lecture.<br />
<br />
I never liked Retrospective meetings, since they were boring and I thought that they don't add any value to the process. I guess I've never been on a good one before.<br />
<br />
After the Linda's lecture, I realized that each iteration should be an experiment. Each one should be a little different than the previous one. We always have to try to change something, measure it and in the end (during the Retrospective meeting) make the summary and new plans for next experiments. <br />
<br />
I remember very clearly when this nice, probably twice older than me, lady was talking about the people who do the best retrospectives in the world... The elder people! Yes, our grandparents! They always tend to look into the past and consider what would they do differently if they were young again, and what they would not change at all. We should learn to look in this same way as they do.<br />
<br />
The real mindfuck for me, on the Retrospective topic, was the possibility to adapt those techniques to the personal life - not only at work. Just like our grandparents do...<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">The Power of toString()</span></div>
<br />
Greg Young is a world wide known IT specialist with many years of experience. During the JDD 11 conference he was leading the workshops about... testing. During three hours we have created our own testing framework based on the top of JUnit, which was doing much more than validating the code.<br />
<br />
Let's look at the Smalltalk for a moment. In this language each method invocation is actually a message being sent to the object. And this message is actually a regular object too.<br />
<br />
On those messages we can invoke an old and almost forgotten method - <span style="font-family: "Courier New",Courier,monospace;">toString()</span>. Usually we use it during debugging, or to log something. We don't tend to find it valuable for the business problems. But if we stop for a moment and think how this method can be written in Commands and Domain Objects, we will get a whole new bunch of possibilities. Especially when using Event Sourcing as a storage mechanism.<br />
<br />
I won't get into much details about this idea, because I suppose we can read it in Greg's upcoming book <i>"<a href="http://www.amazon.com/Event-Centric-Simplicity-Addison-Wesley-Signature/dp/0321768221" target="_blank">Event Centric</a>"</i>.<br />
<br />
In general the idea is to bring the <span style="font-family: "Courier New",Courier,monospace;">toString()</span> method back to business through the tests. We should write our business tests scenarios in a Given-When-Then pattern and then apply this method in an appropriate context.<br />
<br />
As Given we can provide collection of Events that were applied earlier, or the Tested Object itself prepared for this particular scenario. We can call <span style="font-family: "Courier New",Courier,monospace;">toString()</span> on those Events, or directly on the Tested Object and write the output in a file with scenario description. Later we can call <span style="font-family: "Courier New",Courier,monospace;">toString()</span> on the Command, treated as When, that is beeing sent and append the output to the file. In the end we can call <span style="font-family: "Courier New",Courier,monospace;">toString()</span> on the Tested Object or on the collection of Events, that were raised during the Command invocation and append the output to the file as Then.<br />
<br />
In this way we can easily generate business documentation based on the test scenarios. We can go to our clients and give them the output of our tests - they will be able to actually understand them! After all we are writing test, aren't we? And if we are, then why do not use them for more than quality checks?<br />
<br />
<div style="color: #073763;">
<span style="font-size: large;">The next year...</span></div>
<br />
I expect, that the new 2012 year will bring me much more mindfucks, than previous one. I am looking forward to face that, since there are not so many things comparable to a good blown mind. ;)<br />
<br />
And did you experience any mindfucks during the past year?<br />
<br />
<br />Piotr Wyczesanyhttp://www.blogger.com/profile/02381372089894674945noreply@blogger.com1