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?
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.
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;
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.
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.
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.
精彩评论