[Python] Create a ValueObject with a complete constructor using dataclasses

Introduction

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.

What is a ValueObject and a complete constructor?

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".

Try to express ValueObject with dataclasses

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)

Make it immutable

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()

How to express the change in the amount

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)

Should I use data classes

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.

Finally

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.

reference

Please refer to here for the usage of data classes. https://docs.python.org/ja/3.7/library/dataclasses.html

Recommended Posts

[Python] Create a ValueObject with a complete constructor using dataclasses
Create a directory with python
Create a company name extractor with python using JCLdic
Create a python GUI using tkinter
Create a virtual environment with Python!
Create a Python function decorator with Class
Build a blockchain with Python ① Create a class
Create a dummy image with Python + PIL.
[Python] Create a virtual environment with Anaconda
Let's create a free group with Python
[Python] Create a Batch environment using AWS-CDK
Create a word frequency counter with Python 3.4
Create a tool to automatically furigana with html using Mecab from Python3
Create a record with attachments in KINTONE using the Python requests module
Create a frame with transparent background with tkinter [Python]
Create a GIF file using Pillow in Python
Create a LINE BOT with Minette for Python
Create a virtual environment with conda in Python
Create a page that loads infinitely with python
[Note] Create a one-line timezone class with python
You can easily create a GUI with Python
Create a python3 build environment with Sublime Text3
Create a web map using Python and GDAL
Create a color bar with Python + Qt (PySide)
Steps to create a Twitter bot with python
Create a decision tree from 0 with Python (1. Overview)
Create a new page in confluence with Python
Create a color-specified widget with Python + Qt (PySide)
Create a Photoshop format file (.psd) with python
Create a Mac app using py2app and Python3! !!
Create a MIDI file in Python using pretty_midi
Create a Python console application easily with Click
Create a Python module
Create a Python environment
Create a data collection bot in Python using Selenium
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 1 ~
Why not create a stylish table easily with Python?
Create a python development environment with vagrant + ansible + fabric
Register a ticket with redmine API using python requests
Create a Layer for AWS Lambda Python with Docker
[python] Create a date array with arbitrary increments with np.arange
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 2 ~
[Python] How to create a 2D histogram with Matplotlib
[Python] Create a Tkinter program distribution file with cx_Freeze
Create a fake Minecraft server in Python with Quarry
Using a Python program with fluentd's exec_filter Output Plugin
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 3 ~
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 4 ~
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 5 ~
Create a 2d CAD file ".dxf" with python [ezdxf]
Using a python program with fluentd's exec Output Plugin
Create a Wox plugin (Python)
Create a function in Python
Create a dictionary in Python
Using Quaternion with Python ~ numpy-quaternion ~
Create 3d gif with python3
[Python] Using OpenCV with Python (Basic)
Create a homepage with django
Create JIRA tickets using Python
Create a python numpy array
Using a printer with Debian 10