views:

167

answers:

6

I'm writing a class to encapsulate some business rules, each of which is represented by a boolean value. The class will be used in processing an InfoPath form, so the rules get the current program state by looking up values in a global XML data structure using XPath operations. What's the best (most idiomatic) way to expose these rules to callers -- properties or public methods?

Call using properties

Rules rules = new Rules();
if ( rules.ProjectRequiresApproval ) {
    // get approval
} else {
    // skip approval
}

Call using methods

Rules rules = new Rules();
if ( rules.ProjectRequiresApproval() ) {
    // get approval
} else {
    // skip approval
}

Rules class exposing rules as properties

public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule property
    public bool ProjectRequiresApproval {
        get { return _amount > threshold }
    }
}

Rules class exposing rules as methods

public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule method
    public bool ProjectRequiresApproval() {
        return _amount > threshold;
    }
}

What are the pros and cons of one over the other?

+3  A: 

Firstly, you would need to wrap get{} around the property logic, and the rule of thumb (for me, anyway) should be that a method can change the content of a class, or performs some kind of business logic, whereas a property exposes information about the class.

For your usage, I would suggest a property as the values already exist and you are creating what is knowns as a derived property.

Also, your code can be refactored to

return _amount < threshold;
Antony Koch
yep, I usually optimize like this -- but stub out the logic using an if-else block first if I don't know how simple it will be. Fixed in the example.
Val
A: 

ProjectRequiresApproval sounds like a property name.

If these rules are evaluated on startup you could make them satic and evaluate them in a static constructor of a static Rules class.

Al Bundy
+2  A: 

According to the Properties vs. Methods guidelines on MSDN (admittedly for an older version of Visual Studio), it sounds like methods might be more appropriate than properties in your case (assuming the rules get more complex than thresholds).

A bit more poking around on this question revealed the following:

  • An excellent answer from Ken Browning on properties vs. methods in general
  • A blog post from Bill Wagner (author of Effective C#) on what conditions should be true in order to use a property
  • Links to a couple of open-source rules engines (NxBRE and Drools.NET) so you can see alternatives for implementing business rules.
Scott A. Lawrence
Interesting... you're the only one recommending methods in this case. I was waiting to see if anyone else agreed, but the consensus so far seems to be that properties are more appropriate.
Val
Franci agrees with you on methods, and I think i buy it -- the class is evaluating data held in other classes, and returning the results of its evaluation. That's an action, not a reflection of some attribute of the rules class itself. Going with methods for now. BTW, thanks for the links!
Val
@Val, you're welcome. Glad to help!
Scott A. Lawrence
+1  A: 

Is that a real example? I ask because I find it bizarre that a Rules object might have an amount and a threshold. I'm mentioning this because I think it's part of the answer. I would imagine your Rules to be a namespace and a Project to be an object, and whether or not it requires approval would be a property of the Project class in my opinion.

Bernhard Hofmann
It's close to a real example --- working with InfoPath is pretty bizarre, as form state is held in a big hierarchical global XML data structure, so it's quite a bit of work to break that down and write classes like Project for each chunk of the XML. I'm in the process of extracting logical tests in button handlers into a separate Rules class. I'll have to see if it's worth the effort to write classes for each concept in the form; at this point, I just want to move the rules out of the GUI! Either way, you imply you'd get the answer from a property...
Val
+2  A: 

I agree with Antony Koch. I use methods when I need to perform a complex calculation that changes the state of the class. If a simple calculation or data retrieval is needed for the current state of the class where the data already exists in that state and does not need to be changed, a property seems more suitable.

Aaron Hawkins
+2  A: 

It all boils down to conveying semantic to whoever consumes that business logic.

A property is an intrinsic value of a particular object. Rules in your example is a business logic engine, so any properties it exposes should apply to the state and behavior of that engine, not to the data that was processed by it. As such, ProjectRequiresApproval() is an action that the engine applies to an external entity.

If on the other hand, there was Rules.GetProcess() method, that would return a Process object, RequiresAproval can be property on that object.

Franci Penov
Thanks -- this is like Aaron's answer, but with some more detailed rationale.
Val
I just re-read this, and now I'm not exactly clear what you're suggesting. Are you saying that since the rules engine processes external objects to determine if a rule has been met or not, the results should be exposed through a method of the engine? And that the properties of the engine should not answer whether a rule has been met, but only aspects of the engine itself, like how many rules it has, or whether the engine is enabled or not, etc.?
Val
Yes, that is exactly what I mean.
Franci Penov