Does domain design depend on static methods?

I read a lot online / offline about where you can put validation and business rules in general for a domain-driven project. I could not understand how an entity can provide methods that perform validation and business rules without resorting to static methods or services? This is especially important for cases when the domain object does not need to be created yet, but we need to check the value that will ultimately be used to set the attribute of the object.

I noticed blog entries such as http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/ based on the .NET extension method, which is not available in languages programming such as Java. I personally do not like static methods, they cannot be overridden and difficult to verify.

In any case, I can do this without static methods or create an instance of an unnecessary domain object to use its validation methods and business rules. If not, does this mean that a domain-driven project is highly dependent on static methods?

thanks

0
java domain-driven-design
source share
2 answers

Use ValueObjects Not objects.

In the registration case, you can enter an object of value UserName. Create a Username object during registration. Embed validation in the UserName constructor.

See question and presentation for more details.

Edit1:
1. How to handle cases where different validation rules apply to different contexts.
For example: the username should not contain numbers for a specific type of member, but is it necessary for other types of members?

Perhaps different factory methods can do this. e.g. UserName.forGoldenCardMember (...) or UserName.forPlainMember (...). Or do MemberType (possibly hierachy) to check for UserName.

Another alternative solution is to use AggregateFactory (AccountFactory in this case).

2. Am I creating the only place to place the verification code? I read online about two points of view: an object should always be valid, and not always. Both present good arguments, but any other approach?

I prefer a valid approach personally. Passing an invalid value object harms encapsulabilty.

Edit2:
require a) a context-based validation business rule (different username rules for member types) b) continue to validate all business rules, even if one of them fails

Adhere to the principle of single responsibility with the help of Value Object (MemberType in this case). AggregateFactory can be introduced to simplify the application level (coarser granularity).

class AccoutFactory { Account registerWith(Username username, MemberType type, ....) { List<String> errors = new ArrayList<String>(); errors.addAll(type.listErrorsWith(username)); errors.add(//other error report... if (CollectionUtils.isEmpty(errors)) { return new Account(username,....); } else { throw new CannotRegisterAccountException(errors); } } } 

Edit3: For questions in the comments
a) Should the name object be the one who has a method that returns an error, for example listErrorsWith ()? After all, does this username have different rules for different types of members?

We could check this question from a different perspective: MemberTypes have different rules for the username. This can replace if / else in the Username.listErrosWith (String, MemeberType) file with polymorphism;

b) If we have a method in MemberType, knowledge will not be encapsulated in Username. In addition, we say that the username is always valid.

We could determine the correct username without MemberType rules. Assuming hippoom@stackoverflow.com is a valid username, it is a good candidate for a GoldenCard member, but not a SilverCard member.

c) I still don’t see how a check is being performed that returns a list of errors without getting a list from the exception thrown by the constructor or the static method. Both do not look perfect IMHO.

Yes, the signature of the ListErrorsWith (): List is as follows: I would prefer to use validate (username) with no return value (throw exception on failure). But this will force the ciltor to catch every validation step in order to run the test immediately.

+2
source share

If you decide to use DDD in your application, you need to build a more complex solution. I agree with @Hippoom, you should not use Entity for this purpose.

I would suggest this solution:

DTO β†’ Service Layer (ValidationService β†’ Converter) β†’ Persistence (repository)

Some explanations: When you receive a DTO from the client with all the necessary parameters, you should check it at your service level (for example, use another service, for example ValidationService ), which can throw an exception if something is wrong. If everything is OK, you can create Entity from DTO to Converter and save it in the Repository .

If you want a flexible solution for ValidationService, I would suggest Drools

+1
source share

All Articles