Necessary solution for validation scenario

I would like to check out some objects. The check has two parts:

  • check whether the user has the right to access the object (specific rights have already been calculated and stored in logical values, there are a maximum of 4 roles)
  • check if an object is in a certain state (from a set of states)

I have many rules (actually about 25 in total), such as those that need to be confirmed:

  • isOwner && & (status == 11 || status == 13 || status == 14)
  • ! (isOwner && isReceiver && status == 12)
  • .....

For me, these rules apply to several methods, 4 or 5 rules in the method. If a rule fails, other rules are not checked. I need to build a validator (or configure an already built) in every method that uses this check.

I am looking for a design template that will make it easier to create a structure for checking objects. My goal is to provide specific error messages. For example, if the check failed, because the user does not have rights, I want to inform him about it. If this happened due to the state of the object, then I want to show that.

First of all, I mean the decorator pattern. I have an error message handler object that can be decorated with specific error messages. One decorator will check user rights, and the other for states. But the order in which I build my validator objects does not matter, so the power of the decorator template is not used. (AFAIK is one big advantage of using a decorator - mixing the scenery). I think the chain might be better for this case ...?!?! What design alternative would you recommend for this scenario?

+5
source share
5 answers

, , , , .

, , . , , ( )?

, , , ..., , .

, , .

, . .

+2

, (isOwner) .

+1

. .

+1

(: ) + (: (.net)).

class Program
    {
        public class StateObject
        {
            public virtual int State { get; set; }
        }

        public abstract class Rule
        {
            public abstract Result Check(StateObject objectToBeChecked);

        }

        public class DefaultAllow : Rule
        {
            public override Result Check(StateObject objectToBeChecked)
            {
                Console.WriteLine("DefaultAllow: allow");
                return Result.Allow;
            }
        }

        public class DefaultDeny : Rule
        {
            public override Result Check(StateObject objectToBeChecked)
            {
                Console.WriteLine("DefaultDeny: deny");
                return Result.Deny;
            }
        }

        public class DefaultState : Rule
        {
            public override Result Check(StateObject objectToBeChecked)
            {
                Console.WriteLine("DefaultState: state: {0}", objectToBeChecked.State);
                return objectToBeChecked.State == 1 ? Result.Allow : Result.Deny;
            }
        }

        public class Strategy
        {

            public virtual IEnumerable<Rule> GetRules()
            {
                return new List<Rule>()
                           {
                               new DefaultAllow(),
                               new DefaultState()
                           };
            }
        }

        public class Validator
        {
            private readonly Strategy _strategy;

            public Validator(Strategy strategy)
            {
                _strategy = strategy;
            }

            public IEnumerable<Result> Process(StateObject objectToBeChecked)
            {
                foreach (Rule rule in _strategy.GetRules())
                    yield return rule.Check(objectToBeChecked);
            }

        }

        public class MyStateMachine
        {
            private readonly Validator _validator;
            private StateObject _stateObject;

            public event EventHandler OnAllow;
            public event EventHandler OnDeny;
            public event EventHandler OnError;

            public MyStateMachine(Validator validator)
            {
                _validator = validator;
            }

            public void Init(StateObject stateObject)
            {
                _stateObject = stateObject;
            }

            protected virtual void Validate()
            {
                Result result = Result.Allow; // default 

                foreach (Result r in _validator.Process(_stateObject))
                {
                    result = r;
                    if (r != Result.Allow)
                        break;
                }

                if (result == Result.Allow)
                    Notify(OnAllow);
                else if (result == Result.Deny)
                    Notify(OnDeny);
                else if (result == Result.Error)
                    Notify(OnError);
                else
                    throw new NotSupportedException();

                Console.WriteLine("Result: {0}", result);
            }


            private void Notify(EventHandler handler)
            {
                if (handler != null)
                    handler.Invoke(_stateObject, EventArgs.Empty);
            }


            public void ChangeState(int prevState, int newState)
            {
                if (prevState != _stateObject.State)
                    throw new InvalidStateException();

                _stateObject.State = newState;

                Validate(); // maybe this,  maybe before assign a new state 
            }
        }

        public class InvalidStateException : Exception { }

        public enum Result { Allow, Deny, Error }


        static void Main(string[] args)
        {
            Strategy defaultStrategy = new Strategy();
            Validator ruleChecker = new Validator(defaultStrategy);
            MyStateMachine stateMachine = new MyStateMachine(ruleChecker);

            StateObject objectToBeChecked = new StateObject();
            stateMachine.Init(objectToBeChecked);

            stateMachine.ChangeState(objectToBeChecked.State, 1);
            stateMachine.ChangeState(objectToBeChecked.State, 2);


            Console.ReadLine();
        }
    }
+1

, , DDD, - Composite Specification , .

0

All Articles