使用属性或方法在C#中公开业务规则?

使用属性或方法在C#中公开业务规则?,c#,properties,methods,C#,Properties,Methods,我正在编写一个类来封装一些业务规则,每个规则都由一个布尔值表示。该类将用于处理InfoPath表单,因此规则通过使用XPath操作在全局XML数据结构中查找值来获取当前程序状态。向调用者公开这些规则的最佳(最惯用的)方法是什么——属性还是公共方法 使用属性调用 Rules rules = new Rules(); if ( rules.ProjectRequiresApproval ) { // get approval } else { // skip approval }

我正在编写一个类来封装一些业务规则,每个规则都由一个布尔值表示。该类将用于处理InfoPath表单,因此规则通过使用XPath操作在全局XML数据结构中查找值来获取当前程序状态。向调用者公开这些规则的最佳(最惯用的)方法是什么——属性还是公共方法

使用属性调用

Rules rules = new Rules();
if ( rules.ProjectRequiresApproval ) {
    // get approval
} else {
    // skip approval
}
Rules rules = new Rules();
if ( rules.ProjectRequiresApproval() ) {
    // get approval
} else {
    // skip approval
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule property
    public bool ProjectRequiresApproval {
        get { return _amount > threshold }
    }
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule method
    public bool ProjectRequiresApproval() {
        return _amount > threshold;
    }
}
使用方法调用

Rules rules = new Rules();
if ( rules.ProjectRequiresApproval ) {
    // get approval
} else {
    // skip approval
}
Rules rules = new Rules();
if ( rules.ProjectRequiresApproval() ) {
    // get approval
} else {
    // skip approval
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule property
    public bool ProjectRequiresApproval {
        get { return _amount > threshold }
    }
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule method
    public bool ProjectRequiresApproval() {
        return _amount > threshold;
    }
}
将规则作为属性公开的规则类

Rules rules = new Rules();
if ( rules.ProjectRequiresApproval ) {
    // get approval
} else {
    // skip approval
}
Rules rules = new Rules();
if ( rules.ProjectRequiresApproval() ) {
    // get approval
} else {
    // skip approval
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule property
    public bool ProjectRequiresApproval {
        get { return _amount > threshold }
    }
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule method
    public bool ProjectRequiresApproval() {
        return _amount > threshold;
    }
}
将规则作为方法公开的规则类

Rules rules = new Rules();
if ( rules.ProjectRequiresApproval ) {
    // get approval
} else {
    // skip approval
}
Rules rules = new Rules();
if ( rules.ProjectRequiresApproval() ) {
    // get approval
} else {
    // skip approval
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

    // rule property
    public bool ProjectRequiresApproval {
        get { return _amount > threshold }
    }
}
public class Rules() {
    private int _amount;
    private int threshold = 100;

    public Rules()  {
        _amount = someExpensiveXpathOperation;
    }

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

一种方法相对于另一种方法的优缺点是什么?

首先,您需要围绕属性逻辑进行分析,经验法则(无论如何,对我来说)应该是,方法可以更改类的内容,或者执行某种业务逻辑,而属性则会公开有关该类的信息

对于您的使用,我建议使用一个属性,因为这些值已经存在,并且您正在创建已知的派生属性

此外,您的代码可以重构为

return _amount < threshold;
return\u amount
根据MSDN的指导原则(对于较旧版本的Visual Studio,这是无可否认的),在您的情况下,方法可能比属性更合适(假设规则比阈值更复杂)

在这个问题上再深入探讨一下,可以发现以下几点:

  • Ken Browning关于一般性质与方法的比较
  • Bill Wagner(《有效C#》一书的作者)关于使用一个属性的条件应该是真的
  • 链接到几个开源规则引擎(和),以便您可以看到实现业务规则的替代方案

    • 这是一个真实的例子吗?我这样问是因为我发现规则对象可能有一个数量和阈值是很奇怪的。我之所以提到这一点,是因为我认为这是答案的一部分。我将把你的规则想象成一个名称空间,把一个项目想象成一个对象,在我看来,它是否需要批准将是项目类的一个属性。

      我同意Antony Koch的观点。当我需要执行更改类状态的复杂计算时,我使用方法。如果类的当前状态需要简单的计算或数据检索,而该状态中的数据已经存在并且不需要更改,则属性似乎更合适

      这一切归结为向使用该业务逻辑的任何人传递语义

      属性是特定对象的内在值<代码>规则
      在您的示例中是一个业务逻辑引擎,因此它公开的任何属性都应该应用于该引擎的状态和行为,而不是应用于它所处理的数据。因此,
      projectrequiresprapproval()
      是引擎应用于外部实体的操作


      另一方面,如果存在
      Rules.GetProcess()
      方法,则该方法将返回
      Process
      对象,
      requiresProval
      可以是该对象上的属性。

      您可能希望在属性定义中放入get{…}。是的,我通常是这样优化的——但是如果我不知道逻辑有多简单,就先用if-else块删除它。在示例中已修复。它接近于一个真实的示例—使用InfoPath非常奇怪,因为表单状态保存在一个大的分层全局XML数据结构中,因此分解它并为每个XML块编写类似Project的类需要相当多的工作。我正在将按钮处理程序中的逻辑测试提取到一个单独的规则类中。我必须看看是否值得为表单中的每个概念编写类;此时,我只想将规则移出GUI!无论哪种方式,你暗示你会从一个属性得到答案…有趣的。。。在这种情况下,你是唯一推荐方法的人。我一直在等待其他人是否同意,但到目前为止的共识似乎是属性更合适。Franci在方法上同意你的观点,我想我也同意——这个类正在评估其他类中的数据,并返回其评估结果。这是一个动作,而不是rules类本身某些属性的反映。目前正在使用方法。顺便说一句,谢谢你的链接!谢谢——这就像亚伦的回答,但有一些更详细的理由。我只是重读了一遍,现在我不太清楚你的建议。您是说,由于规则引擎处理外部对象以确定是否满足规则,因此结果应该通过引擎的方法公开吗?引擎的属性不应该回答是否满足规则,而应该回答引擎本身的一些方面,比如它有多少个规则,或者引擎是否启用等等?是的,这正是我的意思。