Design Pattern Advice: Rule checker
I sell products throgh my website. Recently we've been given a list of rules that need to be checked against each order, to make sure it's not fraudulent. So this list of rules/fraud indicators will change and grow so I want to make sure it's easily maintainable and really solid.
I'm thinking I have an abstract class rule
that each of the rules implements.
abstract class Rule
{
public string Message;
public bool Success;
public void CheckOrder(OrderItem currentOrder);
}
class FakeCreditCardNumberRule : Rule
{
public string Message = "Fake CC Number Rule";
public void CheckOrder(OrderItem currentOrder)
{
currentOrder.CreditCardNumber = "1234-5678-9012-3456";
Success = false;
}
}
class ReallyLargeOrderRule : Rule
{
public string Message = "Really Large Order Rule";
public void CheckOrder(OrderItem currentOrder)
{
currentOrder.ItemsOrder.Count > 100;
Success = false;
}
}
Then I'm thinking of having a class that accepts an Order object
in it's costructor and checks though the list of rules. Something like:
class FraudChecker
{
List<Rule> rules;
public FraudChecker(OrderItem currentOrder)
{
foreach(v开发者_开发百科ar rule in rules)
{
rule.CheckOrder(currentOrder);
}
}
}
So I was trying to think of the best place/best way to populate the FraudChecker .Rules list and started thinking there might be some nice design pattern that does something like what I'm doing.
Has anyone seen a design pattern I should use here? Or can anyone think of a good place to populate this list?
-Evan
Specification Pattern
I've been dealing with a very similar issue.
I've found the Specification Pattern to be particularly useful.
For me the main benefits of the pattern is the way it incorporates chaining.
The link above provides a basic overview, and the related links in the article are useful too. After, if you do some more searching you'll find more detailed examples.
You have already used the Startegy pattern... I believe a factory pattern can solve your problem.
Link
I would probably go with my own implementation of enum. I would create a class like this:
public sealed class Rules
{
public static readonly Rule FakeCreditCardNumberRule = new FakeCreditCardNumberRule ();
public static readonly Rule ReallyLargeOrderRule = new ReallyLargeOrderRule ();
//here I would write more
private static readonly List<Rule> _all = List<Rule> { FakeCreditCardNumberRule, ReallyLargeOrderRule };
//every time you add new rule to the class you have to add it to the _all list also
public static IEnumerable<Rule> All
{
get
{
return _all;
}
}
public static FraudChecker(OrderItem currentOrder)
{
foreach(var rule in All)
{
rule.CheckOrder(currentOrder);
}
}
}
and then you can use it like this:
Rules.FraudChecker(currentOrder);
or
Rules.FakeCreditCardNumberRule.CheckOrder(currentOrder);
You can add every new rule to the Rules class. You can also create new methods in it that will process only part of the Rules and so on.
精彩评论