Search the web
Sign In
New User? Sign Up
domaindrivendesign · Domain-Driven Design
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Show off your group to the world. Share a photo of your group with us.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
To throw or not to throw on Rule Violation   Message List  
Reply | Forward Message #5557 of 16097 |
I have a question regarding business logic validation in my domain. Im not talking about validation in the sense of simple data validation such as checking for null values or specific data ranges.  These days it seems like most people are handling these types of validations with a validation framework and checking an IsValid operation or something similar.  I refer to these as data validations.  It may be fine in some domains for an object to exist and be persisted when that object is in an invalid data state.  I am faced with an issue in which I cannot allow certain objects to ever be in an invalid state. 
 
In my domain I have PromoCode and Account. PromoCodes can be redeemed by accounts, but there are rules regarding redemption.  If any of these rules are violated, redemption cannot succeed and the application must prevent the redemption.  These rule violations are not fatal and are to be expected, however I must notify the user as to why the redemption did not succeed.  So my question is, what is the preferred way of communicating business rule violations to the UI when an action cannot be performed because it would put the object into an invalid state that cannot be persisted?
 
I think there are essentialy 4 ways:
1) Throw an exception describing the first violation
2) Use Notification pattern to communicate information about all violations.
3) Throw an exception that encapsulates the Notification object as described in Sergio's blog post, A Notification Strategy for Business Errors
4) Provide a Check operation which returns a a boolean or a Notification object such as Notification CanRedeem(Account); or bool CanRedeem(Account);  If the check operation returns any violations, Redeem would throw an exception.
 
The thought of throwing exceptions doesn't sit real well with me but it is the easiest way to get the information to any interested parties because they just have to try...catch it.  The Notification pattern has value but it seems more difficult to get the information to the interested parties.  Granted, the Redeem operation on PromoCode is a void operation and I could just return a Notification object from that call. However, in my research for this problem Im trying to comeup with a solution that would also work with operations that had a return value.  #4 is an instersting option but im a little turned off by it because the check would have to be called multiple times, once from the client and once from the redeem operation.  Here is a sample
 
public class PromoCode{
 
    string code;
    DateTime expirationDate;
    bool isRedeemed;
    bool isOnlyForNewAccounts; 
   
    public Notification CanRedeem(Account account){
        Notification violations = new Notification();
       
        if(this.isRedeemed){
            violations.Add(PromoCodeViolation.AlreadyRedeemed);       
        }
 
        if(this.expirationDate > DateTime.Now){
            violations.Add(PromoCodeViolation.Expired);
        }
 
        if(this.isOnlyForNewAccounts && account.IsNewAccount == false){
           violations.Add(PromoCodeViolation.NewAccountsOnly);
        }
       
        return violations;
    }
   
    public void Redeem(Account account){
        Notification violations = this.CanRedeem(account);
       
        if(violations.HasErrors){
            throw new BusinessRuleException(violations);
        }
 
        this.DoRedeem(account);
    } 
   
    protected void DoRedeem(Account account){
        ...
    }
}
 
 
public class PromoCodeTest{
 
    public void RunCanRedeem(){
       
        Account testAccount = Mock.GetMock<Account>();
       
        PromoCode code = CreateValidPromoCode();
 
        if(code.CanRedeem(testAccount).HasErrors == false){
            code.Redeem(testAccount);
 
            Assert.IsTrue(code.IsRedeemed);
        }
    }
}
 
 
 
Any thoughts or advice on this?  Any ways to improve it?  Or is the a better strategy that I havent seen?
 
Thanks,
Jesse
 
 


Thu Jun 28, 2007 1:41 am

juice_johnson17
Online Now Online Now
Send Email Send Email

Forward
Message #5557 of 16097 |
Expand Messages Author Sort by Date

I have a question regarding business logic validation in my domain. Im not talking about validation in the sense of simple data validation such as checking for...
Jesse Napier
juice_johnson17
Online Now Send Email
Jun 28, 2007
1:41 am

My recommendation is to not consider such scenarios as exceptions but treat them as regular business scenarios instead, with their own flow and page output. So...
berthooyman
Offline Send Email
Jun 28, 2007
7:43 am

... 2) Use Notification pattern<http://www.martinfowler.com/eaaDev/Notification.html>to communicate information about all violations. ... Hi Jesse, and all DDD...
Sergio Bossa
sergio_bossa
Offline Send Email
Jun 28, 2007
8:41 am

Sergio, I didnt really think that wraping the notifications in an exception was the point of your post. I just pointed people there to show one of the ways...
Jesse Napier
juice_johnson17
Online Now Send Email
Jun 28, 2007
7:08 pm

I wrote a rather complex validation system for end-user application. I'll take a moment to describe it because the solution I built may help you. We had three...
Patrick Bohan
ARKBAN
Offline Send Email
Jun 28, 2007
12:06 pm

It seems to me that there are quite a bit of redundant work going on with your design. First, I'd agree with the general notion (from many posts) that throwing...
Jiho Han
jihohan
Offline Send Email
Jun 28, 2007
1:31 pm

... I agree there was redundancy; it was intentional. Redundancy is good in many situations, i.e. RAID. It simply needs to be managed well. ... I agree expense...
ARKBAN
Offline Send Email
Jun 28, 2007
2:02 pm

Count me as vote number two for not using Exceptions to capture what sounds like real business concepts. I like the idea of creating a class, whether vague...
Joe A. Reddy
joethebigshmoe
Offline Send Email
Jun 28, 2007
1:45 pm

Call me old fashioned, but I prefer simply throwing a checked exception. The exception then becomes part of the method signature, which makes for a more...
Jeff Lowe
jefflowe7
Offline Send Email
Jun 28, 2007
1:52 pm

I think the concern revolves around the mantra "exceptions are for exceptional situations". Validation is most often not exceptional but expected; validation...
ARKBAN
Offline Send Email
Jun 28, 2007
2:12 pm

That's a cute mantra. "exceptional situation" is certainly subjective. As Jesse stated, there's a difference between simple data validation, and the violation...
Jeff Lowe
jefflowe7
Offline Send Email
Jun 28, 2007
3:15 pm

Highly recommended for those who haven't read: Effective Java Exceptions. Especially useful here are the distinctions the author draws between 'Contingency'...
cbeams
cbeams78
Offline Send Email
Jun 28, 2007
3:31 pm

Its so true that exceptional situations are very subjective. I've found myself battling with that all the time. In my case, it seems like an exceptional...
Jesse Napier
juice_johnson17
Online Now Send Email
Jun 28, 2007
7:42 pm

I like it. It makes it clear to anyone and everyone that when PromoCodes are redeemed they need to deal with Violations. This code would be hard to misuse. ......
Joe A. Reddy
joethebigshmoe
Offline Send Email
Jun 28, 2007
8:22 pm

How are they forced to deal with violations in these code examples? In the first I could just not register a listener/event handler, and in the second I could...
ARKBAN
Offline Send Email
Jun 28, 2007
8:30 pm

In C# when I type myPromo.Redeem( the IDE will tell me I will be passing into two arguments. One is an Account passed by value and the other is Violations...
Joe A. Reddy
joethebigshmoe
Offline Send Email
Jun 28, 2007
8:38 pm

I think you want "out" there not ref Joe (you method is taking control of the instantiation). INotificationCollection Notifications = null; //? ...
Greg Young
gumboismadeo...
Offline Send Email
Jun 28, 2007
10:22 pm

<< I think you want "out" there not ref Joe (you method is taking control of the instantiation).>> Yep, that's what I said..." Violations passed by reference...
Joe A. Reddy
joethebigshmoe
Offline Send Email
Jun 29, 2007
2:11 pm

With a method you are right this does work very well. Not to go off on a tangent but I think that's one of the pitfalls of C# Properties, they don't lend...
ARKBAN
Offline Send Email
Jun 29, 2007
1:04 am

Arkban, That's a good point, this style wouldn't work very well for properties. Usually setting a property doesn't trigger a state change, so we would be fine...
Jesse Napier
juice_johnson17
Online Now Send Email
Jun 29, 2007
1:26 am

Arkban, its true, the client may not do anything with the violations. That doesnt change the fact that the PromoCode still did not get redeemed. If the client...
Jesse Napier
juice_johnson17
Online Now Send Email
Jun 28, 2007
8:58 pm

Personally, treating contingency business cases as checked exceptions makes a ton of sense. That is the argument put forward, quite effectively in my opinion,...
Louis Richer
louisricher
Offline Send Email
Jun 28, 2007
8:44 pm

I tend to agree with Jeff. I'm very concerned about keeping an object in a valid state....
Chris Gardner
chris_gardner76
Offline Send Email
Jun 28, 2007
5:07 pm

How did we jump from debating using a specific domain object to objects going into an invalid state? I must have missed something. public redeem(Account...
Joe A. Reddy
joethebigshmoe
Offline Send Email
Jun 28, 2007
5:12 pm

What about languages that don't support checked exceptions? e.g., C#, Ruby I'm used to being able to declare the exceptions that a method will throw as part of...
saad rehmani
saadrehmani
Offline Send Email
Jun 28, 2007
8:37 pm

Personally, treating contingency business cases as checked exceptions makes a ton of sense. That is the argument put forward, quite effectively in my opinion,...
Louis Richer
louisricher
Offline Send Email
Jun 28, 2007
8:38 pm
Advanced

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help