Live data from Hacker News

Better Software Design with Clean Architecture

fullstackmark.com

31–40 of 141 posts

Re: Better Software Design with Clean Architecture

#31
This design puts entities in the middle - everything else pivots around entities. Additionally, it uses the OO approach of implementing logic as methods on the entities.

After a couple of decades of experience, I've come to the conclusion that this isn't right. Most business rules involve processes, which are inherently procedural, or, from another perspective, functional - functions of the whole state of the system to a new state of the system. Most processes don't logically belong on an object, and when you stick them to one end, you create lots of problems for yourself.

Just take that example Student entity class; what stops you from writing:

    student.RegisteredCourses.Add(course);
Moreover, when you have a relation between two entities, it's not uncommon for the relation to be modelled at both ends; that is, a student has a list of courses, and a course has a list of students. Do you implement the same validation at both ends? Make one end (choose one) read-only? Do edits done on one end automatically turn up on the other end? How do you protect the visibility of methods that keep either end in sync, without exposing invariant-violating APIs to other code?

Invariants and validations for fields are trivial with an OO approach; for entities, they're reasonably easy, but sometimes you need partially invalid versions while editing or constructing an entity; but once you bring in multiple entities, and relations, everything starts getting hairy pretty quickly. Assertions and validations that would be trivial to write [1] in a relational language like SQL aren't possible in an object-oriented language without a lot of system-building.

So I've come around to the idea that the database is a better thing to put at the centre; that encapsulation and hiding of the main fact store is harmful to the architecture of a system, especially in a heterogeneous environment where your entities are represented in different languages, all backed by the same fact store.

[1] Trivial to write, but not necessarily cheap to evaluate. I'm not advocating writing all global validations in SQL.

Re: Better Software Design with Clean Architecture

#33
post #31

This design puts entities in the middle - everything else pivots around entities. Additionally, it uses the OO approach of implementing logic as methods on the entities. After a couple of decades of experience, I've come to the conclusion that this isn't right. Most business rules involve processes, which are inherently procedural, or, from another perspective, functional - functions of the whole state of the system…

This is solved by DDD and aggregates. Here's how i would do it.

   Course - Aggregate Root

   Student - Aggregate Root

       RegisteredCourses[RegisteredCourse[]) - Sub Entity Collection - with id reference to course. With metadata like date time when the registration occurred.

       RegisterForCouse Method
There should be no mutable public properties, internal methods should be private. Everything should go through an aggregate root method.

Re: Better Software Design with Clean Architecture

#34
post #16

Earlier quoted context omitted.

> Surprising this has been written in 2017. It looks like java written a decade ago. Because good architecture has somehow evolved? > This can be a kind of organizational solution much like microservices to separate concerns. This is orthogonal to microservices. And microservices aint but one model of creating applications, not "THE 2017 model".

> Because good architecture has somehow evolved? Of course. Every year gives us greater insight into what approaches work and don't work. Which is why we have seen Java technologies like EJB, JCA, JTA, OSGI, JSP etc generally fall by the wayside in favour of less convoluted and less architecturally heavy approaches. > And microservices aint but one model of creating applications, not "THE 2017 model". Microservices a…

I am very intetested. What makes you think that microservices is current standard? Is there a peer-reviwed study?

Re: Better Software Design with Clean Architecture

#35

Earlier quoted context omitted.

It remains a good approach, even in your scenario - because that perf problem is solved using a temporal cache.

I see it now ..... A interface to define the validation aspect. 3 separate implementations of said interface : 1 for db lookup, 1 for cache lookup and last for unit tests. 1 factory method which return the instance to use depending of context. Another temporal cache that holds the instance of said interface (after all, you can never have enough caches). And all of a sudden, validating some single shit takes +300 line…

Why do an interface at all? Is the validation definitely being shared across business functions?

Re: Better Software Design with Clean Architecture

#36
post #33
post #31

This design puts entities in the middle - everything else pivots around entities. Additionally, it uses the OO approach of implementing logic as methods on the entities. After a couple of decades of experience, I've come to the conclusion that this isn't right. Most business rules involve processes, which are inherently procedural, or, from another perspective, functional - functions of the whole state of the system…

This is solved by DDD and aggregates. Here's how i would do it. Course - Aggregate Root Student - Aggregate Root RegisteredCourses[RegisteredCourse[]) - Sub Entity Collection - with id reference to course. With metadata like date time when the registration occurred. RegisterForCouse Method There should be no mutable public properties, internal methods should be private. Everything should go through an aggregate root…

How did you decide that the registration is a property of the student and not the course?

Re: Better Software Design with Clean Architecture

#37
post #36
post #33

Earlier quoted context omitted.

This is solved by DDD and aggregates. Here's how i would do it. Course - Aggregate Root Student - Aggregate Root RegisteredCourses[RegisteredCourse[]) - Sub Entity Collection - with id reference to course. With metadata like date time when the registration occurred. RegisterForCouse Method There should be no mutable public properties, internal methods should be private. Everything should go through an aggregate root…

How did you decide that the registration is a property of the student and not the course?

This is actually a part of understanding the specific domain. How do the educational practitioners think about the problem for application your working on? Is the application student or course centric? This is big part of DDD, and involves working domain experts and getting inside each others heads.

You could defiantly model it as the Register method on the course. But this example shows how you can avoid people messing around with internals once you've modeled it. There is only one way of registering for a course.

Re: Better Software Design with Clean Architecture

#38
post #37
post #36

Earlier quoted context omitted.

How did you decide that the registration is a property of the student and not the course?

This is actually a part of understanding the specific domain. How do the educational practitioners think about the problem for application your working on? Is the application student or course centric? This is big part of DDD, and involves working domain experts and getting inside each others heads. You could defiantly model it as the Register method on the course. But this example shows how you can avoid people mess…

I know there are ways to solve the problem; but I believe these are accidental complexities, not essential complexities. That is, these design solutions complect the problem, sacrificing simplicity for a dubious principle.

Re: Better Software Design with Clean Architecture

#40
post #38
post #37

Earlier quoted context omitted.

This is actually a part of understanding the specific domain. How do the educational practitioners think about the problem for application your working on? Is the application student or course centric? This is big part of DDD, and involves working domain experts and getting inside each others heads. You could defiantly model it as the Register method on the course. But this example shows how you can avoid people mess…

I know there are ways to solve the problem; but I believe these are accidental complexities, not essential complexities. That is, these design solutions complect the problem, sacrificing simplicity for a dubious principle.

Actually I think this is a major advantage. They are not complexities, they are putting down into code how you think about your application in your head.

If your design is some data, which you can mutate however you want to get the job done, you don't really have model of the application.

Your business rules can become inconsistent because different developers are implementing different but similar methods in your business logic layer all applying slightly different rules. If the entities themselves enforce these rules, it become a lot less likely.

Post reply on HN