2010-03-11 18 views
10

Escribo una clase para encapsular algunas reglas de negocio, cada una de las cuales está representada por un valor booleano. La clase se usará para procesar un formulario de InfoPath, de modo que las reglas obtengan el estado actual del programa al buscar valores en una estructura de datos XML global utilizando las operaciones de XPath. ¿Cuál es la mejor forma (más idiomática) de exponer estas reglas a las personas que llaman: propiedades o métodos públicos?¿Utiliza propiedades o métodos para exponer reglas comerciales en C#?

llamada utilizando propiedades

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

llamada utilizando métodos clase

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

Reglas exponer reglas como propiedades

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

    public Rules() { 
     _amount = someExpensiveXpathOperation; 
    } 

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

reglas de clase exponiendo reglas que los métodos

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

    public Rules() { 
     _amount = someExpensiveXpathOperation; 
    } 

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

¿Cuáles son los pros y los contras de uno sobre el otro?

+0

Probablemente quiera poner get {...} en la definición de su propiedad. –

+0

d'oh, sí, arreglado – Val

Respuesta

2

Todo se reduce a transmitir semántica a quien consume esa lógica comercial.

Una propiedad es un valor intrínseco de un objeto en particular. Rules en su ejemplo es un motor de lógica de negocios, por lo que cualquier propiedad que exponga debe aplicarse al estado y comportamiento de ese motor, no a los datos que procesó. Como tal, ProjectRequiresApproval() es una acción que el motor aplica a una entidad externa.

Si por el contrario, no había Rules.GetProcess() método, que devolvería un objeto Process, RequiresAproval puede ser propiedad de ese objeto.

+0

Gracias - esta es como la respuesta de Aaron, pero con una razón más detallada. – Val

+0

Acabo de volver a leer esto, y ahora no estoy exactamente claro qué estás sugiriendo. ¿Está diciendo que, dado que el motor de reglas procesa objetos externos para determinar si se ha cumplido o no una regla, los resultados deben exponerse a través de un método del motor? Y que las propiedades del motor no deberían responder si se ha cumplido una regla, sino solo aspectos del propio motor, como cuántas reglas tiene, si el motor está habilitado o no, etc. – Val

+0

Sí, eso es exactamente lo que quiero decir. –

3

En primer lugar, tendría que ajustar get {} alrededor de la lógica de la propiedad, y la regla general (para mí, de todos modos) debería ser que un método puede cambiar el contenido de una clase o realizar algún tipo de lógica empresarial , mientras que una propiedad expone información sobre la clase.

Para su uso, sugeriría una propiedad ya que los valores ya existen y está creando lo que se conoce como una propiedad derivada.

Además, el código se puede refactorizar a

return _amount < threshold; 
+0

Sí, generalmente optimizo de esta manera, pero corto la lógica usando un bloque if-else primero si no sé qué tan simple será. Reparado en el ejemplo. – Val

2

De acuerdo con los Properties vs. Methods directrices en MSDN (la verdad para una versión anterior de Visual Studio), suena como métodos podrían ser más apropiados que las propiedades en su caso (suponiendo que las reglas se vuelven más complejas que los umbrales).

un poco más a hurgar en esta cuestión reveló lo siguiente:

  • Un excellent answer de Ken Browning en las propiedades frente a los métodos en general
  • Un blog post de Bill Wagner (autor de efectivo de C#) en lo las condiciones deben ser verdaderas para usar una propiedad
  • Enlaces a un par de motores de reglas de código abierto (NxBRE y Drools.NET) para que pueda ver alternativas para implementar reglas comerciales.
+0

Interesante ... usted es el único que recomienda métodos en este caso. Estaba esperando ver si alguien más estuvo de acuerdo, pero hasta ahora el consenso parece ser que las propiedades son más apropiadas. – Val

+0

Franci está de acuerdo con usted en los métodos, y creo que lo compro: la clase evalúa los datos de otras clases y devuelve los resultados de su evaluación. Eso es una acción, no un reflejo de algún atributo de la clase de reglas en sí misma. Yendo con métodos por ahora. Por cierto, gracias por los enlaces! – Val

+0

@ Val, de nada. ¡Encantado de ayudar! –

1

¿Es eso un verdadero ejemplo? Lo pregunto porque me parece extraño que un objeto Rules tenga una cantidad y un umbral. Menciono esto porque creo que es parte de la respuesta. Me imagino que sus Reglas para ser un espacio de nombres y un Proyecto para ser un objeto, y si es o no que requiere aprobación sería una propiedad de la clase Proyecto, en mi opinión.

+0

Está cerca de ser un ejemplo real --- trabajar con InfoPath es bastante extraño, ya que el estado de forma se mantiene en una gran estructura de datos XML global jerárquica, por lo que es bastante trabajo descomponerlo y escribir clases como Project para cada fragmento del XML. Estoy en el proceso de extraer pruebas lógicas en manejadores de botón en una clase de reglas separada. Tendré que ver si vale la pena el esfuerzo de escribir clases para cada concepto en el formulario; en este punto, ¡solo quiero sacar las reglas de la GUI! De cualquier manera, implica que obtendría la respuesta de una propiedad ... – Val

2

Estoy de acuerdo con Antony Koch. Utilizo métodos cuando necesito realizar un cálculo complejo que cambia el estado de la clase.Si se necesita un cálculo simple o recuperación de datos para el estado actual de la clase donde los datos ya existen en ese estado y no es necesario cambiarlos, una propiedad parece más adecuada.

Cuestiones relacionadas