验证中的原则 DRY?

Principle DRY in validation?

我使用工具箱菜单中的标准 DataGridView。

我通过事件 cellEditEnd 验证 DataGridView 中的每个单元格。它看起来像这样:

private void dataGrid_CellEditEnding(object sender,DataGridCellEditEndingEventArgs e)
{
     // Below I demonstrate pseudo code for brevity

     if(cell.name.value is not Number){
         print "Wrong cell value";
     }
}

因此,在另一种形式 (WinForms) 中,我具有从 Excel 文件导入数据并将其显示在 DataGridView 中的功能。

我需要在插入每个单元格之前验证 Excel 数据。为此,我可以使用事件 CellValidation。但我不想重复我在 dataGrid_CellEditEnding 方法中使用的相同代码。

如何避免重复代码?

如何创建一个静态 ValidationHelper class,其中包含所有验证方法,然后在需要时调用它们。

public static class ValidationHelper
{
  public static void ValidateIsNumeric(string value)
  {
    if(value is not Number){
      print "Wrong cell value";
    }
  }
}

你可以这样调用:

private void dataGrid_CellEditEnding(object sender,DataGridCellEditEndingEventArgs e)
{
   ValidationHelper.ValidateIsNumeric(cell.name.value);
}

您可以查看责任链设计模式,您的代码将是可配置的并且更面向对象,看起来像这样:

    public interface IHandler
    {
        void Handle(string value);
    }

    public abstract class CellRequestTemplate : IHandler
    {
        protected readonly IHandler _next;
        protected CellRequestTemplate(IHandler next)
        {
            _next = next ?? throw new ArgumentNullException(nameof(next));
        }

        public abstract void Handle(string value);
    }

    public sealed class FirtsRuleForCell : CellRequestTemplate
    {
        public FirtsRuleForCell(IHandler next) : base(value, next) { }
        public override void Handle(string value)
        {
            if(value is number)
            {
                _next.Handle(value);
            }
            else
            {
                //print "Wrong cell value";
            }
        }
    }

    public sealed class SecondRuleForCell : CellRequestTemplate
    {
        public SecondRuleForCell(IHandler next) : base(value, next) { }
        public override void Handle(string value)
        {
            //if some validation
            //do something
            //else 
            //
            _next.Handle(value);

        }
    }

    public sealed class EndOfChain : IHandler
    {
        public void Handle(string value)
        {
            throw new InvalidOperationException("End of Chaing, cant handle");
        }
    }

    public interface IHandleCellFactory
    {
        IHandler CreateHandler();
    }

    public sealed class Form1GridHandler : IHandleCellFactory
    {
        public IHandler CreateHandler()
        {
            return new FirtsRuleForCell(new SecondRuleForCell(new EndOfChain()));
        }
    }

    public sealed class Form2GridHandler : IHandleCellFactory
    {
        public IHandler CreateHandler()
        {
            return new SecondRuleForCell(new EndOfChain());
        }
    }


    public abstract class ClientCode
    {
        private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
            // Below I demonstrate pseudo code for brevity
            var valueToHandle = string.Empty; //cell.name.value;
            var handler = new Form1GridHandler().CreateHandler();
            handler.Handle(valueToHandle);
            //continue with Execution code
        }
    }

有关设计模式的更多信息,look at this link as reference。 希望这对您有所帮助,问候!