星期五, 10月 13, 2023

[DP] 責任鍊

以資料驗證為例子,使用責任鍊 (Chain of Responsibility,簡稱 cor) 來消除 IfElse 的驗證流程

概念示意圖 (第一次畫)
Legacy Code:IfElse
using System;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string data = "AB-20231013";
            bool isValid = false;

            if (data.Length == 11)
            {
                if (data.Substring(0, 2) == "AB")
                {
                    if (data.Substring(2, 1) == "-") ;
                    {
                        string date = data.Substring(3, 8);

                        isValid = DateTime.TryParseExact(
                            date,
                            "yyyyMMdd",
                            System.Globalization.CultureInfo.InvariantCulture,
                            System.Globalization.DateTimeStyles.None,
                            out DateTime result);
                    }
                }
            }

            Console.WriteLine($"驗證結果為 {isValid}");
        }
    }
}
Designe Pattern:責任鍊來消除 IfElse
using System;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string data = "AB-20231013";

            AbstractHandler chain = new 總長度Handler(
                new 前兩碼Hanlde(
                new 符號Handler(
                new 日期Handle(null))));

            bool isValid = chain.HandleRequest(data);
            Console.WriteLine($"驗證結果為 {isValid}");
        }
    }

    public class 日期Handle : AbstractHandler
    {
        public 日期Handle(AbstractHandler successor) : base(successor)
        {
        }

        protected override bool Handle(string request)
        {
            string date = request.Substring(3, 8);

            return DateTime.TryParseExact(
                date,
                "yyyyMMdd",
                System.Globalization.CultureInfo.InvariantCulture,
                System.Globalization.DateTimeStyles.None,
                out DateTime result);
        }
    }

    public class 符號Handler : AbstractHandler
    {
        public 符號Handler(AbstractHandler successor) : base(successor)
        {
        }

        protected override bool Handle(string request)
        {
            return (request.Substring(2, 1) == "-");
        }
    }

    public class 前兩碼Hanlde : AbstractHandler
    {
        public 前兩碼Hanlde(AbstractHandler successor) : base(successor)
        {
        }

        protected override bool Handle(string request)
        {
            return (request.Substring(0, 2) == "AB");
        }
    }

    public class 總長度Handler : AbstractHandler
    {
        public 總長度Handler(AbstractHandler successor) : base(successor)
        {
        }

        protected override bool Handle(string request)
        {
            return (request.Trim().Length == 11);
        }
    }

    public abstract class AbstractHandler
    {
        private AbstractHandler _successor;

        public AbstractHandler(AbstractHandler successor)
        {
            _successor = successor;
        }

        protected abstract bool Handle(string request);

        public bool HandleRequest(string request)
        {
            if (Handle(request) == false)
                return false;

            if (_successor == null)
                return true;

            return _successor.HandleRequest(request);
        }
    }
}

1 則留言:

吉娃娃 提到...

真是厲害 寫得淺顯易懂 感謝大大

張貼留言