Best way to return error description to user - validation

Suppose I need to register user in my system.
Buisness rules are:
email shoud be unique (a kind of identity);
name shouldn't be blank.
It looks like I need Service for it.
Probably something like that:
public interface RegistrationService {
bool Register(String email, String name);
}
And it's fine until I have to return failure reason to user.
How to deal with it?
I can see few options (but I don't like any of them):
Implement a kind of result object:
public interface RegistrationService {
RegistrationResult Register(String email, String name);
}
public interface RegistrationService {
bool Succes();
Error[] Errors();
User NewUser();
}
It's fine, and even could be useful for example for REST api.
But isn't it too cumbersome(especially considering that blank name probably should be checked at factory)?
Throw exceptions
public interface RegistrationService {
void Register(String email, String name) throws RegistrationError;
}
It looks a bit more accurate. But exception are expensive. Using them like this is looks like bad idea.
Use DB constraint. But it looks even more messy than (2).

let's start with point 3: DB constraints get their job done. Yes, the exception/error message is messy, I agree about that. But ask yourself: What is more messy: a terrible error message shown to 1 user or 2 user accounts with the same email adress that can corrupt your system? The DB constraint should be your last safety net. Your service needs to check if a user account with this email already exists. But what happens if in another thread somebody creates a user account with this email in the microsecond between your check and the creation of the new user account? You'll be happy about the DB constraint.
Yes, you could find a better solution, but that would require you to have a singleton service that serializes all account creation and makes sure that no two threads can create a user account at the same time.
Point 2: Exceptions are for exceptional situations. The situation that somebody wants to create a user account with an already used email is an exceptional situation. Don't be worried about costly operations in situations where somebody wants to do something dirty.
Point 1: I don't like this. But that's just my opinion. There are situations where a Result Object of this kind makes sense, but I try to Keep it to a Minimum.

Different layers can have different ways of considering and signalling a problem. Just because the Infrastructure raises an exception doesn't mean every other layer should do so.
You could have :
Infrastructure : throws duplicate key exception, because clients are not expected to threaten the DB's integrity
Application: catches the exception and returns a simple RegistrationResult.Failure value, because it's an expected failure case
Presentation: returns HTTP 409 conflict

Related

DDD Entity validation

I have a question related to entity validation. As an example, there is a User which can be registered into a system given email and password. The business rule says that:
email must be valid (must conform to email format) and unique;
password should be between 6 and 20 characters.
My initial thought is to place the validation inside the User.Register(email, password). The main advantage of this approach is that User controls how it is registered by verifying itself the correctness of registration data. The disadvantage is that email uniqueness verification requires calls to UserRepository, so the User might have dependency on its Repository. To solve this issue, email and password validation might be factored out to some kind of BusinessRule objects. So the validation in User.Register() method might look like this:
var emailValidationErrors = _emailRule.Validate(email);
var passwordValidationErrors = _passwordRule.Validate(password);
where _emailRule and _passwordRule might be passed as constructor arguments: User(EmailRule emailRule, PasswordRule passwordRule).
In this casse User is not directly coupled to UserRepository. In this way the rules are explicitly shown in the domain, which make it more expressive.
So the question is: what do you think about this approach? Are there any other solutions?
You could implement a Domain Service that encapsulates this. Typically in DDD you would use a Domain Service when the business logic falls outside of the scope of one individual aggregate; in this case it is the uniqueness check. So, what I'd do is:
public class UserRegistrationService : IUserRegistrationService
{
private readonly IUserRespository _userRepository;
public void Register(string email, string password)
{
if (!_userRepository.DoesEmailExist(email))
throw new Exception("Email already registered");
User user = User.Create(email, password);
_userRepository.Save(user);
}
}
Also, if you are worried about User.Create being called outside of the registration service and therefore escaping the uniqueness check, you could possibly set the User.Create method to internal, meaning the only way to create a user is via the RegistrationService.
There are three validations that you're trying to do in this example:
Email address must be a valid format;
Email address must be unique (i.e., there isn't an existing user who has that email address);
Password must conform to certain length constraints.
1 and 3 above are simple validations that should be able to be done declaratively on the entity properties (using custom attributes and a suitable validation library in .NET for example).
2 above is the tricky bit, and that's where the intrinsic dependency on the User repository exists in my opinion.
The question is: "Does the responsibility of preventing the creation of a User with the same email address as an existing User lie with the User entity?". I believe the answer to that question is "No" ... it "feels" like this responsibility should lie with a higher-level service or entity for which it is natural to have knowledge of the whole set of users.
So, my take is:
Place those validations that sit with the user inside the User entity (strong cohesion);
Place the uniqueness constraint in a DDD service that is specifically responsible for maintaining the invariants of the set of users--it would do this by wrapping the uniqueness check and the persistence of the new User in a transaction.
You can kind of think there are 2 kinds of validation: internal state validation, and context validation. You can perform internal validation from within that entity, and then perform context validation using some service.
Markus,
His approach was not bad, but I just do differently.
In my opinion you respect the OCP, putting validation rules out of the Entity, which was wisely decided. Using these validation rules in the class constructor you are suggesting that the rules are immutable, right?
I would not do this way, just create a method dyad setting the rules as this constructor. For me it was not clear what would happen if the validation rules were violated. I like to throw exceptions to the user interface that handles as more ubiquitous warnings.
Another thing that was not clear to me is the event that triggers this validation. it would be when the entity User was added to the repository or have a method of the entity that would do this? I'll take the second option calling the method isValidAuthentication() throwing that exceptions.
Regarding the dependence of the Entity to the Repository, I venture to say that is wrong. You could even make the entity dependent on him, because the repository is a collection of objects, what's wrong with this? However, at this point seems clear that validation is a Service. So if we put these validations in a Service would eliminate this coupling and apply the OCP again. Do you agree?
A big hug and success!

method name for a long method

The good style (Clean Code book) says that a method's name should describe what the method does. So for example if I have a method that verifies an address, stores it in a database, and sends an email, should the name be something such as verifyAddressAndStoreToDatabaseAndSendEmail(address);
or
verifyAddress_StoreToDatabase_SendEmail(address);
although I can divide that functionality in 3 methods, I'll still need a method to call these 3 methods. So a large method name is inevitable.
Having And named methods certainly describes what the method does, but IMO it's not very readable as names can be very very large. How would you solve it?
EDIT: Maybe I could use fluent style to decompose the method name such as:
verifyAddress(address).storeToDatabase().sendEmail();
but I need a way to ensure the order of invocation. Maybe by using the state pattern, but this causes the code to grow.
How I approach this is to make the 3 smaller methods as you mentioned and then in the higher method that calls the 3 smaller ones, I name it after the "why" I need to do those three things.
Try to define why you need to do those steps and use that as the basis of the method name.
A single method should not do 3 things. Thus divide the work into 3 methods:
verifyAddress
storeAddress
sendEmail
I'm following up on my previous comment, but I've got more here than would fit reasonably in a comment so I'm answering.
The details of the method belong in the documentation not in the name of the method (in my opinion). Think of it this way... By putting SendEmail in the name of the method, you're committing implementation details to the method name. What if a decision is made down the road to send notification via SMS or twitter or something else instead of email? Do you change the name of the method and break your API, or do you have a method name that misleads the consumers of the API? Something to consider.
If you insist on keeping the functionality of the method in its name, I'd urge you to find something more generic. Perhaps something along the lines of VerifySaveAndNotify(Address address). That way, the method name tells you what it's doing without specifying how it does it. The parameter of type Address let's you know what is being verified and saved. All of that works together to make your method name informative, flexible, and terse.
EDIT: Maybe I could use fluent style to decompose the method name such as:
verifyAddress(address).storeToDatabase().sendEmail();
but I need a way to ensure the order of invocation. Maybe by using the state pattern, but this causes the code to grow.
To ensure ordering of commands in a fluent style, each result would be an object that exposes only the functionality required by the next step. For example:
public class Verifier
{
public DataStorer VerifyAddress(string address)
{
...
return new DataStorer(address);
}
}
public class DataStorer
{
public Emailer StoreToDataBase()
{
...
return new Emailer(...);
}
}
public class Emailer
{
public void SendEmail()
{
...
}
}
This is handy if you need to create a very granular design and want to optimise your classes for reuseability, but is likely to be design overkill under most circumstances. Better probably as others have said to choose a name that represents what the whole process is supposed to represent. You could simply call it "StoreAndEmail", making an assumption that verification is something you do routinely before committing data to any destination. The alternative if you don't mind names being long is to simply describe it in full and accept that a long name is necessary. In the end, it really doesn't cost you anything, but can certainly make you code more specific in its intent.

Encapsulation Aggregation / Composition

The Wikipedia article about encapsulation states:
"Encapsulation also protects the integrity of the component, by preventing users from setting the internal data of the component into an invalid or inconsistent state"
I started a discussion about encapsulation on a forum, in which I asked whether you should always clone objects inside setters and/or getters as to preserve the above rule of encapsulation. I figured that, if you want to make sure the objects inside a main object aren't tampered with outside the main object, you should always clone it.
One discussant argued that you should make a distinction between aggregation and composition in this matter. Basically what I think he ment is this:
If you want to return an object that is part of a composition (for instance, a Point of a Rectangle), clone it.
If you want to return an object that is part of aggregation (for instance, a User as part of a UserManager), just return it without breaking the reference.
That made sense to me too. But now I'm a bit confused. And would like to have your opinions on the matter.
Strictly speaking, does encapulation always mandate cloning?
PS.: I program in PHP, where resource management might be a little more relevant, since it's a scripted language.
Strictly speaking, does encapulation always mandate cloning?
No, it does not.
The person you mention is probably confusing the protection of the state of an object with the protection of the implementation details of an object.
Remember this: Encapsulation is a technique to increase the flexibility of our code. A well encapsulated class can change its implementation without impacting its clients. This is the essence of encapsulation.
Suppose the following class:
class PayRoll {
private List<Employee> employees;
public void addEmployee(Employee employee) {
this.employees.add(employee);
}
public List<Employee> getEmployees() {
return this.employees;
}
}
Now, this class has low encapsulation. You can say the method getEmployees breaks encapsulation because by returning the type List you can no longer change this detail of implementation without affecting the clients of the class. I could not change it for instance for a Map collection without potentially affecting client code.
By cloning the state of your object, you are potentially changing the expected behavior from clients. This is a harmful way to interpret encapsulation.
public List<Employee> getEmployees() {
return this.employees.clone();
}
One could say the code above improves encapsulation in the sense that now addEmployee is the only place where the internal List can be modified from. So If I have a design decision to add the new Employee items at the head of the List instead of at the tail. I can do this modification:
public void addEmployee(Employee employee) {
this.employees.insert(employee); //note "insert" is used instead of "add"
}
However, that is a small increment of the encapsulation for a big price. Your clients are getting the impression of having access to the employees when in fact they only have a copy. So If I wanted to update the telephone number of employee John Doe I could mistakenly access the Employee object expecting the changes to be reflected at the next call to to the PayRoll.getEmployees.
A implementation with higher encapsulation would do something like this:
class PayRoll {
private List<Employee> employees;
public void addEmployee(Employee employee) {
this.employees.add(employee);
}
public Employee getEmployee(int position) {
return this.employees.get(position);
}
public int count() {
return this.employees.size();
}
}
Now, If I want to change the List for a Map I can do so freely.
Furthermore, I am not breaking the behavior the clients are probably expecting: When modifying the Employee object from the PayRoll, these modifications are not lost.
I do not want to extend myself too much, but let me know if this is clear or not. I'd be happy to go on to a more detailed example.
No, encapsulation simply mandates the ability to control state by creating a single access point to that state.
For example if you had a field in a class that you wanted to encapsulate you could create a public method that would be the single access point for getting the value that field contains. Encapsulation is simply this process of creating a single access point around that field.
If you wish to change how that field's value is returned (cloning, etc.) you are free to do so since you know that you control the single avenue to that field.

Should multiple service layer objects share a DAO?

I have a Contact class that contains a PortalAccount object. When I want to create a "Portal Account" for a contact, an account is created remotely on a portal application using soap/axis and then the contact's portalAccount is populated and the contact is saved (local database holds information about the remote account, like user id and username, etc).
So I have a service class PortalServiceImpl that has methods to actually create a user on a remote portal, given a Contact instance.
Given all of this information, my question then is: should the PortalServiceImpl get an instance of a ContactDAO object and actually do the saving, or should the PortalServiceImpl class just create the remote user, modify the passed in Contact object, and let the client be responsible for saving?
Method 1:
class ServiceFacadeImpl {
public void createPortalAccount(Contact contact) {
// here the contact is implicitly saved
this.portalService.createPortalAccount(contact);
}
}
Method 2:
class ServiceFacadeImpl {
public void createPortalAccount(Contact contact) {
// here contact is implicitly modified
this.portalService.createPortalAccount(contact);
this.contactDAO.save(contact);
}
}
Both methods feel wrong to me. Method 1 feels wrong because the PortalService is creating a remote user AND saving the contact to the database (albeit through a DAO interface). Method 2 feels wrong because I have to assume that the PortalService is modifying the Contact I'm passing to it.
I also have a feeling that I'm not seeing some other gotchas, like potentially not handling transactions consistently.
(BTW, I've already used both methods, and don't want to continue refactoring in an endless circle. Something just seems wrong here.)
Are you sure it's a good idea that you have different contact IDs locally and remotely? It seems wrong to me, but maybe I just don't know your domain.
In my application all new contacts are sent through the webservice to remote portal and saved there. So, when I save new contact locally, it is sent to a remote portal and saved there. Maybe you need the same?
If the above thoughts are unacceptable for you, then I would do it like this:
class ServiceFacadeImpl {
public void CreatePortalAccountAndSaveContact(Contact contact) {
try
{
contact.portalAccount = this.portalService.createPortalAccount(contact);
this.contactDAO.save(contact);
}
catch(...)
{
// do cleanup, for example do you need to delete account from remote
// portal if it couldn't be saved locally?
// If yes, delete it from portal and set contact.portalAccount = null;
}
}
}
Some may say, that CreatePortalAccountAndSaveContact break single responsibility principle but imo in this situation it's absolutely normal because, as I understand, you need this operation to be atomic. Right?
Or you can add boolean flag to the method, indicating if you want to save contact. But if you always need to save contact with PortalAccount straight after getting it from remote portal - then boolean flag is not needed.
PS. Why do you use "this" keyword? Is portalService private member? If yes, then maybe you need to reconsider your naming convention and name private members with prefix "_" for example (I think it's the most popular one), like _portalService - then it will be easy to understand that _portalService is a private member. Sorry for offtopic.
Good luck.

Should my repository enforce validity of data, if so, where and how?

I have a repository data access pattern like so:
IRepository<T>
{
.. query members ..
void Add(T item);
void Remove(T item);
void SaveChanges();
}
Imagine the scenario where I have a repository of users, users have a user name which is unique, if I create a new user with a username that exists (imagine I have a dumb ui layer that doesn't check), when I add it to the repository, all is fine.. when I hit SaveChanges, my repository attempts to save the item to the database, my database is enforcing these rules luckily and throws me back an aborted exception due to a unique key violation.
It seems to me that, generally this validation is done at the layer ABOVE the repository, the layers that call it know they should ensure this rule, and will pre-check and execute (hopefully in some kind of transaction scope to avoid races, but doesn't always seem possible with the medium ignorance that exists).
Shouldn't my repository be enforcing these rules? what happens if my medium is dumb, such as a flat database without any integrity checks?
And if the repository is validating these kind of things, how would they inform callers about the violation in a way that the caller can accurately identify what went wrong, exceptions seem like a poor way to handle this because their relatively expensive and are hard to specialize down to a specific violation..
I've been playing around with a 'Can' pattern, for example.. CanAdd with Add, add will call CanAdd and throw an invalid operation exception if can returns a violation.. CanAdd also returns a list of violations about what went wrong.. this way I can start to stack these routines through the stack.. for example, the service layer above would also have a 'Can' method that would return the repositories report + any additional violations it wanted to check (such as more complicated business rules, such as which users can invoke specific actions).
Validation of data is such a fundamental yet I feel there is no real guidance for how to handle more advanced validation requirements reliably.
Edit, additionally in this case, how do you handle validation of entities that are in the repository and are updated via change tracking.. for example:
using (var repo = ...)
{
var user = repo.GetUser('user_b');
user.Username = 'user_a';
repo.SaveChanges(); // boom!
}
As you could imagine, this will cause an exception.. going deeper down the rabbit hole, imagine I've got a validation system in place when I add the user, and I do something like this:
using (var repo = ...)
{
var newUser = new User('user_c');
repo.Add(newUser); // so far so good.
var otherUser = repo.GetUser('user_b');
otherUser.Username = 'user_c';
repo.SaveChanges(); // boom!
}
In this case, validating when adding the user was pointless, as 'downstream' actions could screw us up anyway, the add validation rule would need to check the actual persistence storage AND any items queued up to persist.
This still doesn't stop the previous change tracking problem.. so now do I start to validate the save changes call? it seems like there would be a huge amount of violations that could happen from aparently unrelated actions.
Perhaps I'm asking for an unrealistic, perfect safety net?
Thanks in advance,
Stephen.
The ideal rule is that each of your layers should be a black box and none of them should depend on validation of another layer. The reason behind this is that the DB has no idea of the UI and vice versa. So when the DB throws an exception, the UI must have DB knowledge (bad thing) to convert that into something the UI layer can understand, so it can eventually convert it into something the user can understand. Ugh.
Unfortunately, making validation on every layer is also hard. My solution: Either put the validation in a single place (maybe the business layer) and make the other layers really dumb. They don't check anything elsewhere.
Or write your validation in an abstract way into the model and then generate all validation from that. For example:
String name;
Description nameDesc = new Description("name",
new MaxLength(20), new NotNull());
This way, you can write code which examines the Description stuff (generate code or even at runtime) and do the validation in each layer with little cost because one change fixes all layers.
[EDIT] For validation, you only have these cases:
Duplicate key
Above some limit
Below some limit
Null (not specified)
Empty
Formatting error (date fields, etc)
So you should be able to get away with these exception classes which have object, field, old&new value plus special info like the limit that was hit. So I'm wondering where your many exception classes come from.
For your other question, this is ... uh ... "solved" by the two phase commit protocol. I say "solved", because there are situations when the protocol breaks down and in my experience, it's much better to give the user a "Retry?" dialog or some other means to fix the problem rather than investing a lot of time into TPC.

Resources