pcah/python-clean-architecture

Domain: elaborate a workflow for Entity classes

lhaze opened this issue · 4 comments

lhaze commented

There are three contexts in which you may consider the life cycle of an entity instance:

  1. Immutability of an instance and making a change to its attributes
  2. Changes to the entity's attributes as a source of events Extracted to #63
  3. Factories and relations to other entities Extracted to #64
  4. What is the moment an instance acquires its ID? Is "lazy ID" (the DB will eventually generate identity for an instance and then we set it) a good pattern?
lhaze commented

Blocked by #61.

lhaze commented

(2) and (3) has been separated to issues #63 & #64, accordingly.

Ad rem (1): Immutability of an instance and making a change to its attributes
Immutability is a great feature and helps the code to be side-effect-free. But isn't it contradictory to the idea of the Entity itself?

lhaze commented

Ad (4): The two key assumptions about the Entity is the ones that:

  • its instance is discernible from other instances by a unique ID
  • its instance lifecycle is independent of any persistence implementation

One of the conclusions has to be the following: an instance of an Entity has to have its ID value defined from the moment of creation. If not, two newly created instances would be undiscernible til saved. Yes, python's id(instance) is good, but is no good when you don't try to coordinate its identity with the Repository. Unless you use Repository to create and keep away from identity conflict, your python id(instance) can't be accepted as a source of information about discernibility.

lhaze commented

Ad (1): Immutability of data structures is a nice property of code and brings multiple benefits but also it makes a huge impact on the API and usage patterns of Entities. While it might be a good idea, I don't assume the library can force such a tenet. Going further, only a part of API of some specific Entity might be considered immutable, so forcing the whole Entity class to be immutable might be excessive. Let's call it frozen.

What can be done with little cost: a descriptor for a generic Python class, that makes its value frozen and can't be modified once it's been set with a value. This will give us some kind of local immutability without making big decisions. In the best case, the whole Entity class may have its declarations of attributes decorated with frozen descriptor without interaction with annotations and other assumptions of the library.