Recently, I recklessly started studying DDD, but there are few examples of Python ...! So ・ Organize your thoughts on DDD ・ Propose an example of how to write in Python I decided to write an article for the purpose. For the time being, this time I'm writing about a Value Object that seems to be the most accessible.
There are many articles that are very easy to understand for other people, so I will give it to you, but if you write it briefly, ValueObject is "a value that is not a primitive type such as int, but an expression of the expected behavior and way of doing things using a class", A complete constructor can be said to be a method for achieving "expected behavior" or conversely "not causing unexpected behavior". (I understand this ... is it right ...?)
For example, if you want to express "amount", you can say "it will not be a negative value". ValueObject is a class that defines the behavior that should be supposed to be. Describe the above "it will not be a negative value" in the constructor, It is a complete constructor that realizes "there is no value that should not exist".
Since we talked about the amount of money in the previous section, let's write it briefly using the amount of money as an example.
import dataclasses
@dataclasses.dataclass
class Money:
#I won't go into details, but the variables listed here are for regular classes.__init__It will be an instance variable described in
amount: int
# __post_init__Is__init__This is the process that is executed after.
#The representation of the full constructor is described here.(2020/5/9 Corrected an error)
def __post_init__(self):
if self.amount < 0:
raise ValueError()
Now there can be no Money object with a negative value, There will only be Money objects that are guaranteed to have the correct values. (I think there are other restrictions that should be imposed, but this time I will move on to this level)
You can also use dataclasses to make your classes immutable. Immutable makes reassignment impossible and improves code security. (ValueObject seems to be basically something that should be immutable) Python is an important feature because there are few ways to prevent reassignment to instance variables.
import dataclasses
# frozen=True makes it immutable
@dataclasses.dataclass(frozen=True)
class Money:
amount: int
def __post__init__(self):
if amount < 0:
raise ValueError()
By making it immutable, once instantiated, the value cannot be changed even if the amount increases or decreases. Now, how to express the increase / decrease of the amount, create a new instance with the value of the amount after the increase / decrease. Methods can be written just like regular classes.
import dataclasses
@dataclasses.dataclass(frozen=True)
class Money:
amount: int
def __post__init__(self):
if amount < 0:
raise ValueError()
def lost(self, loss):
return Money(self.amount - loss.amount)
#For example, write like this
money1 = Money(1000)
money2 = Money(100)
left_money = money1.lost(money2)
The same thing can be done with the conventional description method, so it is not essential. However, ・ Can be immutable ・ The amount of constructor description can be reduced. -The description of the instance variable and the description of the logic to make it a complete constructor can be separated, making it easier to see. In that respect, I have the impression that it is better to use data classes. Since dataclasses has various other functions, I would like to use it not only for ValueObject.
I introduced this time that you can express ValueObject even in Python if you write it like this. Since I have just started studying, the explanation of ValueObject itself is thin, but if you deepen your understanding I would like to write supplementary articles and write articles about entities.
Please refer to here for the usage of data classes. https://docs.python.org/ja/3.7/library/dataclasses.html
Recommended Posts