'Decoupling expensive I/O operations from domain model

Let's assume I have User on my business logic that has a username, address, phone, and profile picture:

class User:
    def __init__(
        self, username: str, address: str, phone: str, profile_picture: np.ndarray
    ):
        self.username = username
        self.address = address
        self.phone = phone
        self.profile_picture = profile_picture

    def foo(self):
        ...

    def bar(self):
        ...

    def flip_profile_picture(self):
        self.profile_picture = np.fliplr(self.profile_picture)

Most of the operations on my User class do not need access to the profile_picture attribute, also it is rather expensive loading the profile picture every time that I need to operate on a User instance.

What is the correct way to abstract away the profile picture from the user? The approach that comes to my mind is creating an entity ProfilePicture that holds the username and the array data. This implies creating a repository for the ProfilePicture class and lets say a user wants to flip his profile picture there would have to be a service that receives a user i.e.:

class ProfilePictureService:
    def __init__(self, profile_picture_repository: ProfilePictureRepository):
        self.profile_picture_repository = profile_picture_repository

    def flip_profile_picture(self, user: User):
        profile_picture = self.profile_picture_repository.get(user.username)
        profile_picture.flip()
        self.profile_picture_repository.update(profile_picture)

Are there any other ways to do this? In general what is the best way to avoid expensive I/O operations on certain attributes from an entity only until they are actually needed.

Pardon me if the DDD terms are not accurate, I can clarify anything if needed.



Solution 1:[1]

Are there any other ways to do this? In general what is the best way to avoid expensive I/O operations on certain attributes from an entity only until they are actually needed.

For something like a profile picture, you probably need to consider why your domain model would ever care about that data (do you give special discounts to members with blue colored backgrounds)? If the domain model doesn't need it, then don't load the picture at all -- take that out of your aggregate, store it in a different database.

But for the case where you do have expensive data that the model needs, but only for some operations, the usual answer is to create separate entities assigned to different aggregates.

Often that means that a bunch of information related to the same user gets spread out across several entities and aggregates

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 VoiceOfUnreason