c# 运用策略模式与模板方法模式实例

策略模式

策略模式的核心在于定义一系列算法,把它们封装起来,并且让它们能够相互替换。策略模式让算法的变化独立于使用算法的客户端。在这个方法里,策略模式的体现如下:

  • convertFunc 参数 :这是一个委托类型的参数,其类型为 Func<BaseResponse, TResponse>。它代表一种转换策略,也就是把 BaseResponse 类型的对象转换成 TResponse 类型的对象。不同的转换逻辑可以通过传入不同的 convertFunc 来实现。
  • isValidFunc 参数 :同样是委托类型,类型为 Func<TResponse, bool>。它代表一种验证策略,用来判断转换后的 TResponse 对象是否有效。不同的验证逻辑可以通过传入不同的 isValidFunc 来实现。

模板方法模式

模板方法模式定义了一个操作中的算法骨架,把一些步骤的实现延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。在这个方法里,模板方法模式的体现如下:

  • 方法的整体逻辑ProcessResult 方法定义了处理结果的整体流程,像是转换响应对象、验证响应对象、更新总体结果等步骤。这些步骤的顺序和基本逻辑是固定的,相当于模板方法模式中的算法骨架。
  • 可变部分交给委托 :而具体的转换和验证逻辑则通过 convertFuncisValidFunc 这两个委托来实现,这类似于模板方法模式中把某些特定步骤的实现延迟到子类中。

代码示例解释

以下是一个简化的代码示例,展示了如何创建 ProcessResult 方法:

cs 复制代码
public class ResultProcessor
{
        private readonly GjpClient _gjpClient;
        //GjpClient 这是请求数据库的接口 为了日志使用可不要
        public ResultProcessor(GjpClient gjpClient)
        {
            _gjpClient = gjpClient;
        } 
        public bool ProcessResult<TResponse>(BaseResponse baseResponse, string operationName, string itemName,
       Func<BaseResponse, TResponse> convertFunc, Func<TResponse, bool> isValidFunc,
       out TResponse response, ref bool overallResult)
       where TResponse : new()
        {
            response = new TResponse();

            if (baseResponse == null)
            {
                LogError(operationName, itemName, "baseResponse为空!", ref overallResult);
                return false;
            }

             if (baseResponse.status.ToLower() != "success")
            {
                LogError(operationName, itemName, "失败信息:" + string.Join(",", baseResponse.messages), ref overallResult);
                return false;
            }

             response = convertFunc(baseResponse);

            if (!isValidFunc(response))
            {
                LogError(operationName, itemName, "响应对象为空或关键信息无效!", ref overallResult);
                return false;
            }

             LogSuccess(operationName, itemName, ref overallResult);
            return true;
        }

        private void LogError(string operationName, string itemName, string errorMessage, ref bool overallResult)
        {
            _gjpClient.AddLog(TurnLog(operationName, "【" + itemName + "】" + operationName + "失败: " + errorMessage, false, "-1", itemName));
            overallResult = false;
        }

        private void LogSuccess(string operationName, string itemName, ref bool overallResult)
        {
            _gjpClient.AddLog(TurnLog(operationName, "【" + itemName + "】" + operationName + "成功!", true, "0", itemName));
        }

         private Log TurnLog(string Operation, string Message, bool Success, string Code, string UserCode)
        {
            Log log = new Log();
            log.RequestTime = DateTime.Now;
            log.Operation = Operation;
            log.Message = Message;
            log.Success = Success;
            log.Code = Code;
            log.UserCode = UserCode;
            return log;
        }
}

使用示例解释

以下是一个简化的代码示例,展示了如何使用 ProcessResult 方法:

cs 复制代码
class Program
{
    static void Main()
    {
        ResultProcessor processor = new ResultProcessor();
        //一般为基类
        BaseResponse baseResponse = new BaseResponse();
        bool overallResult = false;

        CustomResponse customResponse;
        //OperationName和ItemName可不需要 因为后续是记录日志使用 不需要日志可忽略这两个参数
        bool result = processor.ProcessResult(
            baseResponse,
            "OperationName",//方法名 比如上传商品
            "ItemName",    //编号 比如商品编号 
            br => br.data as CustomResponse ,//BaseResponse中的data转类型 不同方法中可转不同类型
            ir => ir != null && ir.id > 0,//customResponse需要判断的逻辑 比如不为空和ID>0
            out customResponse,//输出结果 后续可以使用
            ref overallResult);//输出是否成功

        Console.WriteLine($"Result: {result}, Overall Result: {overallResult}");
    }
}

public class BaseResponse
    {
        /// <summary>
        /// 是否正确处理请求,返回success或error,不区分大小写
        /// </summary>
        public string status { get; set; }

        /// <summary>
        /// 处理结果的消息
        /// </summary>
        public List<string> messages { get; set; }

        /// <summary>
        /// 业务处理的错误代码,参见错误代码表
        /// </summary>
        public int errorCode { get; set; }

        /// <summary>
        /// 实体信息
        /// </summary>
        public object data { get; set; }
    }

public class CustomResponse 
    {
        /// <summary>
        /// id
        /// </summary>
        public int id{ get; set; }
    }

在这个示例中,convertFuncBaseResponse 转换为 CustomResponseisValidFunc 验证 CustomResponse 是否有效。ProcessResult 方法定义了处理的整体流程,而具体的转换和验证逻辑则通过委托传入。

综上所述,ProcessResult 方法结合了策略模式和模板方法模式的思想,提高了代码的灵活性和可维护性。

相关推荐
★YUI★5 小时前
学习游戏制作记录(玩家掉落系统,删除物品功能和独特物品)8.17
java·学习·游戏·unity·c#
克拉克盖博6 小时前
chapter03_Bean的实例化与策略模式
java·spring·策略模式
谷宇.6 小时前
【Unity3D实例-功能-拔枪】角色拔枪(二)分割上身和下身
游戏·unity·c#·游戏程序·unity3d·游戏开发·游戏编程
LZQqqqqo6 小时前
C# 中 ArrayList动态数组、List<T>列表与 Dictionary<T Key, T Value>字典的深度对比
windows·c#·list
Dm_dotnet9 小时前
Stylet启动机制详解:从Bootstrap到View显示
c#
三千道应用题11 小时前
WPF&C#超市管理系统(6)订单详情、顾客注册、商品销售排行查询和库存提示、LiveChat报表
开发语言·c#·wpf
唐青枫15 小时前
别滥用 Task.Run:C# 异步并发实操指南
c#·.net
我好喜欢你~1 天前
C#---StopWatch类
开发语言·c#
一阵没来由的风1 天前
拒绝造轮子(C#篇)ZLG CAN卡驱动封装应用
c#·can·封装·zlg·基础封装·轮子
一枚小小程序员哈1 天前
基于微信小程序的家教服务平台的设计与实现/基于asp.net/c#的家教服务平台/基于asp.net/c#的家教管理系统
后端·c#·asp.net