0

I want to to follow a clean architecture rules (with domain and architecture layers). I have a problem with properties that an entity should or should not have.

Let's say that I have a User domain. It has all the business related properties (like first name, last name, email, mobile phone number, etc.). But there are also some properties that are specific to each user, but have only indirect business relation. For example the business may want me to send an email, which is customized based on the OS the user uses to interact with our service. Can I make the "OS version" a property of the User entity? Or should I create an application service that will retrieve an OS version based on provided User entity?

Update: I have a supplementary use case: what if we are using an external provider who assignes its own unique ID for each of the user? For example Stripe - in order to update user's credit card info I need to provide Strip with unique ID which I get when user registered his card. Does the stripe_id become a part of User entity?

  • 1
    An indirect business relation is still a business relation. I would keep it on the User entity. – Dan Wilson Feb 12 at 16:42
  • From my standpoint, the OS version is still more business related rather than technical, since it is a business/company decision to add a new OS or pick/change to some other OS. To the email example, are you saying that the service is accessed as some Desktop/Web UI, or is it accessed in other applications like a Service Reference? And, are you saying that you want to account for the app/underlying SMPT based on OS? – eparham7861 Feb 12 at 16:54
  • 2
    Are you envisioning that a user interacts with the system using only one OS ever? – Erik Eidt Feb 12 at 17:47
  • Thanks for your questions. I have added a supplementary use case that better explains my problem. Which is that there are some parameters which my entity needs to be able to follow business rules, but which the business doesn't need at all (in fact, the business is unaware of them). – george007 Feb 13 at 7:06
  • 1
    With the update, I think the User entity can hold some implementation of Credit Card, whether if be Stripe or whatever, so any unique identifier in this context represents both User and Card combined instead of uniquely identifying some User or some Card. A user could have more than one card registered. So, I would say that "stripe_id" can be retrieved through the user (user -> card -> unique user/card identifier), but that id should not be the only thing added to the entity. – eparham7861 Feb 13 at 21:08
2

Answer Based On Comments

With the provided update, User entity is something that can hold some implementation of Credit Card, whether it be Stripe or whatever other external thing that is outside of your system, so any unique identifier in this context represents both User and Card combined instead of uniquely identifying some User or some Card exclusively. A user could have more than one card registered. So, I would say that "stripe_id" can be retrieved through the user (user -> card -> unique user/card identifier), but some external id should not be the only thing added to the entity.

To briefly touch on the original bit of the question, the OS/OS version is usually not something that is part of most business-like entities, very similar to the perspective given with the credit card update. For me as someone looking into the provided context, the confusing part is that the idea of a business entity like User having/knowing what the OS/OS version feels backwards, since the OS normally gives a description about the environment that where the business entities may exist. Using the update for perspective, it would be roughly the same as a business entity Credit Card for Stripe having/owning the Unique Id for the user from your system.

As a last note, the concept that you had in the original question fits better in the terms of some database or whatever you use to store information. For example, a lookup table that maps a user id to one-to-many credit card ids, or a transaction log that describes an entry as the user (user id) purchasing some item with this card (unique card id).

0

Domain Driven Design would have you organise your Business Objects by the way the business speaks about them.

So, if the business talks about "the users OS..." then you should have User.Os

However, I think you are right to be cautious. Businesses have a way of talking about 'The users OS' but when challenged will say 'Oh! of course I mean the User's Device's OS' or 'the User's Web Browsers device header'

One way to tackle this is to have multiple User objects depending on whether they are used by the Web team or the App team or whatever. But I find this soon becomes confusing.

My advice would be to take the business language with a pinch of salt and add technical objects where you think they will help.

  • Thank you for your answer. I have a supplementary use case: what if we are using an external provider who assignes its own unique ID for each of the user? For example Stripe - in order to update user's credit card info I need to provide Strip with unique ID which I get when user registered his card. Does the stripe_id become a part of User entity? – george007 Feb 13 at 7:03
0

It depends, It's an abstraction question, If your goal is to treat technical informations, these informations become domain information (because this is your domain) and not just technical infos and it turns to be a domain requirements, if it's the case I would create a Value Object (DDD approach) of the OS and bind it with the user as the user OS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.