If the Use Cases must NOT extend the Entities, on which layer of Clean Architecture must be the entities with application-specific properties?

110 views
Skip to first unread message

徳川武

unread,
Oct 11, 2022, 5:21:55 AM10/11/22
to Clean Code Discussion
Asking the question  Must the use cases extend the entities in Clean Architecture? at Stack Overflow I has been answered "No". I suppose there are the developers which have another opinion about this question. I'll bring the example where the extending could be useful.

According the section Entities of Chapter 20 "Business Rules,

Very strictly speaking, the these rules (note: the enterprise business rules) would make or save the business money, irrespective of whether the were implemented on a computer. They would make or save money even if they were executed manually.

Below class is matching with this concept because product has the title (which could be written by pen on the physical label) and the price:

class Product {

  public title: string;
  public price__dollars__withoutTax: number;

  public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
    this.title = properties.title;
    this.price__dollars__withoutTax = properties.price__dollars__withoutTax;
  }

}


Unlike this, below class has the properties which are existing only inside application - the ID, createdAt__ISO86101, updatedAt__ISO86101:

class Product {

  public readonly ID: number = Product.generateID();

  public title: string;
  public price__dollars__withoutTax: number;

  public createdAt__ISO86101: string;
  public updatedAt__ISO86101?: string;

  public constructor(properties: Readonly<{ title: string; price__dollars__withoutTax: number; }>) {
    this.title = properties.title;
    this.price__dollars__withoutTax = properties.price__dollars__withoutTax;
    this.createdAt__ISO86101 = new Date().toISOString();
  }


  private static counterForID_Generating = -1;
  private static generateID(): number {
    Product.counterForID_Generating++;
    return Product.counterForID_Generating;
  }  
}


How above class must not be extended from the first version of Product class, how it should be organized in the Clean Architecture hierarchy?

SFKy9.jpg
Message has been deleted

deepbl...@gmail.com

unread,
Oct 11, 2022, 9:45:02 AM10/11/22
to Clean Code Discussion
Hi

You misunderstand what use cases are.
Writing the name of a product on a piece of paper does not make the company money. Selling it does!

Think of entities as objects encapsulating application INDEPENDENT business logic. 
For example, if you take a shopping cart from one shopping app to another, there should be no reason to rewrite it. It adds/removes/holds product entities (that consist of a base class with all the common properties like SKU, name, price, etc., and subclasses to handle company specific product info), tells you how many items you have in the cart and possibly calculates the total in the cart. As such, the shopping cart is an entity.

Use cases manipulate entities and gateways to get something done, and they contain application DEPENDENT business logic. Examples of use cases would be:
Checkout - (each company has their own process)
Pay employees - (Each company pays employees differently with different schemes)
Start engine - (each company and vehicle model might have a different engine start sequence)
Create purchase order - (Each company has different ways of procurement)

As such, us cases are NOT entities (extension means "is a"). Also, Uncle Bob does not cover this in his book, but use cases come in 2 varieties:
- low level use cases  - they generally get one thing done
- high level use cases - they coordinate between low level use cases to get more complex things done.

Regarding a previous question of yours that I saw, but could not reply to because the UI of this forum sucks on a phone, gateways are simply objects that shuttle entities in and out of the app. Gateway interfaces  depend on entities and primitives ONLY.
That means that they will NEVER return raw database table data, or network responses, or bytes or any such nonsense. They always take and return Entities. Think about them as portals. 
You have an entity (let's say employee) and you want to tell the portal "Here's an employee! Sore it!" and the portal takes your employee entity and sends it over the network, or to the disk or saves it into a database. The app should not know or care how this happens.  Or you tell it "Gimme a list of Employees who satisfy condition X!" and the portal returns a list of employees fetched for a network, or disk, or DB. Again, the app does not know or care about how the portal does what it does. 

Perhaps the diagram below makes it easier for you to visualize what's going on. Arrows mean a  "Has a" relationship.

DB     Disk    Network
  ⭡---------⭡-----------⭡
                  |
         Gateways                   Entities
             ⭡__________________⭡
                              |
                       Use cases
                              ⭡
                              UI

Hope this helps!

Regards,

Norbert

徳川武

unread,
Oct 12, 2022, 5:27:40 AM10/12/22
to Clean Code Discussion
Thank you for the answer.

You misunderstand what use cases are.
I totally agree. Unfortunately, there are no code/UML examples in the "Use cases" section and just one verbal example with loan issuing.
I also have not found these examples in "Object-Oriented Software Engineering" book of Ivar Jacobson.
So because currently my understanding of the Use cases concept is pretty weak, all that I wrote below is not the objection, just the questions occurred during the attempts to understands.

Checkout - (each company has their own process)
Pay employees - (Each company pays employees differently with different schemes)
Start engine - (each company and vehicle model might have a different engine start sequence)
Create purchase order - (Each company has different ways of procurement)

Hmm, these examples sounds like Enterprise business rules - the business rules of the specific organization, the innermost ring of the hierarchy.
The checkout and payments could be executed without digital application...
Has I missed something?


That means that they will NEVER return raw database table data, or network responses, or bytes or any such nonsense. They always take and return Entities.

Completely agree with first sentence.
But below paragraph from the Request and Response Models section causes the concern:

You might be template to have these data structured contain references to Entity Objects. You might think this makes sense because the Entities and the requires/response models share so much data. Avoid this temptation! The purpose of the two objects is very different. Over time they will change for very different reasons, so tying them together is any way violated the Common Closure and Single Responsibility Principles. The result would be lots of tramp data, and lots of conditionals in your code.

Here is the another question - are these Request and Response Models and Gateway Interfaces are the same thing?
Well, I should discuss this in other topic.


Perhaps the diagram below makes it easier for you to visualize what's going on. Arrows mean a  "Has a" relationship.

I am sorry, what is the "UI" in the bottom of the diagram?
I can't believe it the the User Interface.

Regards,
Takeshi Tokugawa
2022年10月11日火曜日 22:45:02 UTC+9 deepbl...@gmail.com:

deepbl...@gmail.com

unread,
Oct 19, 2022, 3:44:24 AM10/19/22
to Clean Code Discussion
Yes, that is the UI. (I included presenters in the UI layer since it's where they belong).
You trigger your use cases from the UI by passing in the necessary parameters (this is your request model). The use case does its thing using Entities and Gateways, and returns a response model to your presenters. The presenters take the response model and convert it to a presentable entity (only stuff you need to show on the UI. All the if-else logic on what to show and when lives here). The presentable entity is passed to the UI, which populates its controls with the values.  

UI --> RequestModel -------------------------------------------------------> UseCase --> Entity --> Gateway --> [BIG BLUE YONDER]
UI <-- PresentableX   <-- Presenter <-- ResponseModel <-- UseCase <-- Entity <-- Gateway <-- [BIG BLUE YONDER]

As you can see, the request and response models have nothing to do with gateways. They represent the interfaces to the use cases.
I recommend you watch Uncle Bob's Java case study series on the Clean Coders site. He gives a pretty good example there.

Regards,

Norbert
Reply all
Reply to author
Forward
0 new messages