How would I make separate duplicated logic in Value Objects - node.js

I'm learning DDD (Domain Driven Design) and reading Clean Architecture. I found out about Value Objects and have been reading more about them and have implemented some in my application which could be found https://gist.github.com/Tyler0722/73ec826be814b8e54b9f6ae6ae836409.
Value Objects are created by calling the factory method which performs validation and follows the separation of concerns principle. The problem is I have two Value Objects where the validation logic is duplicated. Username and QuizTitle where the only difference is MAX_LENGTH which violates the DRY principle. I was wondering if anyone knew anyway I could make this DRY.

If you want to remove repetition you must be very careful.
The first question you should ask yourself is
What is the same and what is different?
Maybe you will find the same or similar structure like
check the props
create an error result or a success result
If you found out what you think the same is you have to ask yourself more questions:
Do the things that are (look) the same have different responsibilities?
Do they change for the same or for different reasons?"
These are the questions that are about the single responsibility principle. Sometime things look the same by accident. They look the same but are different, because they change of different reasons. If you eliminate the "duplication" in this case you will have more problems then you solve.
E.g. if you consolidate the validation logic of QuizTitle and Username into one method and later you get a change request for the QuizTitle validation you can easily break the validation behavior of Username. I guess it should not change if the QuizTitle validation changes.
You might also want to read the good article by Martin Fowler about Avoiding Repetition

My suggestion is to not do it. In this case it's just not necessary.
But if you want to do it anyway, you can build a Validation class with static functions. At my work we use Webmozart/Assert and if you take a look at its implementation you will understand what I mean. In my opinion there are very handy. Also you can pass the MAX_LENGHT as an argument.

Well, I agree with Darius Mann, that these value objects have similar business logic is ocasional, if they are different concepts in your app, keep them separated and independently, it is my opinion.

Related

Domain Driven Design Entity Advice for a Novice

I'm trying to learn Domain Driven Design. At the moment I'm putting together a context map for a dummy personal project designed to store information about clients and leads (there's also an email template engine and some other bits).
I've stumbled on a small hurdle; the problem I have is that I've created a bounded context for storing information about clients and companies. There are two types of client, Proxy clients who sub-contract and end clients.
I'm not sure if I should just be modelling this as client with a client type value type or as separate domain entities for clients and proxy clients? Any advice would be appreciated.
Please Note
The diagram above isn't complete so there are some links missing. If I'm doing something obviously wrong here please don't hesitate to let me know.
I'm also using arrow heads instead of upstream / downstream as I think they're a little better visually.
The way to model this will depend on the requirements for your application and the business domain.
There is something that seems to me is missing for ProxyClients. If they sub-contract, they should be involved in some kind of Project for an EndClient maybe?
I'll just assume that this is the case and add Project to the model.
Now, can a client be one time an EndClient for one Project and another time a SubClient for another?
If the answer is yes then you will need a separate ClientEntity that can have a ClientType or Role assigned to it for a Project. The Role doesn't make sense on it's own, it exists only for a Project.
An advantage of using ClientType or ClientRole as a separate concept in your model is that it's dynamic and you can change the type of a Client or assign multiple types/roles.
Using different entities will prevent you from doing this. If later in the life-cycle of your application the requirements change you will have to refactor to the other design. Leaving the old design and converting a SubClient to EndClient probably won't be possible or you will need to store all the information for all projects done by this EndClient. Another way to deal with this is to have one client have copies in both ProxyClients and EndClients
On the other hand if you don't need the flexibility of the design with separate Type/Role you will be better of with different entities. This has the advantage of having a clean separation of what type of a client you are dealing with and will make the system simpler.
For more information on this topic check this article
Now onto the model and the design.
When someone answers your question there are two thing that a person can do. One is to answer the direct question that you are asking.
Another is to notice problems with you design, model etc. and give you feedback for it.
You said that somethings are missing, but they are important. I did answer your concrete question, but the small amount of information prevents me from giving you more feedback on your design and give you some pointers on where you mistakes may be.
One of the things I don't uderstand is ProxyClient. Does a Company SubContract for a Client and that's why this client is a ProxyClient for this Company or is the Company hired to do a Project for an EndClient and it hires a SubContractor that you call a ProxyClient.
This point is important for your design yet it's not clear. Because if you are in the second case then I would say that your concepts may need to change. For example you have a SubContractor doing the work and won't call it a ProxyClient as it doens't make sense. This will change the whole model with new concepts.
Next time try to give more information or try to derive a simpler and more clearer case. Sometimes the original case is complex, so you may need to present a similar yet simpler case that faces the same problem so that people don't get confused. Also give more information on your application and your domain. How things should work and what are the relationships between them.

Do I have this Use Case diagram correct?

With this Use Case diagram, I'm unsure if I'm currently doing it correctly or not. Checked online and each site is giving me a different answer. I just need a direction or someone to correct me.
This is interesting as I am currently going through the exact same discussion with a client...
I would say "no" simply because I am unsure of what this actually represents.
A use case must bring a benefit to a user, and I really don't this in this diagram. What does Actor0 actually trying to accomplish? I do not get this from the diagram.
Did you write down statements before trying to do this? I find that going to a whiteboard and writing down what your actor's goal and how you see this happening so that the actor achieves the goal is a good start to better understanding the use case and differentiate the system being built from external systems. One way to do this is through a set of user stories (or use case slices).
And answering Thomas Kilian's excellent questions will also help you in this task!
Also, you are doing something that I see too often from people starting with use cases (and sometimes with UML experience): use case decomposition as a set of actions - basically trying to model a set of activities by breaking it down. Doing that is typically the second step in your analysis (e.g., by using activity and sequence diagrams).
No. Only "Register" (what?) and "Add/View Details" (which?) can be regarded as use cases since they add value. Neither "Login" nor "Main Menu" are use cases. The first is a constraint and the second an implementation detail.

In DDD and CQRS, should I just put the required presentation logic directly into each Read (Finder) query?

I'm trying to decide the best place to take care of presentation logic. I've separated out my Read queries (CQRS) with each method querying and generating a DTO for my View. But my Views are simply templates with variables scattered about that will come from the DTO. They don't have any logic in them.
Say I want to do some things like reformatting how the date looks, and turning flags into actual descriptive words, or adding little conditions on what is displayed depending on what is queried from the database, and so on. I'm thinking to put this logic in with each query, and to not worry about being too DRY (I find that in some cases if you DRY too much then you could be making things hard to change in that you have to check each dependency or hope your unit tests hold up). I may use some "helpers" here and there to do formatting that I find I keep doing, but I don't see the need to add a whole other "presentation layer". So presentation logic would reside with each query and go into the returned DTO, to be dropped right into a View. This would keep the Read side of CQRS super thin, and makes sense in that each View corresponds to a Read query. But I'm also concerned in that some of this presentation logic would be very specific to the domain. A new developer coming on board would need to look at other queries and repeat the same formatting techniques, as opposed to just throwing the data out there straight from a raw query.
Is this the sound approach, or is there another approach used in DDD/CQRS? I'm having trouble finding any guidance from CQRS research I've done. Note: I happen to be using PHP/MySQL, but I imagine this question is language agnostic.
I think the most important part to understand about CQRS is that it doesn't have to be complicated. In fact, for the read side of things go for the simplest solution that will work and be maintainable. If all you need is a SELECT statement from a view to bind to a grid, why make a bunch of layers, DTO's, and web services? Is that adding any value to the business? However if there is a legitimate reason to add a layer to the equation then you may do so, and usually DTOs are a good way to communicate between those layers.
Your system may call for different query strategies depending on the use case at hand, so this doesn't have to be a one size fits all approach. Performance should always be one of your first concerns, so get the data as close to the consuming presentation code as possible and only add complexity when truly needed.
Some might say this is not loosely coupled if the presentation layer is reading directly from the database. However, just because you have many layers between 2 things, doesn't make them loosely coupled. In fact, it may be the same amount of coupling, but now you've added a maintenance headache since you have to touch 10 places every time a field is added.
Focus more on your command side, and do whatever feels practical for the read side.

Is this too much responsibilities for one class?

I got a command : MovePlayerCommand.
One of the validator for this command does 3 things :
calculate the cost for the player to move (can be called for validation but also for displaying purpose)
validate this cost
listen to the "PlayerMoved" event so we can apply the costs (for instance - 10 action point).
Is this too much responsibilities for a single class ? If so how would you separate this ?
Edit : I know that removing the cost and checking it are 2 things, but I cant separate them from the computing of this costs, and I don't want to have 3 classes for each Action
There is a big misunderstanding here, as some poeple making comments seem to be mixing DDD and CQRS. The OP is talking about commands and has tagged the question with cqrs, so I am going to assume that the OP is indeed using DDD with CQRS.
The domain validation logic should be in the command handler, you can do, and indeed should do data checking before the command hits the handler stub, but not do any domain logic validation. That said, there is no other place where you could validate the command against the domain logic other than in the command handler because that is the place where your aggregates are loaded.
The validations you are showing are domain validations, so they should be actually performed by your aggregate, so yes, I think you should break that responsibility a bit, and split the different types of validation: data and domain.
Impossible to answer definitively without a lot more information.
That said, what you described does not sound like a validator; it sounds like a "calculator" of sorts.
It's likely that the calculating methods would belong in one class (the calculator class), and the validator class would then reference the calculator.
I tend to handle domain events in a very thin handler class, which then defers to an aggregate root or service (this is a common but not universal practice). So the root or service would likely also have a reference to the calculator (and possibly the validator).
This question may be too broad for SO, and might be better answered on a DDD forum. Even then, you may need to provide more background.

Domen driven architecture and user typos/errors

DDD teaches us to build our classes like their real-world prototypes.
So instead of using setters
job = new Job
job.person = person
job.since = time.Now()
job.title = title
we define well-named methods in our aggregation root
job = person.promote(title, /** since=time.Now() **/)
Now the tricky part
Assume we have an UI for an HR where he/she enters a new title via the HTML form and makes a typo like "prgrammer" (Of course in real application there'd be a select list, but here we have a text input), or selects a wrong date (like default today)
Now we have a problem. There are no typos in real world. Our John Doe is definitely a "programmer" and never a "prgrammer"
How do we fix this typo in our domain model?
Our Person has just promote, demote, fire, etc. methods, which reflect the HR domain model.
We could cheat a little bit and change the Job record directly, but now we have a Job.setTitle method, that doesn't reflect our domain model and also, setters are evil, you know.
That may look a little "academic", but that really bugs me when I try to build a good domain model for a complex application
Another side of DDD is invariants - "always valid" entity. And when you try to break this invariant (some rule) you must stop execution and say "loudly" adout this (throw exception). So, you need to have a list of valid titles and when you try to change title (does not matter how) to invalid state, you must throw some usefull exception.
To "fix" typo situations you must separate operations in your domain promote is one operation (it may check something, sent contratulation email :) and so on). And edit operation - just to edit some properties. So, the differenece is in logic of operations. You can't call promote without some preconditions (for example, required experience of worker), but you can call edit and fix worker's name because of type.
And usually this operations are separated between different users: only HR's can promote but a worker can edit his name, if it's wrong.
This solution is very complicated for such example, but it's always with DDD.
The main concept - separate operations. Each one with their own conditions, permissions, rules.
A question about invariants (rules).
If a client is purely entering data, then the underlying domain in this (bounded) context is not very deep. In these cases, it's fine to use a CRUD style application and allow titles to be changed (setTitle()).
Just make sure dependent BCs (e.g., billing, vacation planning, ...) where no such thing as "invalid data" exists, can react to changes in your CRUD context appropriately.
The application should enforce input correctness before it reaches the domain layer, no garbage input. If that means using a dropdown for the job titles then so be it. You can validate the title against existing titles.
In my company of 18 thousand employees, typo happens all the time. You are going to have to be pragmatic about this and accept that there will be setters in your code (one way or another)
Pragmatic thinking is very much at the core of the domain driven design, and is what keep things simple.
"Purity is good in theory, but in practice it can be very difficult to achieve, and sometimes you must choose the pragmatic approach" - Patterns, Principles, and Practices of Domain-Driven Design (2015)
"There are no typos in real world", I get what you mean, but that's not true, there are human mistakes in real world scenarios and they should be accounted for in your domain if they are frequent.
If data entry errors aren't frequent it may not be worth the extra modeling efforts and those could perhaps just get fixed directly in the DB. It also depends if the business wishes to learn something about those mistakes or not.
However, if data entry errors are frequent, it might be an indicator that the system is perhaps not offering enough guidance and the business may wish to learn more about those errors in order to make processes more efficient and less error-prone.
You may wish to implement an operation such as job.correctTitle(...), perhaps in a BC dedicated to data corrections? Also, it's probably very rare that each and every piece of information will be erroneous so corrective operations can be segregated. That means you probably do not need a job.correctAllInformation(...) kind of operation.
This whole scenario is very fictive since job titles would usually be managed in a separate BC from where they are used and they would probably get picked from a list, therefore typos would be less frequent, but you will always have to deal with data entry errors. Choosing the appropriate solution is not always easy and will vary from case to case, but try to stay pragmatic and not strive for the perfect model in every sphere of your domain.

Resources