<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Cristian Olaru</title>
    <description>The latest articles on DEV Community by Cristian Olaru (@colaru).</description>
    <link>https://dev.to/colaru</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F157524%2F6e1f7fa5-3260-48c0-8753-818ade67b6f6.jpg</url>
      <title>DEV Community: Cristian Olaru</title>
      <link>https://dev.to/colaru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/colaru"/>
    <language>en</language>
    <item>
      <title>Java Number One in 2019?</title>
      <dc:creator>Cristian Olaru</dc:creator>
      <pubDate>Mon, 23 Dec 2019 10:24:26 +0000</pubDate>
      <link>https://dev.to/colaru/java-number-one-in-2019-34i0</link>
      <guid>https://dev.to/colaru/java-number-one-in-2019-34i0</guid>
      <description>&lt;p&gt;&lt;strong&gt;End of the year! Some facts about Java in 2019! Is it good? Is it bad? Your thoughts?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 2019 Java is still number one on Tiobe index - &lt;a href="https://www.tiobe.com/tiobe-index/"&gt;https://www.tiobe.com/tiobe-index&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oracle Java One conference is now renamed to Code One&lt;/p&gt;

&lt;p&gt;Android is Kotlin first announced by Google. Google will deliver the Android APIs first in Kotlin and after this in Java&lt;/p&gt;

&lt;p&gt;Refactoring 2 by Martin Fowler has the samples in JavaScript and not Java, like in the first version of the book&lt;/p&gt;

&lt;p&gt;Pivotal (Spring) was acquired by VMware&lt;/p&gt;

&lt;p&gt;RedHat (JBoss) was acquired by IBM&lt;/p&gt;

&lt;p&gt;Java EE is JAKARTA EE now out of Oracle garden and in the Eclipse Foundation - &lt;a href="https://jakarta.ee/"&gt;https://jakarta.ee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oracle refuses to let the &lt;em&gt;javax&lt;/em&gt; package to be used by Jakarta&lt;/p&gt;

&lt;p&gt;September 2019 → Java 13 in many distributions: &lt;a href="https://sdkman.io/jdks"&gt;https://sdkman.io/jdks&lt;/a&gt; (but everyone I know is still blocked at Java 8)&lt;/p&gt;




&lt;p&gt;For 2020 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.oracle.com/code-one/"&gt;Oracle Code One&lt;/a&gt; Is Moving to Las Vegas -&amp;gt; September 21–24, 2020!&lt;br&gt;
&lt;a href="https://springoneplatform.io/"&gt;Pivortal Spring One&lt;/a&gt; Will be in Seattle -&amp;gt; September 21–24, 2020!&lt;/p&gt;

</description>
      <category>java</category>
      <category>javaee</category>
      <category>spring</category>
      <category>java8</category>
    </item>
    <item>
      <title>Clean Architecture - a short book review</title>
      <dc:creator>Cristian Olaru</dc:creator>
      <pubDate>Tue, 13 Aug 2019 19:50:04 +0000</pubDate>
      <link>https://dev.to/colaru/clean-architecture-a-short-book-review-3no9</link>
      <guid>https://dev.to/colaru/clean-architecture-a-short-book-review-3no9</guid>
      <description>&lt;p&gt;This is a review for the &lt;a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164"&gt;Clean Architecture book&lt;/a&gt; written by &lt;a href="https://blog.cleancoder.com/"&gt;Uncle Bob&lt;/a&gt; (for the first three parts). I read it on my holidays, and I must confess is not what I can name a 'holidays book'. This, because it is a very serious book about programming written by someone with more than 50 years in this field - that 50 years of programming history are reflected everywhere in this book. You need some quiet place to reflect about it, and a net connection to browse additional material.&lt;/p&gt;

&lt;p&gt;First, I will make a description of the book parts with the essential aspects discussed. In the end, I will express my feelings and impressions about the content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--znC3LJJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/duesyq4zvwgmkm19vad7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--znC3LJJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/duesyq4zvwgmkm19vad7.jpg" alt="Clean Architecture book photo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PART 1 - &lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design and architecture are the same - architecture is sometimes considered to be the structuring at the high level of the system and design to be the structuring of the low level of the system. Both are architecture!&lt;/p&gt;

&lt;p&gt;The goal of architecture is to 'minimise the human resources required to build and maintain the required system'. The author gives an example of a wrong application, where for release 8, the code was 40 times more expensive to produce than in release 1.&lt;/p&gt;

&lt;p&gt;The software provides two values to the stakeholders: behaviour and structure. The developers have the responsibility to keep both these values high. The software has to be 'soft' = easy to be changed and maintained. That's why the structure = architecture is essential.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8VsCYV0i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ss88armov887l9u5dgxj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8VsCYV0i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ss88armov887l9u5dgxj.jpg" alt="Clean Architecture book photo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PART 2 - &lt;strong&gt;Programming Paradigms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This part of the book is dedicated to the programming paradigms. There are three paradigms that are discovered between 1958 and 1968, and no paradigms were discovered in the following decades. This is a sign that these are all we can have:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structured programming&lt;/strong&gt; = programming based just on these structures of control: sequence, selection and iteration. 'Go To statement considered Harmful' article of Dijkstra imposed the 'discipline on direct transfer of control' - jumps from one line of code to others are evil and are not needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Object Oriented programming&lt;/strong&gt; - in ALGOL the class/object concept was born = the function call stack frame can be moved in Heap, the function can become the class constructor, and the inner functions can be the class methods.&lt;/p&gt;

&lt;p&gt;The essence of OO consists not in the ability to model the world with objects - 'everything is an object' - but by the benefits of OO: encapsulation, inheritance and polymorphism. While encapsulation, inheritance and polymorphism can be achieved in non-POO languages, in POO these are more simple or even trivial to be expressed. &lt;/p&gt;

&lt;p&gt;And especially the polymorphism is giving us dependency inversion = absolute control of all source code dependencies in the system → independent deployability → independent develop-ability. OO polymorphism imposes 'discipline on indirect transfer of control'.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functional programming&lt;/strong&gt; - variables in a functional language do not vary = are immutable. This is a big advantage because all the concurrent problems are because of mutable variables. &lt;/p&gt;

&lt;p&gt;One idea is to use a technique named 'event sourcing' = to evict the update/delete operations (CR from CRUD) and to keep a ledger of events like in accounting - anytime we can recalculate the state from events. Functional programming is about 'discipline imposed upon variable assignment.' &lt;/p&gt;

&lt;p&gt;As a conclusion, the software these days is composed of &lt;strong&gt;sequence, selection, iteration and indirection&lt;/strong&gt;. The hardware changed drastically in time, but the software remains the same as in the first days of programming.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kj-sZMAO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/m2pm4afs23cpswnc8ey5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kj-sZMAO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/m2pm4afs23cpswnc8ey5.jpg" alt="Clean Architecture book photo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Part 3 - &lt;strong&gt;Design Principles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a description of the SOLID principles seen from the architecture point of view. SOLID is about how to arrange our functions and data into classes and how classes should be interconnected like 'bricks in the walls'. The next part will talk about how to structure components in the systems = 'rooms in the buildings'.&lt;/p&gt;

&lt;p&gt;These principles are used to create structures 'bricks in the walls' that tolerate change and make the code easy to understand = the global scope of design/architecture.&lt;/p&gt;

&lt;p&gt;The principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;ingle Responsibility Principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A module should have one, and only one reason to change. More precise, to only one actor: user or stakeholder. The classical solution for this problem is to split into more functions/classes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;O&lt;/strong&gt;pen/Closed Principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A software artefact should be open for extension but closed for modifications. An example is shown about how we can protect higher-level components from changes in lower-level components.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt;iskov Substitution Principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Barbara Liskov (1988) If for each object o1 of type S there is an object o2 of type T such for all programs P  defined in terms of T, the behaviour of P is unchanged when o1 is substituted for o2 then S is a subtype of T. The author is using the classical rectangle-square problem to reflect the principle.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;nterface Segregation Principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Depending on something that carries baggage that you don't need can cause you troubles. So split the interfaces in pieces and in this way you will evict inutile recompilations and redeployments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt;ependency Inversion Principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Interfaces are less volatile than implementations. So don't refer to volatile concrete classes, but interfaces. The author shows an Abstract Factory pattern implementation for illustrating the dependency inversion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RVDFz13W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/81uzh87f3pe0vf0utdim.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RVDFz13W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/81uzh87f3pe0vf0utdim.jpg" alt="Clean Architecture book photo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My ideas(maybe not so well articulated, so you can skip this part)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three in one coffee&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think the tendency in modern languages is to have all three programming paradigms inside - structural, OO and functional.  For example, Java has structural control blocks similar to the C language. It is OO by design. And in these days it has functional support starting with Java 8 lambda functions and streams (functional also with Groovy support). Javascript (another language that I am interested in) is structural at ES5 level, and become OO at ES6, and can be used in a functional style with libraries like &lt;a href="https://underscorejs.org/"&gt;Underscore.JS&lt;/a&gt; and &lt;a href="https://lodash.com/"&gt;Lodash JS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First time I saw a computer and I wrote a program&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I miss 30 years of experience from my uncle Bob's history - that's why we need an uncle to tell us stories about the past!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I started to use Java in the 2000s, and it was my primary programming language till now. My feeling is that we had two waves of POO. First was  C++ and Objective C, where we still can see pointers and references to the machine. The second wave was Java and C# with Virtual Machines (JVM and CLR), Garbage Collectors, and no pointers. These were high-level programming language where we think just in objects - without any reference to the machine in our code (Threads, Sockets, etc. are OS-specific and are modelled as objects). Will fill the machine maybe, just when we start the JVM, and we configure the memory, GC type.&lt;/p&gt;

&lt;p&gt;But the first language I learned in school was &lt;a href="https://ro.wikipedia.org/wiki/BASIC"&gt;BASIC&lt;/a&gt; in the '90s, and it has GOTO, and there I was giving numbers to the lines, and I remember I used to jump from one line to another - imperative programming we named it. The second main language in school was &lt;a href="https://en.wikipedia.org/wiki/Pascal_(programming_language)"&gt;PASCAL&lt;/a&gt; - structured programming (procedural). &lt;/p&gt;

&lt;p&gt;In that time the Z80 (Zilog) processors were used at home with 64K memory - x86 (Intel/AMD) was already seen as the future but were too expensive at that time to have one at home - still remember first 486, and 586 (Pentium) we have at school. I still remember those games on tapes we used to play all day. I do some assembly language subroutines also on Z80 inspired by the games.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typed/dynamic languages debate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think a subject of the programming history is also the typed/dynamic typed dispute in languages. See the languages from the last time (Scala, Groovy). Static compile checked languages like Java, TypeScript versus runtime dynamic languages like Groovy (also running on JVM) or JavaScript. The tendency of dynamic languages to be scripting oriented - a lot of semantic in a concise syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functional means just immutability?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not sure what is the essence of functional programming (if immutability) - I think that the possibility to apply a function to a data structure, to make chain of functions in a declarative way, to have the function as a citizen of the language passing it as a parameter - to do all this map/reduce stuff that is hard to be done in structured programming.&lt;/p&gt;

&lt;p&gt;Immutability is not the single way to simplify the concurrency problems (locks, pools of threads). Event loops/single-threaded per core programming like Node.JS/Vertex can help as to escape from classical concurrency problems (works hand in hand with non-blocking but is imposing you to have all your system modelled by small non-blocking events - or use workers for long time jobs).&lt;/p&gt;

</description>
      <category>unclebob</category>
      <category>cleanarchitecture</category>
    </item>
    <item>
      <title>The Software Craftsman - a short book review</title>
      <dc:creator>Cristian Olaru</dc:creator>
      <pubDate>Sat, 03 Aug 2019 07:37:11 +0000</pubDate>
      <link>https://dev.to/colaru/the-software-craftsman-a-short-book-review-17dk</link>
      <guid>https://dev.to/colaru/the-software-craftsman-a-short-book-review-17dk</guid>
      <description>&lt;p&gt;I use to take a book with me on holidays to read something interesting. There are some moments on my holidays when I have some time to read. Especially when I am waiting for the plane, I am in the flight time or on the beaches &lt;strong&gt;under the Spanish sun&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This holidays I took with me &lt;a href="https://www.amazon.es/Software-Craftsman-Professionalism-Pragmatism-Robert/dp/0134052501" rel="noopener noreferrer"&gt;The Software Craftsman&lt;/a&gt; - Professionalism, Pragmatism, Pride written by &lt;a href="https://twitter.com/sandromancuso?lang=ro" rel="noopener noreferrer"&gt;Sandro Mancuso&lt;/a&gt;. I thought it would take the entire holidays to read the book. I was wrong because I read it in 4 days because it catches me. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffjqmjuqd6gn5x11jnmem.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffjqmjuqd6gn5x11jnmem.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From far, it is the best book I read this year - even it doesn't have one line of code. Maybe from the way it is written with short real-life stories from the author career, many am them being a "deja vu" for me. &lt;/p&gt;

&lt;p&gt;I also correlated this book content with this fascinating Uncle Bob Martin video presentation - &lt;a href="https://www.youtube.com/watch?v=ecIWPzGEbFc" rel="noopener noreferrer"&gt;The Future of Programming&lt;/a&gt;, which is the past and the future of programming. I also read this article at the same time and is the first time when I heard about planes crashing because of outsourcing software. The material is this &lt;a href="https://www.bloomberg.com/news/articles/2019-06-28/boeing-s-737-max-software-outsourced-to-9-an-hour-engineers" rel="noopener noreferrer"&gt;Boeing’s 737 Max Software Outsourced to $9-an-hour Engineers&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Book structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I will introduce the book chapters with a single main idea I liked most in each section.&lt;/p&gt;

&lt;p&gt;The first part is a retrospective of the current state of works in the programming.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Software Development in the twenty-first century&lt;/strong&gt; - seniority in the 90s "writing code that no one else could understand would make you a senior developer straight-away."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agile&lt;/strong&gt; - Agile transformation is fake because "project managers become Scrum masters. And agile became the new name of the old way of working"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software Craftsmanship&lt;/strong&gt; - introduction and explanations of the Software Craftsmanship manifesto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Software Craftsmanship attitude&lt;/strong&gt; - about keeping ourselves up to date&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working software&lt;/strong&gt; - "working software is not enough" and why "developers are scared to touch the existing code" to add new features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heroes, Goodwill, and Professionalism&lt;/strong&gt; - learning how to say "no" and give alternatives (no .. but)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical practices&lt;/strong&gt; - introducing XP practices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The long road&lt;/strong&gt; - "assuming that money is off the table - knowledge workers are motivated by three things: autonomy, mastery and purpose."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The second part is about the actions we have to do to exit from the current state.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Recruitment&lt;/strong&gt; - First three chapters are about recruiting because it is the first steps for changing something&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interviewing Software Craftsmen&lt;/strong&gt; - "interviews are a two-way street."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview anti-patterns&lt;/strong&gt; - don't make the candidate look like a fool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost of low morale&lt;/strong&gt; - how we lose it and how we can recover it injecting passion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Culture of learning&lt;/strong&gt; - we have to create a culture of learning in our company&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Driving technical changes&lt;/strong&gt; - sceptics: the uninformed, the herd, the cynic, the burned, the time-crunched, the boss, the irrational, the indifferent, the wronged, the inept, the ivory-tower architect, the insecure, the fanboy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pragmatic Craftsmanship&lt;/strong&gt; - '... to be able to change the code almost as quietly they change their minds'&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A career as a software craftsman&lt;/strong&gt;  - passion is the main word&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Some random ideas&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I try to expose here what impressed me much on this book in no given order.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuaqydb2rqrer3sh3ga25.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fuaqydb2rqrer3sh3ga25.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outsourcing problems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was impressed by the story of the author experience in Brazil working in an outsourcing company. There he was forced to slip in his car in the company parking because he didn't have enough time to commute because of the overtime. And his colleagues were coming to him in the night to ask questions about the project.&lt;/p&gt;

&lt;p&gt;Outsourcing projects problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the wrong way of thinking that &lt;strong&gt;the diagrams and specs are the only important thing&lt;/strong&gt; because &lt;strong&gt;writing code is simple, and the developers are not important&lt;/strong&gt; and they are like factory workers&lt;/li&gt;
&lt;li&gt;the wrong idea that we will stay in our cubicles, and we will produce beautiful specifications for the teams over the sees - and they will create our fantastic product&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The old way of writing code like in the '90s (still practised by many today)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;** cryptic writing code** similar with the algorithms we lean in school and &lt;strong&gt;the IDE debugger used on day by day basis&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;the wrong practice of &lt;strong&gt;writing generic code to the extreme&lt;/strong&gt; and never write specific code is also something that originated in the school (it's a kind of premature optimisation)&lt;/li&gt;
&lt;li&gt;the code can be written so unclean, so &lt;strong&gt;we became afraid to make changes&lt;/strong&gt; even with all these extraordinary refactoring tools we have today in the IDEs&lt;/li&gt;
&lt;li&gt;and the things are going from wrong to worse as time is passing; &lt;strong&gt;first that will leave are the good devs&lt;/strong&gt;; the rest will stay and will make the tragedy bigger&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Career inside companies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;many people are entering in political games &lt;strong&gt;wanting to become part of the management instead of being software craftsmen&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;that's why someone from Eastern Europe is saying that if you &lt;strong&gt;are over 30, and you are a developer in the company than you are failure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sometimes we have to say "no" to management; in fact, we have to give alternatives: "&lt;strong&gt;no ... but&lt;/strong&gt;"&lt;/li&gt;
&lt;li&gt;the sceptic typologies of people from companies resisting to change are very well described: &lt;strong&gt;the uninformed, the herd, the cynic, the burned, the time-crunched, the boss, the irrational, the indifferent, the wronged, the inept, the ivory-tower architect, the insecure, the fanboy&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;the problem of treating the &lt;strong&gt;programmers as factory workers&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Scrum and XP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scrum process is about "made the right software" vs XP techniques are about  "made the software right."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a balance between the two is needed&lt;/li&gt;
&lt;li&gt;Scrum was not well adopted (because &lt;strong&gt;managers are becoming scrum masters&lt;/strong&gt;, &lt;strong&gt;certifications to be considered enough&lt;/strong&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Scrum and Lean Startup is giving value for the business&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9mmrom7gjarucjvpgqr7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9mmrom7gjarucjvpgqr7.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Inspirational resources links&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The future of programming - &lt;a href="https://www.youtube.com/watch?v=ecIWPzGEbFc" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=ecIWPzGEbFc&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Boeing accident - &lt;a href="https://www.bloomberg.com/news/articles/2019-06-28/boeing-s-737-max-software-outsourced-to-9-an-hour-engineers" rel="noopener noreferrer"&gt;https://www.bloomberg.com/news/articles/2019-06-28/boeing-s-737-max-software-outsourced-to-9-an-hour-engineers&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Extreme Programming - &lt;a href="http://www.extremeprogramming.org/" rel="noopener noreferrer"&gt;http://www.extremeprogramming.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>softwarecraftsman</category>
    </item>
    <item>
      <title>GraphQL - The REST is over</title>
      <dc:creator>Cristian Olaru</dc:creator>
      <pubDate>Wed, 31 Jul 2019 11:11:29 +0000</pubDate>
      <link>https://dev.to/colaru/graphql-the-rest-is-over-1a4h</link>
      <guid>https://dev.to/colaru/graphql-the-rest-is-over-1a4h</guid>
      <description>&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the last years, I was very happy exposing REST Web Services consumed by Angular JS clients (and using Swagger for documenting the API). But it was a situation in the last year when we had a huge data model with hundreds of entities exposed as REST resources. In that case, the &lt;strong&gt;REST was not enough&lt;/strong&gt;. So, &lt;strong&gt;my rest was over&lt;/strong&gt; - I started to search for a better way to expose and consume web services and I found something named &lt;a href="https://graphql.org/"&gt;GraphQL&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_x8yrtvI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2wme77mlotjqj7gizbrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_x8yrtvI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2wme77mlotjqj7gizbrl.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This doesn't mean that REST is over. A GraphQL API can stand in front of a REST API or the tho APIs can coexist at the same time. The idea is that there is a new way of consuming/exposing an API. It is better in the case we have a schema on the server-side. There is &lt;a href="https://apifacade.com/graphql-for-the-rest-of-us"&gt;GraphQL For The Rest of Us&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9BQagNWX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vtbm9gdiucnqps34d4bp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9BQagNWX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vtbm9gdiucnqps34d4bp.jpg" alt=""&gt;&lt;/a&gt;&lt;br&gt;
Image credit &lt;a href="http://howtographql.com"&gt;http://howtographql.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The application story&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application was a classical client-server app with Java/EJB in the backend exposing a set of JAX-RS REST web services to an Angular client. We used JPA for persistence and we modeled the entire graph of entities using JPA annotations. &lt;/p&gt;

&lt;p&gt;We split the domain in some aggregates with dozen of classes and with an aggregate root - mainly using IDs as fields instead of foreign keys. We exposed an end-point for some aggregate roots - in a &lt;strong&gt;rest-full way&lt;/strong&gt;. The requirement of the project was to expose just CRUD operations in our endpoints (of corse not CRUD wasn't enough) because the business flows are part of the client application. This was good because we can respect the REST principle of having resources (NOUNS) with the state modified by the HTTP commands (VERBS).&lt;/p&gt;

&lt;p&gt;We used Swagger for documented the API - the frontend team was able to call our API from Swagger UI in realtime. The Swagger/&lt;a href="https://www.openapis.org/"&gt;Open API&lt;/a&gt; documentation was generated dynamically from the annotated endpoints. The Angular front-end was generating the TypeScript client from Swagger using its code generation facilities. Everything seems to be fine.&lt;/p&gt;

&lt;p&gt;But something wasn't all right. Our JPA entities are also our REST resources. In JPA the entities are linked together in a graph according to the database schema. When we get the aggregate root, we get the entire graph of entities with all fields. And because the entities are the resources the client is receiving a &lt;strong&gt;huge JSON file&lt;/strong&gt; each time. Usually, in the Angular components, not the entire graph was needed, and not all the fields of the resources. &lt;/p&gt;

&lt;p&gt;What we will do if we have a data model like in this story, a data model in which the company invested years to create. What we will do if we have a model like &lt;a href="https://apis.guru/graphql-voyager/"&gt;this &lt;strong&gt;GitHub data model&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R7jPrmOJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qd9ji1b9x16vtd0vytir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R7jPrmOJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qd9ji1b9x16vtd0vytir.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
Image credit: &lt;a href="//howtographql.com"&gt;howtographql.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There are a few patches&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;One is to use some annotation from the marshaling/un-marshaling framework @JsonIgnore, @XmlTransient on our entities to simplify the JSON received by the client. This is problematic because in some endpoints we need to send to the client some fields of the resources in other cases different fields - annotating the entities/resources will suppress the fields for all client calls.&lt;/p&gt;

&lt;p&gt;Another solution is to create different WS endpoints and to hide some fields when we sent a response to the client. To use for example a different package of resources different from the domain entities and to populate them from entities when we send back the response. This is also problematic because we introduce more complexity - our API will be more in the RPC style (not REST) and we will have extra work in populating the resources from entities. And we have to write Named Queries or Criteria Queries to fetch the right data from the database and not just CRUD operations.&lt;/p&gt;

&lt;p&gt;The last solution I know is to have real isolated resources and not graphs of objects exposed on the server-side. In this case, we will have multiple calls maybe &lt;strong&gt;1+n calls&lt;/strong&gt; on the cases of collections. So this is also a problem because of the multitude of calls we have to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The REST is not enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This kind of project from the previews story shown a downside of the REST - it is not good for this case when we have a rich domain on the server-side - a graph of objects. In this case, the generated JSON is huge and enriched with un-necessary information. The solutions to solve this problem will lead us out of the REST style to remote procedures calls (RPC). Or to complicate the backend using some extra code - not use just simple ORM CRUD operations.&lt;/p&gt;

&lt;p&gt;For these cases, it seems that GraphQL is the solution. We will ask the server just for the pice of information we need. Because we don't want the entire schema. REST is fine when we have isolated pieces of information like system messages, notifications. But is not good for the case we have a big schema. &lt;/p&gt;

&lt;p&gt;And schemas are everywhere - documents (XML, PDF, JSON), the file/folders file systems, relational databases (even if is a forced schema), DOM, etc. REST is ok for non-relational databases (MONGO-DB) where we have collections of entities. But is a relational database we store a graph of objects (even if we do this in a forced way). That's how we store the majority of the data we have now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introducing GraphQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GraphQL was born from the effort of the Facebook team to accommodate the application to the modern world of mobiles. It is used inside Facebook along with other technologies like React or Jest, also invented by this company. The complete story can be found in this &lt;a href="https://youtu.be/783ccP__No8"&gt;GraphQL original documentary&lt;/a&gt;, presented by the developers of the technology.&lt;/p&gt;

&lt;p&gt;GraphQL was at the beginning just a specification about how to interact with the data from the client perspective in a declarative way. First, a reference implementation was created for Java Script, and other developers started to implement it on other programming languages. It is not a way to expose an API on the server-side, but a way to consume data from the client-side. It doesn't specify the dataset that is exposed if it is a database or a REST API. It doesn't specify the communication protocol that is used - if it is HTTP or not!&lt;/p&gt;

&lt;p&gt;GraphQL provides a method to document the API, a way to specify the API capabilities named &lt;strong&gt;Schema&lt;/strong&gt;. Historically speaking, we have GraphQL/Schema as we have SOAP/WSDL, REST/Swagger-OpenAPI. We can start from this schema to generate de client or the server in the same way we do with the other types of web services APIs (REST or SOAP).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to learn&lt;/strong&gt; GraphQL&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--atWvat3j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/whrmbb7vmqagn1rlsrrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--atWvat3j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/whrmbb7vmqagn1rlsrrl.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First watch this video named &lt;a href="https://www.youtube.com/watch?v=783ccP__No8&amp;amp;feature=youtu.be"&gt;GraphQL - The documentary&lt;/a&gt; to understand how, when and why this technology was born&lt;/li&gt;
&lt;li&gt;Learn as match you can from these &lt;a href="https://www.howtographql.com/"&gt;GraphQL video tutorials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Make some real calls with an existing UI client and on an &lt;a href="https://www.graphqlhub.com/"&gt;real online APIs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Study the support for GraphQL in your preferred programming language&lt;/li&gt;
&lt;li&gt;Implement an API on a simple schema &lt;/li&gt;
&lt;li&gt;Read the &lt;a href="https://graphql.github.io/graphql-spec/June2018/"&gt;GraphQL spec&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;See how &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby.js&lt;/a&gt; implements the source and transformers plugins&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Gatsby.js vision&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I can't finish this article without saying something about &lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby.js&lt;/a&gt;. Why can I name it &lt;strong&gt;the next WordPress&lt;/strong&gt;? Because it has everything, Wordpress has a pluggable system with themes, easy to extend by developers, based on the right abstractions. It is a way to create micro frontends combining React components with GraphQL schemas. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j-KVKINZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hjn0qirbiwuqffehq2cs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j-KVKINZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hjn0qirbiwuqffehq2cs.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be honest, I dreamed of this for a long time in the form of a combination of &lt;a href="https://www.webcomponents.org/"&gt;Web Components&lt;/a&gt; and &lt;a href="https://martinfowler.com/articles/microservices.html"&gt;Microservices&lt;/a&gt; - but it seems that React/GraphQL is offering this under the Gatsby.js umbrella right now when you read this.&lt;/p&gt;

&lt;p&gt;Gatsby is offering a good option to create &lt;strong&gt;static progressive web apps&lt;/strong&gt;. For the GraphQL part, Gatsby is offering a set of &lt;a href="https://www.gatsbyjs.org/plugins/"&gt;sources and transformers plugins&lt;/a&gt; that are letting you pull data from headless CMSs, SaaS services, APIs, databases, your file system or any other source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inspirational Resources Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GraphQL documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GraphQL documentary - &lt;a href="https://youtu.be/783ccP__No8"&gt;https://youtu.be/783ccP__No8&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Technology site -&lt;a href="https://graphql.org/"&gt;https://graphql.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to GraphQL - &lt;a href="https://www.howtographql.com/"&gt;https://www.howtographql.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Introduction to GraphQL - &lt;a href="https://graphql.org/learn/"&gt;https://graphql.org/learn/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Play with online GraphQL APIs - &lt;a href="https://www.graphqlhub.com/"&gt;https://www.graphqlhub.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Build FB with React, GraphQL and Relay - &lt;a href="https://www.youtube.com/watch?v=WxPtYJRjLL0"&gt;https://www.youtube.com/watch?v=WxPtYJRjLL0&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GraphQL-conference -&lt;a href="https://www.graphqlconf.org/"&gt;https://www.graphqlconf.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Awesome GraphQL GitHub - &lt;a href="https://github.com/chentsulin/awesome-graphql"&gt;https://github.com/chentsulin/awesome-graphql&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Client support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apolo Client - &lt;a href="https://github.com/apollographql/apollo-client"&gt;https://github.com/apollographql/apollo-client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Relay Client - &lt;a href="https://relay.dev/"&gt;https://relay.dev/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Server support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot Server support - &lt;a href="https://www.pluralsight.com/guides/building-a-graphql-server-with-spring-boot"&gt;https://www.pluralsight.com/guides/building-a-graphql-server-with-spring-boot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Grails Gorm Server support - &lt;a href="https://grails.github.io/gorm-graphql/snapshot/guide/index.html"&gt;https://grails.github.io/gorm-graphql/snapshot/guide/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IDE/UI Clients&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voyager Client - &lt;a href="https://apis.guru/graphql-voyager/"&gt;https://apis.guru/graphql-voyager/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GraphiQL Client - &lt;a href="https://github.com/graphql/graphiql"&gt;https://github.com/graphql/graphiql&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GraphiQL Client Electron packaged - &lt;a href="https://electronjs.org/apps/graphiql"&gt;https://electronjs.org/apps/graphiql&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Playground Client - &lt;a href="https://github.com/prisma/graphql-playground"&gt;https://github.com/prisma/graphql-playground&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Altair Client - &lt;a href="https://altair.sirmuel.design/"&gt;https://altair.sirmuel.design/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Micro frontends &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Micro Frontends - &lt;a href="https://micro-frontends.org/"&gt;https://micro-frontends.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Micro Frontend Martin Fowler - &lt;a href="https://martinfowler.com/articles/micro-frontends.html"&gt;https://martinfowler.com/articles/micro-frontends.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gatsby&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gatsby static site generator - &lt;a href="https://www.gatsbyjs.org/"&gt;https://www.gatsbyjs.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gatsby source plugins - &lt;a href="https://www.gatsbyjs.org/plugins/?=source"&gt;https://www.gatsbyjs.org/plugins/?=source&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Others&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rest components - &lt;a href="https://github.com/brillout/awesome-react-components/blob/master/README.md"&gt;https://github.com/brillout/awesome-react-components/blob/master/README.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>graphql</category>
      <category>rest</category>
    </item>
    <item>
      <title>Creating a Domain Model rapidly with Java and Spring Boot</title>
      <dc:creator>Cristian Olaru</dc:creator>
      <pubDate>Thu, 18 Jul 2019 07:02:52 +0000</pubDate>
      <link>https://dev.to/colaru/creating-a-domain-model-rapidly-with-java-and-spring-boot-i85</link>
      <guid>https://dev.to/colaru/creating-a-domain-model-rapidly-with-java-and-spring-boot-i85</guid>
      <description>&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this short article, we are creating a domain model for a simple application. We illustrate how we are creating the classes/objects of the model, based on the application business description. We insist just on the entities that are part of the model. &lt;/p&gt;

&lt;p&gt;Here we talk about domain modeling in the case of a Web application with a client-server architecture where we have Java on the server-side (backend). All the examples are in Java language. We use Spring Boot to accelerate the application startup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start the implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tools we are using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://adoptopenjdk.net/" rel="noopener noreferrer"&gt;Java 8 JDK from AdoptOpenJDK&lt;/a&gt; installed with &lt;a href="https://sdkman.io/" rel="noopener noreferrer"&gt;SdkMan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spring.io/projects/spring-boot" rel="noopener noreferrer"&gt;SpringBoot&lt;/a&gt; - just for starting rapidly an app with integrated build using &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring Starter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://maven.apache.org/" rel="noopener noreferrer"&gt;Maven&lt;/a&gt; - used internally for build&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mvnrepository.com/artifact/junit/junit" rel="noopener noreferrer"&gt;JUnit&lt;/a&gt; - used for playing with the domain&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jetbrains.com/idea/" rel="noopener noreferrer"&gt;Intellij Idea&lt;/a&gt; - for code editing (you can use &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; or &lt;a href="https://www.sublimetext.com/" rel="noopener noreferrer"&gt;Sublime&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are on Windows OS then the Java JDK 8 can be installed manually and also Maven can be installed manually. Spring Initializr -&lt;a href="https://start.spring.io" rel="noopener noreferrer"&gt;https://start.spring.io&lt;/a&gt; can be used to download the Spring Boot starter app. But on MAC OS and Linux, the fastest way is to use the terminal commands as you can see after.&lt;/p&gt;

&lt;p&gt;Starting our app (we name it &lt;strong&gt;cindykat&lt;/strong&gt; - a name very close to &lt;strong&gt;syndicate&lt;/strong&gt;) and running it is is just like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# install SDKMAN
curl -s "https://get.sdkman.io" | bash
# install JDK
sdk install 8.0.212.j9-adpt
# create app
curl https://start.spring.io/starter.zip -d name=CindyKat -d groupId=com.colaru -d artifactIf=cindykat -d packageName=com.colaru.cindykat -d dependencies=web -d javaVersion=8 -o cindykat-springboot.zip
# unzip, then run it
unzip cindykat-springboot.zip -d cindykat-springboot
cd cindykat-springboot &amp;amp;&amp;amp; ./mvnw spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now our app is up and running on 8080 - it is a web application! No need for a web app - is ok to have something up and running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq69q29l28yo7cwhkp3wh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq69q29l28yo7cwhkp3wh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have this project structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmoqha36m9olbmiishwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmoqha36m9olbmiishwb.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the application domain?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The domain model is the place in our code, where we are modelling the business of our app. Usually, an application model has to be a direct reflection of the business it implements. Our code has to be a story of the reality we are modelling. And we have to use a ubiquitous language used by all people working on the project. &lt;/p&gt;

&lt;p&gt;That's no need to introduce other abstractions different than what we have in the reality we are modelling. The nouns and verbs from the business have to appear in the name of our classes, fields, methods. When we introduce other things - we can be suspected of over-engineering.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaekl98v93wgb540xnd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpaekl98v93wgb540xnd1.png" alt="Domain model"&gt;&lt;/a&gt;&lt;br&gt;
Image source: &lt;a href="https://www.slideshare.net/Dennis_Traub/dotnetcologne2013-ddd" rel="noopener noreferrer"&gt;https://www.slideshare.net/Dennis_Traub/dotnetcologne2013-ddd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is the model so important? Because all the rest of the application will be in contact with the model. It is hard to have separate packages of DTOs or WS REST resources or persistence entities because of the marshalling/un-marshalling complications. We will be forced to do this if we don't want to expose the internal model outside the system. So we will use the model in all the layers of the application. You can be sure that the UI, persistence, reporting, WS, messaging integrations, all are using the domain model classes.&lt;/p&gt;

&lt;p&gt;And the model can become more an more complicated over time (hundreds of classes). And what is in the model will evolve and will influence the entire application. This is the hardest part to be understood in any app by a new development team joiner. Here is not something like a library or framework reused in other applications, but here is something specific to a business. And the businesses can be very, very complicated. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The DDD book&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are a few ways of starting a Java Web application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend first - play with the Java domain using tests to create a domain model that is the core of the server-side&lt;/li&gt;
&lt;li&gt;Frontend first - start with UX/UI with HTML/ CSS/ JavaScript and create some mockups that will illustrate the user interaction - you can play with a domain model in  JSON or Typescript here also&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is common to have a team that is working in the frontend, and a different team that is working in the backend and the contract between them is a Swagger/Open API spec.&lt;/p&gt;

&lt;p&gt;The first approach, modelling the domain, is the subject of this article. And is the subject also of a very well known book: &lt;a href="https://dddcommunity.org/book/evans_2003/" rel="noopener noreferrer"&gt;Domain-Driven Design&lt;/a&gt; by Eric Evans. In this book, more topics are introduced apart from the graph entities described in this article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks796j9ifrvixa71kfkk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fks796j9ifrvixa71kfkk.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image from &lt;a href="https://www.infoq.com/minibooks/domain-driven-design-quickly/#minibookDownload,%20/minibooks/domain-driven-design-quickly/#minibookDownload/" rel="noopener noreferrer"&gt;Domain Driven Design Quickly&lt;/a&gt; book&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our application business explained&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The application we want to implement is an analytics system for the data provided by &lt;a href="https://trends.google.com/trends/trendingsearches/daily?geo=US" rel="noopener noreferrer"&gt;Google Trending Searches&lt;/a&gt; - The history of searches from Google Search reported per day and country by Google. We want to import some data from Google Trends, then store it in our system and make it possible to analyse it, show it in a different form, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq5muuo0wgymuc8mogaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq5muuo0wgymuc8mogaz.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, it will be simple to model our domain used in our analytics system. Because we are distingue our entities from the format used to get the searches data. See this Google Trends &lt;strong&gt;Atom Syndication Format&lt;/strong&gt; XML snippet:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        &amp;lt;item&amp;gt;
            &amp;lt;title&amp;gt;Women's World Cup 2019&amp;lt;/title&amp;gt;
            &amp;lt;ht:approx_traffic&amp;gt;1,000,000+&amp;lt;/ht:approx_traffic&amp;gt;
            &amp;lt;description&amp;gt;2019 Women, Women World Cup, WWC&amp;lt;/description&amp;gt;
            &amp;lt;link&amp;gt;https://trends.google.com/trends/trendingsearches/daily?geo=US#Women's%20World%20Cup%202019&amp;lt;/link&amp;gt;
            &amp;lt;pubDate&amp;gt;Mon, 10 Jun 2019 22:00:00 -0700&amp;lt;/pubDate&amp;gt;
            &amp;lt;ht:picture&amp;gt;https://t2.gstatic.com/images?q=tbn:ANd9GcTW4UzPHNC9qjHRxBr6kCUEns71l8XK6HYcmLpJbhlfZWUbeBQPiia1GDzN3Ehl7nfD-HPbgnG_&amp;lt;/ht:picture&amp;gt;
            &amp;lt;ht:picture_source&amp;gt;CBSSports.com&amp;lt;/ht:picture_source&amp;gt;
            &amp;lt;ht:news_item&amp;gt;
                &amp;lt;ht:news_item_title&amp;gt;&amp;amp;lt;b&amp;amp;gt;2019 Women&amp;amp;amp;#39;s World Cup&amp;amp;lt;/b&amp;amp;gt; scores, highlights: Canada squeaks by, Japan underwhelms, Argentina gets historic point&amp;lt;/ht:news_item_title&amp;gt;
                &amp;lt;ht:news_item_snippet&amp;gt;Day 4 of the &amp;amp;lt;b&amp;amp;gt;2019&amp;amp;lt;/b&amp;amp;gt; FIFA &amp;amp;lt;b&amp;amp;gt;Women&amp;amp;amp;#39;s World Cup&amp;amp;lt;/b&amp;amp;gt; in France featured a two-game slate with two potential contenders opening their campaigns against slightly inferior opponents. When the dust settled, neither team looked particularly sharp as only one goal was&amp;amp;amp;nbsp;...&amp;lt;/ht:news_item_snippet&amp;gt;
                &amp;lt;ht:news_item_url&amp;gt;https://www.cbssports.com/soccer/world-cup/news/2019-womens-world-cup-scores-highlights-canada-squeaks-by-japan-underwhelms-argentina-gets-historic-point/&amp;lt;/ht:news_item_url&amp;gt;
                &amp;lt;ht:news_item_source&amp;gt;CBSSports.com&amp;lt;/ht:news_item_source&amp;gt;
            &amp;lt;/ht:news_item&amp;gt;
            &amp;lt;ht:news_item&amp;gt;
                &amp;lt;ht:news_item_title&amp;gt;&amp;amp;lt;b&amp;amp;gt;2019 Women&amp;amp;amp;#39;s World Cup&amp;amp;lt;/b&amp;amp;gt; scores, highlights, recap: Japan underwhelms in opener as Argentina gets historic point&amp;lt;/ht:news_item_title&amp;gt;
                &amp;lt;ht:news_item_snippet&amp;gt;Day 4 of the &amp;amp;lt;b&amp;amp;gt;2019 World Cup&amp;amp;lt;/b&amp;amp;gt; has a small slate of action with just two games, but two contenders to win the tournament were scheduled to play their opener. After the first match, we may just be talking about one contender. With talented Canada set to play&amp;amp;amp;nbsp;...&amp;lt;/ht:news_item_snippet&amp;gt;
                &amp;lt;ht:news_item_url&amp;gt;https://www.cbssports.com/soccer/world-cup/news/2019-womens-world-cup-scores-highlights-recap-japan-underwhelms-in-opener-as-argentina-gets-historic-point/&amp;lt;/ht:news_item_url&amp;gt;
                &amp;lt;ht:news_item_source&amp;gt;CBSSports.com&amp;lt;/ht:news_item_source&amp;gt;
            &amp;lt;/ht:news_item&amp;gt;
        &amp;lt;/item&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So it is simple! We have an &lt;strong&gt;Item&lt;/strong&gt; which has a list of &lt;strong&gt;NewsItem&lt;/strong&gt;. We separately have a &lt;strong&gt;Source&lt;/strong&gt; entity that will be reused between &lt;strong&gt;NewsItem&lt;/strong&gt;. Also, a &lt;strong&gt;Country&lt;/strong&gt; is needed for the &lt;strong&gt;Item&lt;/strong&gt; specify the country/language. That's all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfylfohl2u2615wi8u5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfylfohl2u2615wi8u5z.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating the graph of entities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The domain model will be a separate package in our application. We choose to create a sub-domain named &lt;strong&gt;newsfeed&lt;/strong&gt; (complete name &lt;strong&gt;com.colaru.cindykat.domain.newsfeed)&lt;/strong&gt; for naming the package because it is possible to have other aggregates (groups of entities) in the future. &lt;/p&gt;

&lt;p&gt;It is a good idea to create an entire module for the domain (in a multi-module Maven/Gradle project) because in this way we can create a dependency to it in any other modules of the application - all the other modules will use the domain model.&lt;/p&gt;

&lt;p&gt;First, using the IDE, we will create an &lt;strong&gt;Item&lt;/strong&gt; class, which is the primary entity (aggregate root in DDD terminology) and then the rest of the classes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.colaru.cindykat.domain.newsfeed;

import java.util.Date;
import java.util.List;

public class Item {

    private String title;
    private List&amp;lt;Tag&amp;gt; description;
    private String link;
    private String picture;

    private Date pubDate;
    private String pubDateAsString;

    private String approxTraffic;
    private Long approxTrafficAsNumber;

    private List&amp;lt;NewsItem&amp;gt; items;
    private Country country;

    // generate getters/setters using the IDE
}



public class NewsItem {
    private String title;
    private String snippet;
    private String url;
    private Source source;
}


public class NewsItem {
    private String title;
    private String snippet;
    private String url;
    private Source source;
}

public class Country {
    private String name;
    private String countryCode;
    private String languageCode;
    private String flag;
}

public class Source {
    private String name;
    private String url;
}

public class Tag {
    private String name;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the end, we will have this graph of entities:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvykqrfdi58wdlic6vbl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvykqrfdi58wdlic6vbl.png" alt="Entities graph"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the project filesystem is like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftput58a2wjagn5q4wswi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftput58a2wjagn5q4wswi.png" alt="Project structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anemic Domain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common problem for a domain is an anti-pattern named &lt;a href="https://martinfowler.com/bliki/AnemicDomainModel.html" rel="noopener noreferrer"&gt;Anemic Domain by Martin Fowler&lt;/a&gt; - the classes are having just state and not behaviour. We get from the real word only the &lt;strong&gt;nouns&lt;/strong&gt; and not the &lt;strong&gt;verbs&lt;/strong&gt;. In this case, the entities are &lt;strong&gt;data structures&lt;/strong&gt; like in the functional programming language and not real &lt;strong&gt;Java objects&lt;/strong&gt; as &lt;a href="https://blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html" rel="noopener noreferrer"&gt;Uncle Bob is describing in this article&lt;/a&gt;. And this is something normal because in general, the entities are our mappers to database tables used by an ORM persistence framework.&lt;/p&gt;

&lt;p&gt;We expect that the &lt;strong&gt;verbs&lt;/strong&gt; will be in the services layer of our application outside the domain. But in this case another discussion is starting: are this services part of the domain?&lt;/p&gt;

&lt;p&gt;But also there it is no problem to introduce some logic directly in the entities - in this case, we have to be aware that we will have business logic in two places: services and in the domain model.&lt;/p&gt;

&lt;p&gt;We will introduce some business methods in the &lt;strong&gt;Item&lt;/strong&gt; entity (some convertors from String to Date and from String to Long):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Item {
        private Date pubDate;
    private String pubDateAsString;
    private String approxTraffic;
    private Long approxTrafficAsNumber;

    // other private fields

    public Date convertStringToDate(String pubDateAsString) throws ParseException {
        SimpleDateFormat parser = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z"); // Wed, 21 Dec 2016 13:00:00 +0200
        return parser.parse(pubDateAsString);
    }

    public Long convertStringToLong(String approxTraffic) {
        return new Long(approxTraffic.toString().replaceAll(",", "").replace("+", ""));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Testing the domain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if the domain is simple, it is a good idea to start playing with it using and creating some tests using JUnit. First, we have to include the JUnit library as part of our Maven dependencies in pom.xml:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.junit.jupiter&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;junit-jupiter-api&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;5.3.2&amp;lt;/version&amp;gt;
        &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
    &amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we can create a first test to play with our simple graph of objects and to verify some small functionalities. This is a first working skeleton good enough to start our TDD development guided by tests for the next features we will add to this app:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class DomainModelTests {

    private Item item;

    @BeforeEach
    void setUp() throws ParseException {
        item = new Item();
        item.setTitle("Women's World Cup 2019");

        item.setLink("https://trends.google.com/trends/trendingsearches/daily?geo=US#Women's%20World%20Cup%202019");
        item.setPicture("https://t2.gstatic.com/images?q=tbn:ANd9GcTW4UzPHNC9qjHRxBr6kCUEns71l8XK6HYcmLpJbhlfZWUbeBQPiia1GDzN3Ehl7nfD-HPbgnG_");

        // tags
        Tag tag = new Tag();
        tag.setName("Word cup");
        List&amp;lt;Tag&amp;gt; tags = new ArrayList&amp;lt;&amp;gt;();
        tags.add(tag);
        item.setDescription(tags);

        NewsItem newsItem = new NewsItem();
        // source
        Source source = new Source();
        source.setName("USA TODAY");
        newsItem.setSource(source);
        newsItem.setTitle("&amp;amp;lt;b&amp;amp;gt;2019 Women&amp;amp;amp;#39;s World Cup&amp;amp;lt;/b&amp;amp;gt; scores, highlights: Canada squeaks by, Japan underwhelms, Argentina gets historic point");
        List&amp;lt;NewsItem&amp;gt; items = new ArrayList&amp;lt;&amp;gt;();
        items.add(newsItem);
        item.setItems(items);
    }

    @Test
    void buildNewItemTest()  {
        Assert.assertEquals(1, item.getItems().size());
        Assert.assertEquals(1, item.getDescription().size());
    }

    @Test
    void convertStringToLongTest() {
        String approxTraffic = "900,000+";
        item.setApproxTraffic(approxTraffic);
        item.setApproxTrafficAsNumber(item.convertStringToLong(approxTraffic));
        Assert.assertEquals(900000, item.getApproxTrafficAsNumber().longValue());
    }

    @Test
    void convertStringToDateTest() {
        String pubDateAsString = "Mon, 1 Jun 2020 09:00:00 -0700";
        item.setPubDateAsString(pubDateAsString);
        try {
            item.setPubDate(item.convertStringToDate(pubDateAsString));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = new Calendar.Builder().setCalendarType("iso8601")
                .setFields(YEAR, 2020, DAY_OF_MONTH, 1, MONTH, 5, HOUR, 18, MINUTE, 0, SECOND, 0)
                .build();

        Assert.assertEquals(cal.getTime(), item.getPubDate());
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;When we run all the test the bar is green (I write the test first, then the tested method, the test run is failing, I add the implementation, I run the test again, and now it is passing):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisanrwa9968xzgpzullv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisanrwa9968xzgpzullv.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we've exposed how we created a simple model for a small application.&lt;/p&gt;

&lt;p&gt;As we can see, the domain model is the core part of the application. This classes that are composing the domain model are technology agnostic (concurrency, persistence is not in our interest now) - are describing just the reality of the business - nothing regarding the technologies used in the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git Repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We published the sources on GitHub:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/colaru/cindykat-springboot.git
cd cindykat-springboot
mvn clean install // the tests will be executed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;You can &lt;a href="https://twitter.com/colaru" rel="noopener noreferrer"&gt;follow me on Twitter&lt;/a&gt; where I continue to document my journey.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Inspiration links for this article&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Value objects vs entities: &lt;a href="https://enterprisecraftsmanship.com/2016/01/11/entity-vs-value-object-the-ultimate-list-of-differences/" rel="noopener noreferrer"&gt;https://enterprisecraftsmanship.com/2016/01/11/entity-vs-value-object-the-ultimate-list-of-differences/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anemic domain: &lt;a href="https://martinfowler.com/bliki/AnemicDomainModel.html" rel="noopener noreferrer"&gt;https://martinfowler.com/bliki/AnemicDomainModel.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Domain services: &lt;a href="https://stackoverflow.com/questions/2268699/domain-driven-design-domain-service-application-service" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/2268699/domain-driven-design-domain-service-application-service&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Domain model: &lt;a href="https://martinfowler.com/eaaCatalog/domainModel.html" rel="noopener noreferrer"&gt;https://martinfowler.com/eaaCatalog/domainModel.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Service layer: &lt;a href="https://martinfowler.com/eaaCatalog/serviceLayer.html" rel="noopener noreferrer"&gt;https://martinfowler.com/eaaCatalog/serviceLayer.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Objects and data structures: &lt;a href="https://blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html" rel="noopener noreferrer"&gt;https://blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Domain Driven Design Book by Eric Evans: &lt;a href="https://dddcommunity.org/book/evans_2003/" rel="noopener noreferrer"&gt;https://dddcommunity.org/book/evans_2003/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Domain Driven Design Quickly book: &lt;a href="https://www.infoq.com/minibooks/domain-driven-design-quickly/#minibookDownload,%20/minibooks/domain-driven-design-quickly/#minibookDownload/" rel="noopener noreferrer"&gt;https://www.infoq.com/minibooks/domain-driven-design-quickly/#minibookDownload, /minibooks/domain-driven-design-quickly/#minibookDownload/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Data structures vs objects by Uncle Bob: &lt;a href="https://blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html" rel="noopener noreferrer"&gt;https://blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;10 Myths About Java in 2019: &lt;a href="https://developer.okta.com/blog/2019/07/15/java-myths-2019" rel="noopener noreferrer"&gt;https://developer.okta.com/blog/2019/07/15/java-myths-2019&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Which Java SDK Should You Use: &lt;a href="https://developer.okta.com/blog/2019/01/16/which-java-sdk" rel="noopener noreferrer"&gt;https://developer.okta.com/blog/2019/01/16/which-java-sdk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>spring</category>
    </item>
  </channel>
</rss>
