A domain model that does not contain the business logic for the model is considered an anti-pattern by some -
https://en.wikipedia.org/wiki/Anemic_domain_model
But in some applications, such as .NET applications, seem to prefer a model with out business logic.
Would the following be a good implementation of combining these two concepts.
Have a base model, with the constructor and all "set" statements defined as protected, then have a class that inherits from that base class, which implements the business logic for the base class and helps create the base object. The base model could then be used for something like an MVC View.
Base class -
public class Customer
{
protected Customer()
{
}
public string FirstName { get; protected set; }
public string LastName { get; protected set; }
public int Age { get; protected set; }
}
Inheriting class -
public class CustomerCreator : Customer
{
public void SetFirstName(string firstName)
{
this.FirstName = firstName;
}
public void SetLastName(string lastName)
{
this.LastName = lastName;
}
public string SetAge(int age)
{
string result = "";
if (age < 18)
{
return "can't be less than 18";
}
this.Age = age;
return result;
}
public Customer GetCustomer()
{
return this;
}
}
Are there any potential hazards to this pattern?
Is this a pattern that is already commonly used?
I don't think you're really buying yourself anything here. Ultimately casting to Customer via the GetCustomer() method doesn't actually change anything in terms of the ability to get properties on the model. You're still indirectly robbing your customer of its own business logic with the derived CustomerCreator class. I think you're better off placing your logic in the class you expect to work with (ie Customer) and creating a projection in the form of a viewmodel or DTO for displaying data to the client. Try something like this for your domain model:
public class Customer
{
private int _age;
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age
{
get => _age;
set
{
if (value < 18)
{
throw new ArgumentOutOfRangeException(nameof(Age), "can't be less than 18");
}
_age = value;
}
}
protected Customer() { }
}
A couple of additional points:
I'd recommend avoiding restricting access on your properties unnecessarily. In the case of FirstName and LastName there are no invariants attached to them so the protected setters are not only confusing, but require additional unnecessary indirection to work with. This could also be confusing in the future if other devs (or you after some time away to forget) question why the accessibility was limited to begin with. Going from less to more restricted access modifiers can be done when business rules demand it and it's a relatively safe operation- almost all issues that can arise as a result of restricting access will do so at design time. Going from more restrictive to less restrictive access should always be done with an abundance of caution- if a property/field/method/etc is less than public then hopefully it was designed that way with good reason. Overlooking those reasons can lead the circumvention of invariants, which can lead to runtime issues, inconsistent system state, and corrupt data.
There is nothing particular to C#/.NET that requires or recommends anemic models. Many developers write their models that way and then act upon them with a variety of services, but that general pattern is not necessary by any means nor is it specific to C#. The teams I have worked with implement rich models that are directly persisted and rehydrated via ORMs such as Entity Framework and while it sometimes requires making concessions due the the quirks of a particular ORM, it always ends up working well.
What you're describing is a builder pattern a pattern that's a part of a more broadly defined set of creational patterns. The most obvious examples are builders such as StringBuilder and UriBuilder.
There's a few problems with a builder pattern on the entity side of things in the DDD world, and in particular your current implementation.
First, builders are suitable for value objects, which are fungible and can have value even if not complete (e.g. just a street address with no zip code). For entities, a factory would be more suitable because we want our entities to always be valid (see this great blog entry by Vladimir Khorikov). A factory doesn't turn out an incomplete car, for example; no one would buy that car because, well, it's not a car yet!
Second, your example uses inheritance, and mixes concepts. Let's examine this.
(Wrong) Alternatives
Inheritance models an is-a relationship. Ask yourself, "Is a CustomerBuilder a Customer?" The answer is no; you can say a HouseBuilder (a person) is not a House so inheritance is not appropriate here. It's the same with customers.
You're also not going to do this using composition, which models a has-a relationship. Does a CustomerBuilder have a Customer? No. By analogy, a HouseBuilder does not have a house, a house builder makes a house. Aside: the builder might live in a house, and thus own one, but how does that have anything to do with building some other house?
Creational Patterns
So, the most natural relationship here is a creational one, and in particular a factory. In your case you'd want a customer factory that creates a customer. It accepts all the inputs such as name, age, and so on, and when finally ready to create the customer, it constructs the customer all at once, completely and correctly. If the final customer is not meant to have things like name or age changes, these properties could be made get-only.
What's important here, is that if you extend customer with a builder as you were doing, you could allow that customer to be changed incorrectly; this is antithetical to DDD. Worse, you've got the confusion between the thing being built and the thing doing the building.
Refinements
Ok, so what if your domain allows a customer to age or their name to change? You don't want unfettered write access to these properties. Consider this example: John Doe is 21 years old. Some piece of calling code sets the first name to Mike and then the age to 30 one year later! Makes no sense. Not only is your entity anemic (no internal logic), the logic is external to your domain and allows for time travel!
Let's instead make your Customer less anemic, and provide sensible rules or policies:
public class Customer
{
public Customer(string firstName, string lastName, int age)
{
...
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
public int Age { get; private set; }
public void AgeByOneYear()
=> Age += 1;
public void ChangeFirstName(string newName, IRenamingPolicy renamingPolicy)
=> FirstName = renamingPolicy.ValidateName(newName);
...
}
Relationship of the Factory/Builder to the Domain
In DDD, factories are part of the domain, but not the domain model itself. At this point you may ask, "Well, wait. This factory has domain logic in it, shouldn't that be in the domain model?"
Good question. The answer is yes, and this will make your domain model less anemic. Another aside: you can have entities in your domain model that don't have much (if any) internal logic without your model being considered anemic. As long as the business/domain logic is in your DDD model, and not in your orchestration, persistence, or other layers, you can skate by the anemic label. This is what I did by externalizing renaming logic in a policy, but effecting the renaming action in the Customer. The RenamingPolicy contains domain logic and is part of your domain.
Final Thoughts
Anemic models (or not) and creational patterns are orthogonal concepts, but I've shown how thinking of them together can lead to a coherent domain model.
Using a Customer entity (even if it was a base class of some kind) is probably not a good idea to use as an MVC view or view model. The needs are different; an entity has behavior in a domain whereas a view model is anemic and expresses properties that are bound to a view for presentation.
If your experience is that .NET domain models are anemic, I'd say that's anecdotal and shouldn't set precedent. For simple apps, that's fine; for rich enterprise apps, you might be looking at a bad design.
A model is anemic if you are using it to just store/carry data and keeping business logic related to it in some other place.
In your example you are inheriting a class purely to create Customer object in a specific way but it's not really protecting any in-variance other than supporting a style of writing code. While I refrain to say something is wrong because there might be a reason behind it, I fail to see a valid one here.
Two main purpose of a language supporting inheritance, in my opinion/understanding are:
Code reuse
Encapsulation - indirect
If you really want to protect how a Customer Object can be instantiated, you could have a static factory method on the Customer class itself. However that doesn't make that model 'rich'.
Difference between 'rich' and 'anemic' is where you decide to keep the business logic - outside of your domain entities (aggregates to be precise but will go with entity for simplicity) or as an operation on domain entities.
If you consider your system as a series of coordinated state changes of entities, you have a choice where you keep the logic of that state change. In rich model you include it as an operation on the entity itself so you have tighter control maintaining the invariant.
is it possible to make this validation:
class Man {
#Unique
String name;
}
class Order {
#Valid
List<Man> manCollection;
}
where is unique logic is: every item in collection manCollection is unique.
You could make this snippet ambiguous just by adding a Customer class that contains a List of Orders:
class Man {
#Unique
String name;
}
class Order {
#Valid
List<Man> manCollection;
}
class Customer {
#Valid
List<Order> orderCollection;
}
Then one couldn't possibly know whether the Man objects must be unique within a given Order or within a given Customer (or both).
So I don't think it's possible with this exact syntax, regardless of what the Bean Validation APIs allow.
What you could do is move the annotation to manCollection, e.g. #UniqueMen List<Man> manCollection;, and implement a ConstraintValidator<List<Man>>.
If it's useful to you, you could even make a more generic #UniqueContent annotation, but that would be much more complex. You would need to pass the target type as a parameter (#UniqueContent(target = Man.class)) and write a validator that parses annotations on the target class in its initialize method. Be careful to use some caching mechanism, though, because annotation parsing is quite slow.
How can I validate the below class using validator (JSR303) API? This should be done using Hibernate Validator API.
Suppose TesterBatters class itself has some validation. How can I validate those?
public class Example {
private String jseId;
private String jseType;
private String jseName;
private Double jsePpu;
private TesterBatters jseBatters;
private List<TesterToppin> jseTopping;
public String getTesterId() {
return jseId;
}
}
You basically have to add constraint annotations such as #NotNull, #Size etc. to the elements of your model (i.e. the properties and/or classes) and perform a validation of these constraints at a suitable point of time (e.g. when persisting objects or processing data entered by the user into a GUI) using the javax.validation.Validator API.
To recursively apply a validation to referenced objects, use the #Valid annotation.
I recommend to have a look into the Hibernate Validator reference guide which explains in detail how to work with Bean Validation.
I'm writing a custom validator for a specific constrain group (not Default), but the runtime gives me the below error.
I'm just curious why they need the default values to be empty. Appreciate if you can share your opinion. Thanks :)
xxx.model.validation.CustomValidation contains Constraint annotation, but the groups parameter default value is not the empty array.
StackTrace: org.hibernate.validator.metadata.ConstraintHelper.assertGroupsParameterExists(ConstraintHelper.java:335)
org.hibernate.validator.metadata.ConstraintHelper.isConstraintAnnotation(ConstraintHelper.java:282)
I can't figure out in which scenario it can be useful to bind a constraint to a specific group.
A group is used for partial validation (and sequence validation). If you have 10 fields in a class you can mark 8 of them with A and 2 with B. Then you can decide to validate only the fields in the A group or in the B group. Conversely you want that #MyConstraint belongs to a specific group named C. It makes no sense. A group is more or less a name used to distinguish some fields from others in the same class. It has no absolute meaning. Groups are useful in validation not in constraint definition, they are related to fields not to constraints.
Furthermore if you hide the group name in the constraint definition you may run into errors because you can think that the fields are validated all togheter.
#Email
private String mail;
#Password
private String pass;
#VAT
private String vatCode;
Are you able to see if there is a partial validation?
EDIT
In relation to the second comment:
Suppose you have a class with 5 fields with no constraint at all. Three of them are integers. If you want to validate the sum of these three fields you have to create a class-level constraint as you suggest. In this way your custom annotation is applied to the class not to fields so, how can you define groups on fields?
Instead, you may use something like this:
#Sum(min = 250, fields = {"length", "width", "height"})
public class MyClass {
private String type;
private String code;
private int length;
private int width;
private int height;
...
}
I need to bind request parameters to an instance of the following Java class (getters and setters omitted):
public class ShippingHouse {
private String name;
private String description;
private List<ShippingRule> shippingRules = new ArrayList<ShippingRule>();
}
public class ShippingRule {
private ShippingHouse shippingHouse;
private String name
}
Notice that there is a 1:N relationship between ShippingHouse and ShippingRule, but each ShippingRule also has a reference to the ShippingHouse thaat owns it.
If these were Grails command/domain classes, I would bind them with request parameters
name=foo&description=bar&shippingRules[0].name=sr0&shippingRules[1].name=sr1
But it doesn't seem like this will set the reference to the owning ShippingHouse within each ShippingRule. Is there a way I can bind this automatically, or must I write the code myself?
Don,
You will need to write code to do it yourself using BindUsing or some other approach. The binder doesn't (and shouldn't) assume anything about back references from a parent to a child. If these were GORM entities and the relationship was explicit, that is different, but in your case the binder should not assume that shippingHouse property in the ShippingRule class has anything to do with the shippingRules property in the ShippingHouse class.
Also note that lucke84 said that your "private" is implicit. Make sure you understand what that means if you are going to remove them. If you remove them the compiler is going to generate public getter and setter methods for those properties, which may or may not be what you want.
If you want to implement a 1:N relationship between the two classes, you should use the right grails approach. Something like this:
class ShippingHouse {
String name
String description
static hasMany = [shippingRules: ShippingRule]
}
class ShippingRule {
String name
static belongsTo = [shippingHouse: ShippingHouse]
}
Please note that semicolons are useless and the "private" declaration on class fields is implicit.