Right now, I have a domain entity named StyleBundle. This StyleBundle takes a list of Styles:
public class StyleBundle
{
public StyleBundle(List<Style> styles)
{
this.Styles = styles;
}
public IEnumerable<Style> Styles { get; private set;}
}
So, in my original design, a StyleBundle should never be created with an empty Style list. This was a rule that the domain experts basically said was good.
I wrote this using a guard clause in the constructor:
if (styles.Count() == 0)
throw new Exception("You must have at least one Style in a StyleBundle.");
which made sure I could not create StyleBundle in an invalid state. I thought an exception made sense here b/c a StyleBundle being created without at least one Style was exceptional in the system.
Of course, change came down the road during the rest of the project, and now it should be possible for a user to create a StyleBundle without Styles, but they should not be allowed to PERSIST a StyleBundle without Styles.
So now I'm looking at my guard clause and realizing that I can't have the exception thrown from the constructor anymore.
Moving forward, I have a Service/Application layer that my code-behinds interact with when they're working with StyleBundles. In my Service Layer, I have a StyleBundleService class, and that class exposes basic functionality to the UI... among them is "CreateStyleBundle".
It seems as if I'll have to have my Service Layer check to see if the StyleBundle does or does not have any Styles before it's persisted to the database, but something about this decision feels "wrong" to me.
Anyone run into a similar thing? Basically, the different between the state of an object being valid when "new'ed up" vs. the state of the same object when it comes to persistence?
Thanks!
Mike
I would add an IsValid method to your entity. This would check if the entity is currently in a valid state (in your case, check if there are styles).
This method can be called from your Repository to check if an entity may be persisted. You can add more rules to the IsValid method for specific entities and you can implement something like a collection of Validation errors is you want to throw a meaningful exception.
Expanding what Wouter said, plus handy BeforeSaving and BeforeDeleting methods:
public interface IDomainObject<T>
{
bool IsValid();
}
public interface IEntity<T> : IDomainObject<T>
{
}
public interface IAggregateRoot<T> : IEntity<T>
{
void BeforeSaving();
void BeforeDeleting();
}
public interface IAggregateRoot { //or simply IEntity depending on the model
bool IsValid();
}
public class StyleBundle : IAggregateRoot<T> {
return styles.Count() > 0
}
public class StyleBundleRepository : Repository<StyleBundle> {
}
public abstract class Repository<T> : IRepository<T> where T : class, IAggregateRoot<T> {
public T Save(T t)
{
t.BeforeSaving(); //for all AggregateRoots, maybe logging what the aggregate was like before the changes
if(!t.IsValid())
throw Exeception("Entity invalid");
EntityStore.Current.SaveChanges();
// "AfterSaving" here, i.e.: log how the entity looks after the update
}
}
Edit: I dont personally use the IsValid idea, I go with a full class of EntityValidationErrors where I can report back to the client what was wrong before attempting to save, things that shouldnt be null, shouldnt be empty (like your Styles etc)
There are multiple strategies:
Some developers prefer to create 2 methods in the entity itself, one called IsValid() which validates the entity in terms of business rules (general validation) and another one called IsValidForPersistence() which validates the entity for persistence.
Regarding IsValid() I prefer instead not to allow invalid state in the first place by validating all inputs, and to support invariants I use factory or builder.
you may check the link http://www.codethinked.com/thoughts-on-domain-validation-part-1
for some thoughts.
I know, this question is three years old, but seeing the current answer is something I like to respond to. We are talking about the domain data. Hence, there can't be a valid StyleBundle with 0 objects. I imagine, you have a frontend editor somewhere, were you create a "new" StyleBundle and have to add at least one style, before hitting the "save" button.
At this point in the frontend, you won't have a domain object. You may have a data transfer object, that will be send with a "CreateNewStyleBundle" command.
In my opinion, the domain object must be agnostic to persitance and should always be in a valid state. If you have to call a "IsValid" method, you circumvent the whole idea of having domain objects in the first place.
That's just my humble opinion.
Related
A 3rd party is sending me part of the data to fill in my domain object via a query string. I need to partially fill in my domain object, and then have the user fill in the rest via a form. I don't have any control over the query string parameters coming in, so I can't change those, but I'd really like to be able to use Spring MVC's data binding abilities, rather than doing it by hand.
How can I do this?
To add some complication to this, some of the parameters will require extensive processing because they map to other objects (such as mapping to a user from just a name) that may not even exist yet and will need to be created. This aspect, I assume, can be handled using property editors. If I run into trouble with this, I will ask another question.
Once I have a partially filled domain object, passing it on to the edit view, etc. is no problem, but I don't know how to properly deal with the initial domain object population.
The only thing I have been able to come up with so far is to have an extra class that has it's properties named to match the inbound query parameters and a function to convert from this intermediary class to my domain class.
This seems like a lot of overhead though just to map between variable names.
Can you not just have the getter named differently from the setter, or have 2 getters and 2 setters if necessary?
private int spn;
// Standard getter/setter
public int getSpn() {
return spn;
}
public void setSpn(int spn) {
this.spn = spn;
}
// More descriptively named getter/setter
public int getShortParameterName() {
return spn;
}
public void setShortParameterName(int spn) {
this.spn = spn;
}
Maybe that is not standard bean convention, but surely would work?
I'd like to include some additional functions in my Doctrine 2 entities to contain code that I'm going to have to run quite frequently. For example:
User - has many Posts
Post - has a single user
I already have a function $user->getPosts(), but this returns all of my posts. I'm looking to write a $user->getActivePosts(), which would be like:
$user->getPosts()->where('active = true') //if this were possible
or:
$em->getRepository('Posts')->findBy(array('user'=>$user,'active'=>true)) //if this were more convenient
As far as I can tell, there's no way to get back to the entity manager though the Entity itself, so my only option would be
class User {
function getActivePosts() {
$all_posts = $this->getPosts();
$active_posts = new ArrayCollection();
foreach ($all_posts as $post) {
if ($post->getActive()) {
$active_posts->add($post);
}
}
return $active_posts;
}
However, this requires me to load ALL posts into my entity manager, when I really only want a small subset of them, and it requires me to do filtering in PHP, when it would be much more appropriate to do so in the SQL layer. Is there any way to accomplish what I'm looking to do inside the Entity, or do I have to create code outside of it?
I think you should implement the method on the PostRepository rather than on the entity model.
I try to keep all model related logic in the repositories behind "domain specific" methods. That way if you change the way you represent whether a post is active or not, you only have to change the implementation of a single method instead of having to find all the active = true statements scattered around in your application or making changes in an "unrelated" entity model.
Something like this
PostRepository extends EntityRepository {
public function findActiveByUser($user){
// whatever it takes to get the active posts
}
}
"Replace conditional with polymorphism" is elegant only when type of object you're doing switch/if statement for is already selected for you. As an example, I have a web application which reads a query string parameter called "action". Action can have "view", "edit", "sort", and etc. values. So how do I implement this with polymorphism? Well, I can create an abstract class called BaseAction, and derive ViewAction, EditAction, and SortAction from it. But don't I need a conditional to decided which flavor of type BaseAction to instantiate? I don't see how you can entirely replace conditionals with polymorphism. If anything, the conditionals are just getting pushed up to the top of the chain.
EDIT:
public abstract class BaseAction
{
public abstract void doSomething();
}
public class ViewAction : BaseAction
{
public override void doSomething() { // perform a view action here... }
}
public class EditAction : BaseAction
{
public override void doSomething() { // perform an edit action here... }
}
public class SortAction : BaseAction
{
public override void doSomething() { // perform a sort action here... }
}
string action = "view"; // suppose user can pass either "view", "edit", or "sort" strings to you.
BaseAction theAction = null;
switch (action)
{
case "view":
theAction = new ViewAction();
break;
case "edit":
theAction = new EditAction();
break;
case "sort":
theAction = new SortAction();
break;
}
theAction.doSomething(); // So I don't need conditionals here, but I still need it to decide which BaseAction type to instantiate first. There's no way to completely get rid of the conditionals.
You're right - "the conditionals are getting pushed up to the top of the chain" - but there's no "just" about it. It's very powerful. As #thkala says, you just make the choice once; from there on out, the object knows how to go about its business. The approach you describe - BaseAction, ViewAction, and the rest - is a good way to go about it. Try it out and see how much cleaner your code becomes.
When you've got one factory method that takes a string like "View" and returns an Action, and you call that, you have isolated your conditionality. That's great. And you can't properly appreciate the power 'til you've tried it - so give it a shot!
Even though the last answer was a year ago, I would like to make some reviews/comments on this topic.
Answers Review
I agree with #CarlManaster about coding the switch statement once to avoid all well known problems of dealing with duplicated code, in this case involving conditionals (some of them mentioned by #thkala).
I don't believe the approach proposed by #KonradSzałwiński or #AlexanderKogtenkov fits this scenario for two reasons:
First, from the problem you've described, you don't need to dynamically change the mapping between the name of an action and the instance of an action that handles it.
Notice these solutions allows doing that (by simply assigning an action name to a new action instance), while the static switch-based solution doesn't (the mappings are hardcoded).
Also, you'll still need a conditional to check if a given key is defined in the mapping table, if not an action should be taken (the default part of a switch statement).
Second, in this particular example, dictionaries are really hidden implementations of switch statement. Even more, it might be easier to read/understand the switch statement with the default clause than having to mentally execute the code that returns the handling object from the mapping table, including the handling of a not defined key.
There is a way you can get rid of all conditionals, including the switch statement:
Removing the switch statement (use no conditionals at all)
How to create the right action object from the action name?
I'll be language-agnostic so this answer doesn't get that long, but the trick is to realize classes are objects too.
If you've already defined a polimorphic hierarchy, it makes no sense to make reference to a concrete subclass of BaseAction: why not ask it to return the right instance handling an action by its name?
That is usually implemented by the same switch statement you had written (say, a factory method)... but what about this:
public class BaseAction {
//I'm using this notation to write a class method
public static handlingByName(anActionName) {
subclasses = this.concreteSubclasses()
handlingClass = subclasses.detect(x => x.handlesByName(anActionName));
return new handlingClass();
}
}
So, what is that method doing?
First, retrieves all concrete subclasses of this (which points to BaseAction). In your example you would get back a collection with ViewAction, EditAction and SortAction.
Notice that I said concrete subclasses, not all subclasses. If the hierarchy is deeper, concrete subclasses will always be the ones in the bottom of the hierarchy (leaf). That's because they are the only ones supposed not to be abstract and provide real implementation.
Second, get the first subclass that answer whether or not it can handle an action by its name (I'm using a lambda/closure flavored notation). A sample implementation of the handlesByName class method for ViewAction would look like:
public static class ViewAction {
public static bool handlesByName(anActionName) {
return anActionName == 'view'
}
}
Third, we send the message new to the class that handles the action, effectively creating an instance of it.
Of course, you have to deal with the case when none of the subclass handles the action by it's name. Many programming languages, including Smalltalk and Ruby, allows passing the detect method a second lambda/closure that will only get evaluated if none of the subclasses matches the criteria.
Also, you will have to deal with the case more than one subclass handles the action by its name (probably, one of these methods was coded in the wrong way).
Conclusion
One advantage of this approach is that new actions can be supported by writing (and not modifying) existing code: just create a new subclass of BaseAction and implementing the handlesByName class method correctly. It effectively supports adding a new feature by adding a new concept, without modifying the existing impementation. It is clear that, if the new feature requires a new polimorphic method to be added to the hierarchy, changes will be needed.
Also, you can provide the developers using your system feedback: "The action provided is not handled by any subclass of BaseAction, please create a new subclass and implement the abstract methods". For me, the fact that the model itself tells you what's wrong (instead of trying to execute mentally a look up table) adds value and clear directions about what has to be done.
Yes, this might sound over-design. Please keep an open mind and realize that whether a solution is over-designed or not has to do, among other things, with the development culture of the particular programming language you're using. For example, .NET guys probably won't be using it because the .NET doesn't allow you to treat classes as real objects, while in the other hand, that solution is used in Smalltalk/Ruby cultures.
Finally, use common sense and taste to determine beforehand if a particular technique really solves your problem before using it. It is tempting yes, but all trade-offs (culture, seniority of the developers, resistance to change, open mindness, etc) should be evaluated.
A few things to consider:
You only instantiate each object once. Once you do that, no more conditionals should be needed regarding its type.
Even in one-time instances, how many conditionals would you get rid of, if you used sub-classes? Code using conditionals like this is quite prone to being full of the exact same conditional again and again and again...
What happens when you need a foo Action value in the future? How many places will you have to modify?
What if you need a bar that is only slightly different than foo? With classes, you just inherit BarAction from FooAction, overriding the one thing that you need to change.
In the long run object oriented code is generally easier to maintain than procedural code - the gurus won't have an issue with either, but for the rest of us there is a difference.
Your example does not require polymorphism, and it may not be advised. The original idea of replacing conditional logic with polymorphic dispatch is sound though.
Here's the difference: in your example you have a small fixed (and predetermined) set of actions. Furthermore the actions are not strongly related in the sense that 'sort' and 'edit' actions have little in common. Polymorphism is over-architecting your solution.
On the other hand, if you have lots of objects with specialised behaviour for a common notion, polymorphism is exactly what you want. For example, in a game there may be many objects that the player can 'activate', but each responds differently. You could implement this with complex conditions (or more likely a switch statement), but polymorphism would be better. Polymorphism allows you to introduce new objects and behaviours that were not part of your original design (but fit within its ethos).
In your example, in would still be a good idea to abstract over the objects that support the view/edit/sort actions, but perhaps not abstract these actions themselves. Here's a test: would you ever want to put those actions in a collection? Probably not, but you might have a list of the objects that support them.
There are several ways to translate an input string to an object of a given type and a conditional is definitely one of them. Depending on the implementation language it might also be possible to use a switch statement that allows to specify expected strings as indexes and create or fetch an object of the corresponding type. Still there is a better way of doing that.
A lookup table can be used to map input strings to the required objects:
action = table.lookup (action_name); // Retrieve an action by its name
if (action == null) ... // No matching action is found
The initialization code would take care of creating the required objects, for example
table ["edit"] = new EditAction ();
table ["view"] = new ViewAction ();
...
This is the basic scheme that can be extended to cover more details, such as additional arguments of the action objects, normalization of the action names before using them for table lookup, replacing a table with a plain array by using integers instead of strings to identify requested actions, etc.
I've been thinking about this problem probably more than the rest developers that I met. Most of them are totally unaware cost of maintaining long nested if-else statement or switch cases. I totally understand your problem in applying solution called "Replace conditional with polymorphism" in your case. You successfully noticed that polymorphism works as long as object is already selected. It has been also said in this tread that this problem can be reduced to association [key] -> [class]. Here is for example AS3 implementation of the solution.
private var _mapping:Dictionary;
private function map():void
{
_mapping["view"] = new ViewAction();
_mapping["edit"] = new EditAction();
_mapping["sort"] = new SortAction();
}
private function getAction(key:String):BaseAction
{
return _mapping[key] as BaseAction;
}
Running that would you like:
public function run(action:String):void
{
var selectedAction:BaseAction = _mapping[action];
selectedAction.apply();
}
In ActionScript3 there is a global function called getDefinitionByName(key:String):Class. The idea is to use your key values to match the names of the classes that represent the solution to your condition. In your case you would need to change "view" to "ViewAction", "edit" to "EditAction" and "sort" to "SortAtion". The is no need to memorize anything using lookup tables. The function run will look like this:
public function run(action:Script):void
{
var class:Class = getDefintionByName(action);
var selectedAction:BaseAction = new class();
selectedAction.apply();
}
Unfortunately you loose compile checking with this solution, but you get flexibility for adding new actions. If you create a new key the only thing you need to do is create an appropriate class that will handle it.
Please leave a comment even if you disagree with me.
public abstract class BaseAction
{
public abstract void doSomething();
}
public class ViewAction : BaseAction
{
public override void doSomething() { // perform a view action here... }
}
public class EditAction : BaseAction
{
public override void doSomething() { // perform an edit action here... }
}
public class SortAction : BaseAction
{
public override void doSomething() { // perform a sort action here... }
}
string action = "view"; // suppose user can pass either
// "view", "edit", or "sort" strings to you.
BaseAction theAction = null;
switch (action)
{
case "view":
theAction = new ViewAction();
break;
case "edit":
theAction = new EditAction();
break;
case "sort":
theAction = new SortAction();
break;
}
theAction.doSomething();
So I don't need conditionals here, but I still need it to decide which BaseAction type to instantiate first. There's no way to completely get rid of the conditionals.
Polymorphism is a method of binding. It is a special case of thing known as "Object Model". Object models are used to manipulate complex systems, like circuit or drawing. Consider something stored/marshalled it text format: item "A", connected to item "B" and "C". Now you need to know what is connected to A. A guy may say that I'm not going to create an Object Model for this because I can count it while parsing, single-pass. In this case, you may be right, you may get away without object model. But what if you need to do a lot of complex manipulations with imported design? Will you manipulate it in text format or sending messages by invoking java methods and referencing java objects is more convenient? That is why it was mentioned that you need to do the translation only once.
You can store string and corresponding action type somewhere in hash map.
public abstract class BaseAction
{
public abstract void doSomething();
}
public class ViewAction : BaseAction
{
public override void doSomething() { // perform a view action here... }
}
public class EditAction : BaseAction
{
public override void doSomething() { // perform an edit action here... }
}
public class SortAction : BaseAction
{
public override void doSomething() { // perform a sort action here... }
}
string action = "view"; // suppose user can pass either
// "view", "edit", or "sort" strings to you.
BaseAction theAction = null;
theAction = actionMap.get(action); // decide at runtime, no conditions
theAction.doSomething();
The switch is simple and looks OK. I don't think it would be that secure if a user could feed in a class name and you could directly use it without a switch conditional.
For obtaining data though, Coders have been known to use a look up table loop to get extra data reducing it to one if in an array look up search. Still thinking the switch looks simple enough to understand but would be cumbersome if you had 100s of choices.
I am developing application having business objects created from EF 4.0. The application is layered with Data Layer having repository of classes. Above that is a business layer where business processes are mapped as per the requirements. Business layer is calling data layer.
Business objects have complex associations. One scenario:
Merchant has Multiple Addresses
Merchant belongs to one Category
Merchant has an Account
Account has a Wallet
User will be creating a new merchant along with above mentioned business objects (graph). There are various business rules when creating and updating a merchant.
I would like to split my validations into two sub sections. 1) Scalar Property Validation to be handled by Validation Blocks 5.0 and 2) Business Process Rules Validation to be handled in business layer components. However, i am facing difficulty on having a centralized way to report broken rules (Scalar Properties validation and Business Process Rule Validation). I don't want to inject exceptions everywhere where business rule in is violated as per the business process mapped.
One e.g is following:
When creating a new merchant, Category needs to be validated. Because if a certain type category is associated with this new merchant then business rule says that such merchant cannot exists twice in the system.
Now, when a UI pass the new merchant graph to business layer component, i first validate BO Scalar properties validation (validated bu Validation Blocks) then this BO is passed into business process rule validation methods to check various rules. There are possible violation points which i want to report and shall not allow the merchant and graph objects to be persisted.
Please share any value able design approach to manage centralized validation rule logging and reporting to UI layer.
EDIT: I don't want to incorporate validations on EF SaveChanges, ChangeAssociation etc event handlers.
While you said you don't want to throw exceptions, I found throwing exceptions very effective. Especially when you having multiple sub systems validating the system, throwing one single type of exception as a facade will be very effective.
What you can do is creating a custom exception (i.e. named ValidationException) that will be thrown either when your Validation Application Block (VAB) reports error or the business rules report errors. In the presentation layer you will have to catch this ValidationException and report this exact type of exception in a user friendly way to the end user.
Using a single exception type for both validation sub systems, allows you to report errors in a consistent way, and also ensures that validation errors won't get unnoticed when you (or an other developer) forgets to handle validation errors. Handling errors should be very explicit IMO. When you let methods return a list of errors it is easy to forget to handle them. When creating a custom exception, it is easy to add a property to that exception type that contains a list of validation errors. Such a list of errors is easily extracted from VAB. I don't know what validation system you use for your business rules validation, but it can't be to hard to extract a list of error codes from it.
The most simple way to handle this in UI is of course by using a try-catch:
var businessCommand = new CreateNewMerchantCommand();
businessCommand.Name = "Wikki";
// etc
try
{
businessCommand.Execute();
}
catch (ValidationException ex)
{
UIValidationHelper.ReportValidationErrors(ex.Errors);
}
Of course having these try-catch statements all over the place is ugly, but at least this code is easy to follow. Dependent on how you structured your business layer and the UI technology you use, there are prettier solutions you could use. For instance, you can wrap the actual operation that can fail with an action as follows:
var businessCommand = new CreateNewMerchantCommand();
businessCommand.Name = "Wikki";
// etc
UIValidationHelper.ExecuteOrDisplayErrors(() =>
{
businessCommand.Execute();
});
The UIValidationHelper would look like this:
public static class UIValidationHelper
{
public static void ExecuteOrDisplayErrors (Action action)
{
try
{
action();
}
catch (ValidationException ex)
{
// Show the errors in your UI technology
ShowErrorMessage(ex.Errors);
}
}
}
An other option, that I've used myself in the past, is by extending the business layer with events. For this to work you need a construct such as commands, as I use in my examples. When using events, the UI could look like this:
var businessCommand = new CreateNewMerchantCommand();
businessCommand.Name = "Wikki";
// etc
businessCommand.ValidationErrorOccurred +=
UIValidationHelper.DisplayValidationErrors;
businessCommand.Execute();
This example hooks a static method to the ValidationErrorOccurred event of a command instance. The trick here is to let the Execute method of that command catch ValidationExceptions and route them to the ValidationErrorOccurred when it is registered. When no method is registered, this exception should bubble up the call stack, because an unhandled validation exception should of course not get unnoticed.
While it is possible to of course do this directly from your business layer, it would make your business layer dependent on a particular validation technology. Besides this, this method allows clients to choose to handle validation errors in any way they want or decide not to handle them at all (for instance when you don’t expect any validation errors to occur in a particular use case).
When using ASP.NET Web Forms, the DisplayValidationErrors method of the UIValidationHelper could look like this:
public static class UIValidationHelper
{
public static void DisplayValidationErrors(
object sender, ValidationErrorEventArgs e)
{
Page page = GetValidPageFromCurrentHttpContext();
var summary = GetValidationSummaryFromPage()
foreach (var result in e.Error.Results)
{
summary.Controls.Add(new CustomValidator
{
ErrorMessage = result.Message,
IsValid = false
});
}
}
private static Page GetValidPageFromCurrentHttpContext()
{
return (Page)HttpContext.Current.CurrentHandler;
}
private ValidationSummary GetValidationSummaryFromPage(Page page)
{
return page.Controls.OfType<ValidationSummary>().First();
}
}
This static helper method injects the messages of the reported errors into a ValidationSummary control on the page. It expects the page to contain a ValidationSummary control at root level of the page. A more flexible solution can easily be created.
The last thing that I like to show you is how the the BusinessCommand would look like when adopting this solution. The base class of these commands could look something like this:
public abstract class BusinessCommand
{
public event EventHandler<ValidationErrorEventArgs>
ValidationErrorOccurred;
public void Execute()
{
try
{
this.ExecuteInternal();
}
catch (ValidationException ex)
{
if (this.ValidationErrorOccurred != null)
{
var e = new ValidationErrorEventArgs(ex);
this.ValidationErrorOccurred(this, e);
}
else
{
// Not rethrowing here would be a bad thing!
throw;
}
}
}
protected abstract void ExecuteInternal();
}
The ValidationErrorEventArgs looks like this:
public class ValidationErrorEventArgs : EventArgs
{
public ValidationErrorEventArgs(ValidationException error)
{
this.Error = error;
}
public ValidationException Error { get; private set; }
}
I hope this all makes sense and sorry for my long answer :-)
Good luck.
Object member validation can be done within encapsulated business objects. Whether you do this in the setter properties or as separate method calls is up to you. Should the objects be set with values that are invalid, should the application allow data into the system that is of the wrong type, range checks etc.
As for the Rules part, I would look at the visitor pattern for each object graph that your trying to achieve some rules checking on. I would report this back probably as a new nested object based on what was found. My personal preference to this reporting side, is to use a visitor pattern that produces an XML Document or some other custom nested class depending on your efficiency needs. The actual rules within the visitor pattern can be declared outside of the visitor pattern, preferably in a declarative approach. For example CheckDuplicateRecord. This would allow for reuse.
Keep all this in the same layer as the Business Layer, but further sub divide the business layer into a Rules validation layer and the Business Objects.
My personal approach with using EF is to use POCO objects as these allow for scalability. I would then do some validation on the UI, then do some validation when transported to the Business Object layer, then do the same again in the EF DAL layer.
I am attempting to create the the business and data layers for my big ASP.NET MVC application. As this is the first time for me attempting a project of this scale I am reading some books and trying to take good care at separating things out properly. Usually my applications mix the business logic and data access layers, and multiple business entities are intertwined in the single class (which has confused me a few times when I was trying to figure out where to add things).
Most of what I have been reading is to separate out the business and data layers. This seems all fine and dandy, but I am having trouble visualizing exactly how to do this in some scenarios. For example, let's say I am creating a system that allows admins to add a new product to the system:
public class Product
{
public int Id { get; private set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Then I separate out the data access by creating a repository
public class ProductRepository
{
public bool Add(Product product);
}
Let's say I want to require a product's name to have at least 4 characters. I can't see how to do this cleanly.
One idea I had was to expand the Name's set property and only set it if it's 4 characters long. However, there is no way for a method that is creating the product to know the name didn't get set except that Product.Name != whatever they passed in.
Another idea I had is to put it in the Add() method in the repository, but then I have my business logic right there with the data logic, which also means if the Add call fails I don't know if it failed for the business logic or because the DAL failed (and it also means I can't test it using mock frameworks).
The only thing I can think of is to put my DAL stuff in a 3rd layer that gets called from the Add() method in the repository, but I don't see this in any of the domain modelling examples in my book or on the web (that I've seen at least). It also adds to the complexity of the domain models when I am not sure it is needed.
Another example is wanting to make sure that a Name is only used by one product. Would this go in the Product class, ProductRepository Add() method, or where?
As a side note, I plan to use NHibernate as my ORM however, to accomplish what I want it (theoretically) shouldn't matter what ORM I am using since TDD should be able to isolate it all.
Thanks in advance!
I usually approach this by using a layered architecture. How to do this? You basically have the following (ideally) VS projects:
Presentation layer (where the UI stuff resides)
Business layer (where the actual business logic resides)
Data access layer (where you communicate with your underlying DBMS)
For decoupling all of them I use so-called interface layers s.t. in the end I have
Presentation layer (where the UI
stuff resides)
IBusiness layer (containing the interfaces for the
business layer)
Business layer (where
the actual business logic resides)
IDataAccess layer (containing the
interfaces for the DAO layer)
Data access layer (where you communicate
with your underlying DBMS)
This is extremely handy and creates a nicely decoupled architecture. Basically your presentation layer just accesses the interfaces and not the implementations itself. For creating the according instances you should use a Factory or preferably some dependency injection library (Unity is good for .Net apps or alternatively Spring.Net).
How does this impact on your business logic / testability of your app?
It is probably too long to write everything in detail, but if you're concerned about having a well testable design you should absolutely consider dependency injection libraries.
Using NHibernate,...whatever ORM
Having a DAO layer completely separated through the interfaces from the other layers you can use whatever technology behind for accessing your underlying DB. You could directly issue SQL queries or use NHibernate, as you wish. The nice thing is that it is totally independent from the rest of your app. You could event start today by writing SQLs manually and tomorrow exchange your DAO dll with one that uses NHibernate without a single change in your BL or presentation layer.
Moreover testing your BL logic is simple. You may have a class like:
public class ProductsBl : IProductsBL
{
//this gets injected by some framework
public IProductsDao ProductsDao { get; set; }
public void SaveProduct(Product product)
{
//do validation against the product object and react appropriately
...
//persist it down if valid
ProductsDao.PersistProduct(product);
}
...
}
Now you can easily test the validation logic in your SaveProduct(...) method by mocking out the ProductDao in your test case.
Put things like the product name restriction in the domain object, Product, unless you want to allow products with fewer than 4 characters in some scenarios (in this case, you'd apply the 4-character rule at the level of the controller and/or client-side). Remember, your domain objects may be reused by other controllers, actions, internal methods, or even other applications if you share the library. Your validation should be appropriate to the abstraction you are modeling, regardless of application or use case.
Since you are using ASP .NET MVC, you should take advantage of the rich and highly extensible validation APIs included in the framework (search with keywords IDataErrorInfo MVC Validation Application Block DataAnnotations for more). There are lots of ways for the calling method to know that your domain object rejected an argument -- for example, throwing the ArgumentOutOfRangeException.
For the example of ensuring that product names are unique, you would absolutely not put that in Product class, because this requires knowledge of all other Products. This logically belongs at the persistence layer and optionally, the repository. Depending on your use case may warrant a separate service method that verifies that the name does not already exist, but you shouldn't assume that it will still be unique when you later try to persist it (it has to be checked again, because if you validate uniqueness and then keep it around a while longer before persisting, someone else could still persist a record with the same name).
This is the way I do it:
I keep the validation code in the entity class, which inherits some general Item Interface.
Interface Item {
bool Validate();
}
Then, in the repository's CRUD functions i call the appropriate Validate function.
This way all the logic paths are validating my values, but i need to look only in one place to see what that validation really is.
Plus, sometimes you use the entities outside the repository scope, for example in a View. So if the validation is separated, each action path can test for validation without asking the repository.
For restrictions I utilize the partial classes on the DAL and implement the data annotation validators. Quite often, that involves creating custom validators but that works great as it's completely flexible. I've been able to create very complex dependent validations that even hit the database as part of their validity checks.
http://www.asp.net/(S(ywiyuluxr3qb2dfva1z5lgeg))/learn/mvc/tutorial-39-cs.aspx
In keeping with the SRP (single responsibility principle), you might be better served if the validation is separate from the product's domain logic. Since it's required for data integrity, it should probably be closer to the repository - you just want to be sure that validation is always run without having to give it thought.
In this case you might have a generic interface (e.g. IValidationProvider<T>) that is wired to a concrete implementation through an IoC container or whatever your preference may be.
public abstract Repository<T> {
IValidationProvider<T> _validationProvider;
public ValidationResult Validate( T entity ) {
return _validationProvider.Validate( entity );
}
}
This way you can test your validation separately.
Your repository might look like this:
public ProductRepository : Repository<Product> {
// ...
public RepositoryActionResult Add( Product p ) {
var result = RepositoryResult.Success;
if( Validate( p ) == ValidationResult.Success ) {
// Do add..
return RepositoryActionResult.Success;
}
return RepositoryActionResult.Failure;
}
}
You could go a step further, if you intend on exposing this functionality via an external API, and add a service layer to mediate between the domain objects and the data access. In this case, you move the validation to the service layer and delegate data access to the repository. You may have, IProductService.Add( p ). But this can become a pain to maintain due to all of the thin layers.
My $0.02.
Another way to accomplish this with loose coupling would be to create validator classes for your entity types, and register them in your IoC, like so:
public interface ValidatorFor<EntityType>
{
IEnumerable<IDataErrorInfo> errors { get; }
bool IsValid(EntityType entity);
}
public class ProductValidator : ValidatorFor<Product>
{
List<IDataErrorInfo> _errors;
public IEnumerable<IDataErrorInfo> errors
{
get
{
foreach(IDataErrorInfo error in _errors)
yield return error;
}
}
void AddError(IDataErrorInfo error)
{
_errors.Add(error);
}
public ProductValidator()
{
_errors = new List<IDataErrorInfo>();
}
public bool IsValid(Product entity)
{
// validate that the name is at least 4 characters;
// if so, return true;
// if not, add the error with AddError() and return false
}
}
Now when it comes time to validate, ask your IoC for a ValidatorFor<Product> and call IsValid().
What happens when you need to change the validation logic, though? Well, you can create a new implementation of ValidatorFor<Product>, and register that in your IoC instead of the old one. If you are adding another criterion, however, you can use a decorator:
public class ProductNameMaxLengthValidatorDecorator : ValidatorFor<Person>
{
List<IDataErrorInfo> _errors;
public IEnumerable<IDataErrorInfo> errors
{
get
{
foreach(IDataErrorInfo error in _errors)
yield return error;
}
}
void AddError(IDataErrorInfo error)
{
if(!_errors.Contains(error)) _errors.Add(error);
}
ValidatorFor<Person> _inner;
public ProductNameMaxLengthValidatorDecorator(ValidatorFor<Person> validator)
{
_errors = new List<IDataErrorInfo>();
_inner = validator;
}
bool ExceedsMaxLength()
{
// validate that the name doesn't exceed the max length;
// if it does, return false
}
public bool IsValid(Product entity)
{
var inner_is_valid = _inner.IsValid();
var inner_errors = _inner.errors;
if(inner_errors.Count() > 0)
{
foreach(var error in inner_errors) AddError(error);
}
bool this_is_valid = ExceedsMaxLength();
if(!this_is_valid)
{
// add the appropriate error using AddError()
}
return inner_is_valid && this_is_valid;
}
}
Update your IoC configuration and you now have a minimum and maximum length validation without opening up any classes for modification. You can chain an arbitrary number of decorators in this way.
Alternatively, you can create many ValidatorFor<Product> implementations for the various properties, and then ask the IoC for all such implementations and run them in a loop.
Alright, here is my third answer, because there are so very many ways to skin this cat:
public class Product
{
... // normal Product stuff
IList<Action<string, Predicate<StaffInfoViewModel>>> _validations;
IList<string> _errors; // make sure to initialize
IEnumerable<string> Errors { get; }
public void AddValidation(Predicate<Product> test, string message)
{
_validations.Add(
(message,test) => { if(!test(this)) _errors.Add(message); };
}
public bool IsValid()
{
foreach(var validation in _validations)
{
validation();
}
return _errors.Count() == 0;
}
}
With this implementation, you are able to add an arbitrary number of validators to the object without hardcoding the logic into the domain entity. You really need to be using IoC or at least a basic factory for this to make sense, though.
Usage is like:
var product = new Product();
product.AddValidation(p => p.Name.Length >= 4 && p.Name.Length <=20, "Name must be between 4 and 20 characters.");
product.AddValidation(p => !p.Name.Contains("widget"), "Name must not include the word 'widget'.");
product.AddValidation(p => p.Price < 0, "Price must be nonnegative.");
product.AddValidation(p => p.Price > 1, "This is a dollar store, for crying out loud!");
U can use a other validation system. you can add a method to IService in service layer such as:
IEnumerable<IIssue> Validate(T entity)
{
if(entity.Id == null)
yield return new Issue("error message");
}