I had old enum
, I converted it to Enumeration class and added one method inside (isValid
). I am not sure if it is good approach to add such small business logic into Enumeration class. I would like to understand if this is a good approach or not.
Here is old enum
:
internal enum Rule
{
None = 0,
CompensationIsZero = 1,
CompensationLessThanDemand = 2,
CompensationBetweenZeroAndDemand = 3,
CompensationEqualsDemand = 4,
CompensationLessOrEqualsDemand = 5
}
Here it is rewritten to Enumeration
class and IsValid
method is added.
public class Rule : Enumeration
{
public static readonly Rule None = new Rule (0, "None");
public static readonly Rule CompensationIsZero = new Rule (1, "CompensationIsZero ");
public static readonly Rule CompensationLessThanDemand = new Rule(2, "CompensationLessThanDemand ");
....
// there are about 5 rules
public Rule(int id, string name)
: base(id, name)
{ }
public bool IsValid(decimal compensation, decimal demand, int rule) {
if (rule == Rule.None.Id) return true;
if (rule == Rule.CompensationIsZero.Id) then return compensation == 0;
if (rule == Rule.CompensationLessThanDemand .Id) then return compensation < demand;
...
}
}
Enumeration
class implementation version is very similar like in this article (https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types)
Thus I have values compensation
and demand
(these come from UI).
And I have some type based on which I get Rule value from database.
And so I call method IsValid (compensation, demand, ruleIdFromDb)
. If it is not validated then I show error on UI.
1 Answer 1
Shouldn't the 'IsValid' method be static? I suppose you use it like Rule.IsValid(calculatedCompensation, 0, Rule.CompensationIsZero.Id)
, (as general idea, obviously it can be simplified).
Anyway PERSONALLY I would not do this, because Rule
is no more an Enum
, you gave it logic, that usually Enum
don't have. I would have keep the Enum
as original and built on top of that a Class
with the required logic. (Maybe called RuleValidator
with a static method public static bool IsValid(Rule rule, decimal compensation, decimal demand) {...}
.
If this does not concern you, than another way could be to write an extension method:
static class RuleExtensions
{
public static bool Validate(this Rule rule, decimal compensation, decimal demand)
{
switch (rule)
{
case None: return true;
case CompensationIsZero: return compensation == 0;
case CompensationLessThanDemand : return compensation < demand;
// ecc...
}
}
}
-
\$\begingroup\$ Your comment make sense. \$\endgroup\$renathy– renathy2020年05月06日 07:55:09 +00:00Commented May 6, 2020 at 7:55
-
\$\begingroup\$ can I ask one more question, what if I would like to have different error messages based on which Case failed. Should I add static property ErrorMessage or should error message be returned from Validate? \$\endgroup\$renathy– renathy2020年05月06日 08:44:15 +00:00Commented May 6, 2020 at 8:44
-
\$\begingroup\$ I can't think a super elegant solution, I'm still junior. But I would go for something like
public static bool Validate (this Rule rule, decimal compensation, decimal demand, out string errorMessage) {...}
. Usage:if (!Rule.None.Validate.(10, 0, out var error)) Console.WriteLine(error);
. InsideValidate
then, before returning false, you would seterrorMessage
with a string retrieved form some kind of external resource (like the .resx files, or a DB). This because you could need the message to change (like for localization). \$\endgroup\$Federico Rossi– Federico Rossi2020年05月07日 06:17:06 +00:00Commented May 7, 2020 at 6:17