1. 引言
本文以珠宝企业完整业务流水线为背景,深入讲解策略模式(Strategy Pattern)这一行为型设计模式的核心思想、结构组成与实战落地方式。通过领域驱动设计(DDD)分层、仓储模式、工作单元以及熔断重试机制的综合运用,展示策略模式在真实业务场景中的价值。
2. 策略模式概述
策略模式属于行为型设计模式,它定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端,从而提升系统的可扩展性与可维护性。
3. 项目结构
本节展示基于 .NET 10 与 C# 实现的珠宝企业业务流水线项目整体结构,包括领域层、应用层、基础设施层与表现层的分层划分,以及各层之间的依赖关系。
4. 领域层核心实体
领域层承载业务核心逻辑,本节介绍业务流程流转记录、珠宝原料、珠宝成品等核心实体的设计与实现,重点说明工厂方法、私有构造函数与业务行为封装等 DDD 实践要点。
5. 枚举与值对象设计
本节讲解业务流程状态、珠宝原料品质等级等枚举定义,以及金额等值对象的设计思路,展示如何通过强类型约束保证业务数据的正确性与一致性。
6. 仓储接口与工作单元
本节定义业务流程流水记录仓储、珠宝原料仓储等接口,以及工作单元接口,体现领域层只依赖抽象、不依赖具体实现的依赖倒置原则。
7. 策略模式在业务流水线中的落地
本节是文章核心,详细讲解如何将策略模式应用于珠宝业务流水线的各个环节,包括策略接口定义、具体策略实现、策略上下文与策略工厂的协作方式,以及如何通过依赖注入实现策略的动态选择与替换。
8. 熔断器与重试机制
本节介绍熔断器加指数退避重试执行器的设计与实现,展示在策略执行过程中如何通过熔断机制提升系统容错能力,保障业务流水线的稳定性与可靠性。
9. 内存仓储与工作单元实现
本节给出基于内存的仓储与工作单元实现,展示并发安全的数据存储方案,并说明生产环境中如何替换为 EF Core 或 Dapper 等真实数据库实现。
10. 调用示例与输出
本节通过完整的调用示例演示珠宝业务流水线的执行过程,展示策略模式与熔断机制协同工作的实际效果,并给出运行输出结果。
11. 总结
本文从理论到实践完整呈现了策略模式在珠宝企业业务流水线中的应用。通过领域驱动设计、仓储模式、工作单元与熔断重试机制的综合运用,构建了一个高内聚、低耦合、易扩展的业务系统。希望读者能够举一反三,将策略模式灵活运用于自身项目中。
项目结构:

cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessFlowRecord.cs
*/
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Entities
{
/// <summary>
/// 业务流程流转记录实体,记录每一步业务策略执行流水
/// </summary>
public class BusinessFlowRecord
{
/// <summary>
/// 流水记录主键
/// </summary>
public long RecordId { get; private set; }
/// <summary>
/// 外部业务唯一ID
/// </summary>
public long BusinessId { get; private set; }
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName { get; private set; } = string.Empty;
/// <summary>
/// 流程状态
/// </summary>
public BusinessFlowStatus FlowStatus { get; private set; }
/// <summary>
/// 返回消息
/// </summary>
public string Message { get; private set; } = string.Empty;
/// <summary>
/// 错误码
/// </summary>
public int ErrorCode { get; private set; }
/// <summary>
/// 操作人信息
/// </summary>
public OperatorInfo Operator { get; private set; }
/// <summary>
/// 执行UTC时间
/// </summary>
public DateTime ExecuteUtcTime { get; private set; }
private BusinessFlowRecord()
{
}
/// <summary>
/// 工厂创建流程记录
/// </summary>
public static BusinessFlowRecord Create(long recordId, long businessId, string phaseName,
BusinessFlowStatus flowStatus, string message, int errorCode, OperatorInfo opInfo)
{
if (recordId <= 0) throw new ArgumentException("记录ID必须大于0");
if (businessId <= 0) throw new ArgumentException("业务ID必须大于0");
if (string.IsNullOrWhiteSpace(phaseName)) throw new ArgumentException("业务环节不能为空");
return new BusinessFlowRecord
{
RecordId = recordId,
BusinessId = businessId,
PhaseName = phaseName,
FlowStatus = flowStatus,
Message = message,
ErrorCode = errorCode,
Operator = opInfo,
ExecuteUtcTime = DateTime.UtcNow
};
}
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : JewelryMaterial.cs
*/
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Entities
{
/// <summary>
/// 珠宝原料 领域实体,拥有唯一业务标识
/// </summary>
public class JewelryMaterial
{
/// <summary>
/// 原料唯一编号
/// </summary>
public long Id { get; private set; }
/// <summary>
/// 物料编码
/// </summary>
public string MaterialCode { get; private set; } = string.Empty;
/// <summary>
/// 原料名称
/// </summary>
public string MaterialName { get; private set; } = string.Empty;
/// <summary>
/// 重量,单位克
/// </summary>
public decimal WeightGram { get; private set; }
/// <summary>
/// 品质等级
/// </summary>
public MaterialQualityGrade QualityGrade { get; private set; }
/// <summary>
/// 采购成本金额
/// </summary>
public Money PurchaseCost { get; private set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; private set; }
/// <summary>
/// 是否已经核验通过
/// </summary>
public bool IsVerified { get; private set; }
/// <summary>
/// 私有构造,领域实体禁止外部new
/// </summary>
private JewelryMaterial()
{
}
/// <summary>
/// 工厂方法创建珠宝原料实体
/// </summary>
/// <param name="id">主键ID</param>
/// <param name="materialCode">物料编码</param>
/// <param name="materialName">物料名称</param>
/// <param name="weightGram">重量克</param>
/// <param name="qualityGrade">品质等级</param>
/// <param name="purchaseCost">采购成本</param>
/// <returns>实体实例</returns>
public static JewelryMaterial Create(long id,
string materialCode,
string materialName,
decimal weightGram,
MaterialQualityGrade qualityGrade,
Money purchaseCost)
{
if (id <= 0) throw new ArgumentException("实体ID必须大于0");
if (string.IsNullOrWhiteSpace(materialCode)) throw new ArgumentException("物料编码不能为空");
if (string.IsNullOrWhiteSpace(materialName)) throw new ArgumentException("物料名称不能为空");
if (weightGram <= 0) throw new ArgumentException("重量必须大于0");
return new JewelryMaterial
{
Id = id,
MaterialCode = materialCode,
MaterialName = materialName,
WeightGram = weightGram,
QualityGrade = qualityGrade,
PurchaseCost = purchaseCost,
CreateTime = DateTime.UtcNow,
IsVerified = false
};
}
/// <summary>
/// 标记原料核验通过,领域内业务行为
/// </summary>
public void MarkVerified()
{
IsVerified = true;
}
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : JewelryProduct.cs
*/
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Entities
{
/// <summary>
/// 珠宝成品产品实体
/// </summary>
public class JewelryProduct
{
/// <summary>
/// 产品主键ID
/// </summary>
public long Id { get; private set; }
/// <summary>
/// 产品外部编号
/// </summary>
public string ProductNo { get; private set; } = string.Empty;
/// <summary>
/// 产品名称
/// </summary>
public string ProductName { get; private set; } = string.Empty;
/// <summary>
/// 对应原料ID
/// </summary>
public long MaterialId { get; private set; }
/// <summary>
/// 销售定价
/// </summary>
public Money SalePrice { get; private set; }
/// <summary>
/// 是否质检合格
/// </summary>
public bool IsQualityPass { get; private set; }
/// <summary>
/// 创建UTC时间
/// </summary>
public DateTime CreateUtcTime { get; private set; }
private JewelryProduct()
{
}
/// <summary>
/// 工厂创建成品
/// </summary>
public static JewelryProduct Create(long id, string productNo, string productName, long materialId, Money salePrice)
{
if (id <= 0) throw new ArgumentException("产品ID必须大于0");
if (string.IsNullOrWhiteSpace(productNo)) throw new ArgumentException("产品编号不能为空");
if (string.IsNullOrWhiteSpace(productName)) throw new ArgumentException("产品名称不能为空");
if (materialId <= 0) throw new ArgumentException("关联原料ID非法");
return new JewelryProduct
{
Id = id,
ProductNo = productNo,
ProductName = productName,
MaterialId = materialId,
SalePrice = salePrice,
IsQualityPass = false,
CreateUtcTime = DateTime.UtcNow
};
}
/// <summary>
/// 设置质检合格
/// </summary>
public void SetQualityPass()
{
IsQualityPass = true;
}
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : BusinessFlowStatus.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Enums
{
/// <summary>
/// 业务流程执行状态枚举
/// </summary>
public enum BusinessFlowStatus
{
/// <summary>
/// 未执行
/// </summary>
None = 0,
/// <summary>
/// 执行成功
/// </summary>
Success = 1,
/// <summary>
/// 执行失败
/// </summary>
Failed = 2,
/// <summary>
/// 熔断拦截
/// </summary>
CircuitBlocked = 3
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : MaterialQualityGrade.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Enums
{
/// <summary>
/// 珠宝原料品质等级
/// </summary>
public enum MaterialQualityGrade
{
/// <summary>
/// 未评级
/// </summary>
UnGrade = 0,
/// <summary>
/// A级优质
/// </summary>
GradeA = 1,
/// <summary>
/// B级普通
/// </summary>
GradeB = 2,
/// <summary>
/// C级次品
/// </summary>
GradeC = 3
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : IBusinessFlowRecordRepository.cs
*/
using StrategyPattern.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Interfaces
{
/// <summary>
/// 业务流程流水记录仓储接口
/// </summary>
public interface IBusinessFlowRecordRepository
{
/// <summary>
/// 新增流程流水记录
/// </summary>
/// <param name="record">流水记录实体</param>
Task AddAsync(BusinessFlowRecord record);
/// <summary>
/// 根据业务ID查询全部流水
/// </summary>
/// <param name="businessId">业务编号</param>
/// <returns>流水集合</returns>
Task<List<BusinessFlowRecord>> QueryByBusinessIdAsync(long businessId);
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : IJewelryMaterialRepository.cs
*/
using StrategyPattern.Domain.Entities;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Interfaces
{
/// <summary>
/// 珠宝原料仓储接口,领域层只定义接口,实现在基础设施层
/// </summary>
public interface IJewelryMaterialRepository
{
/// <summary>
/// 根据ID获取原料
/// </summary>
/// <param name="id">主键</param>
/// <returns>原料实体,没有返回null</returns>
Task<JewelryMaterial?> GetByIdAsync(long id);
/// <summary>
/// 根据物料编码查询
/// </summary>
/// <param name="materialCode">物料编码</param>
/// <returns>实体</returns>
Task<JewelryMaterial?> GetByCodeAsync(string materialCode);
/// <summary>
/// 添加原料
/// </summary>
/// <param name="entity">原料实体</param>
Task AddAsync(JewelryMaterial entity);
/// <summary>
/// 更新原料
/// </summary>
/// <param name="entity">原料实体</param>
Task UpdateAsync(JewelryMaterial entity);
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : IUnitOfWork.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Interfaces
{
/// <summary>
/// 工作单元接口,控制事务,领域层抽象
/// </summary>
public interface IUnitOfWork
{
/// <summary>
/// 提交全部变更
/// </summary>
/// <returns>受影响行数</returns>
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : MaterialDomainService.cs
*/
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.Services
{
/// <summary>
/// 原料领域服务,处理领域业务规则,不依赖外部基础设施
/// </summary>
public class MaterialDomainService
{
private readonly IJewelryMaterialRepository _materialRepo;
/// <summary>
/// 构造注入仓储接口
/// </summary>
/// <param name="materialRepo">原料仓储接口</param>
public MaterialDomainService(IJewelryMaterialRepository materialRepo)
{
_materialRepo = materialRepo;
}
/// <summary>
/// 执行原料核验领域规则校验
/// </summary>
/// <param name="materialCode">物料编码</param>
/// <param name="opInfo">操作人员</param>
/// <returns>核验后的原料实体</returns>
/// <exception cref="InvalidOperationException">校验不通过抛出领域异常</exception>
public async Task<JewelryMaterial> VerifyMaterialAsync(string materialCode, OperatorInfo opInfo)
{
var material = await _materialRepo.GetByCodeAsync(materialCode);
if (material is null)
{
throw new InvalidOperationException($"物料编码[{materialCode}]不存在");
}
if (material.IsVerified)
{
throw new InvalidOperationException($"物料[{materialCode}]已经完成核验,不可重复核验");
}
//领域业务规则:重量必须大于0
if (material.WeightGram <= 0)
{
throw new InvalidOperationException($"物料[{materialCode}]重量非法,无法核验");
}
material.MarkVerified();
await _materialRepo.UpdateAsync(material);
return material;
}
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : Money.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.ValueObjects
{
/// <summary>
/// 金额值对象,封装货币,防止浮点数精度问题
/// </summary>
public record Money
{
/// <summary>
/// 金额数值
/// </summary>
public decimal Amount { get; }
/// <summary>
/// 货币单位
/// </summary>
public string Currency { get; }
/// <summary>
/// 私有构造
/// </summary>
/// <param name="amount">金额</param>
/// <param name="currency">货币</param>
private Money(decimal amount, string currency)
{
Amount = amount;
Currency = currency;
}
/// <summary>
/// 创建人民币金额
/// </summary>
/// <param name="amount">金额</param>
/// <returns>Money实例</returns>
public static Money CreateCny(decimal amount)
{
if (amount < 0)
throw new ArgumentException("金额不能为负数");
return new Money(amount, "CNY");
}
}
}
/*
encoding: utf-8
版权所有 2026 ©涂聚文有限公司™ ®
许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
Author : geovindu,Geovin Du 涂聚文.
IDE : vs2026 c# .net 10
os : windows 10
database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
Datetime : 2026/08/22 22:16
User : geovindu
Product : Visual Studio 2026
Project : CSharpDesignPattern
File : OperatorInfo.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Domain.ValueObjects
{
/// <summary>
/// 操作人员信息 值对象,无独立ID,不可变
/// </summary>
public record OperatorInfo
{
/// <summary>
/// 操作人员编号
/// </summary>
public long OperatorId { get; }
/// <summary>
/// 操作人员姓名
/// </summary>
public string OperatorName { get; }
/// <summary>
/// 所属部门
/// </summary>
public string Department { get; }
/// <summary>
/// 私有构造,只能通过工厂方法创建
/// </summary>
/// <param name="operatorId">操作员ID</param>
/// <param name="operatorName">操作员名称</param>
/// <param name="department">部门名称</param>
private OperatorInfo(long operatorId, string operatorName, string department)
{
OperatorId = operatorId;
OperatorName = operatorName;
Department = department;
}
/// <summary>
/// 工厂方法创建操作人员信息
/// </summary>
/// <param name="operatorId">操作员ID</param>
/// <param name="operatorName">操作员名称</param>
/// <param name="department">部门名称</param>
/// <returns>值对象实例</returns>
/// <exception cref="ArgumentException">参数校验异常</exception>
public static OperatorInfo Create(long operatorId, string operatorName, string department)
{
if (operatorId <= 0)
throw new ArgumentException("操作员ID必须大于0");
if (string.IsNullOrWhiteSpace(operatorName))
throw new ArgumentException("操作员名称不能为空");
if (string.IsNullOrWhiteSpace(department))
throw new ArgumentException("部门不能为空");
return new OperatorInfo(operatorId, operatorName, department);
}
}
}
cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessExecuteResultDto.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Dtos
{
/// <summary>
/// 业务策略执行返回结果DTO
/// </summary>
public class BusinessExecuteResultDto
{
/// <summary>
/// 是否执行成功
/// </summary>
public bool IsSuccess { get; set; }
/// <summary>
/// 返回消息
/// </summary>
public string Message { get; set; } = string.Empty;
/// <summary>
/// 业务输出数据对象
/// </summary>
public object? OutputData { get; set; }
/// <summary>
/// 业务错误码,0代表无错误
/// </summary>
public int ErrorCode { get; set; }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryBusinessInputDto.cs
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Dtos
{
/// <summary>
/// 珠宝业务输入DTO,应用层接收外部输入数据
/// </summary>
public class JewelryBusinessInputDto
{
/// <summary>
/// 业务唯一编号
/// </summary>
public long BusinessId { get; set; }
/// <summary>
/// 当前业务环节名称
/// </summary>
public string BusinessPhase { get; set; } = string.Empty;
/// <summary>
/// 原料物料编码
/// </summary>
public string MaterialCode { get; set; } = string.Empty;
/// <summary>
/// 珠宝产品编号
/// </summary>
public string ProductNo { get; set; } = string.Empty;
/// <summary>
/// 业务数量
/// </summary>
public decimal Quantity { get; set; }
/// <summary>
/// 业务金额
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// 操作人员ID
/// </summary>
public long OperatorId { get; set; }
/// <summary>
/// 操作人员名称
/// </summary>
public string OperatorName { get; set; } = string.Empty;
/// <summary>
/// 操作人员所属部门
/// </summary>
public string OperatorDepartment { get; set; } = string.Empty;
/// <summary>
/// 业务备注
/// </summary>
public string Remark { get; set; } = string.Empty;
/// <summary>
/// 业务发生本地时间
/// </summary>
public DateTime OccurTime { get; set; }
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IBusinessStrategy.cs
*/
using StrategyPattern.Application.Dtos;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Interfaces
{
/// <summary>
/// 业务策略接口,策略模式抽象,应用层定义
/// 每一个珠宝业务环节实现该接口,实现开闭原则
/// </summary>
public interface IBusinessStrategy
{
/// <summary>
/// 获取业务环节显示名称
/// </summary>
string PhaseName { get; }
/// <summary>
/// 执行业务逻辑
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>业务执行结果DTO</returns>
Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : IResilienceExecutor.cs
*/
using StrategyPattern.Application.Dtos;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Interfaces
{
/// <summary>
/// 弹性执行器接口:重试+熔断,应用层抽象,实现在基础设施层
/// </summary>
public interface IResilienceExecutor
{
/// <summary>
/// 使用熔断重试包装业务委托执行
/// </summary>
/// <param name="businessFunc">业务异步委托</param>
/// <param name="businessId">业务编号,用于日志追踪</param>
/// <returns>业务执行结果</returns>
Task<BusinessExecuteResultDto> ExecuteWithResilienceAsync(Func<Task<BusinessExecuteResultDto>> businessFunc, long businessId);
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : BusinessStrategyContext.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Services
{
/// <summary>
/// 策略上下文,持有策略实例,对外统一调用入口
/// 职责:封装策略切换,调用策略执行,记录日志
/// </summary>
public class BusinessStrategyContext
{
private readonly ILogger<BusinessStrategyContext> _logger;
private IBusinessStrategy? _currentStrategy;
/// <summary>
/// 构造注入日志对象
/// </summary>
/// <param name="logger">日志实例</param>
public BusinessStrategyContext(ILogger<BusinessStrategyContext> logger)
{
_logger = logger;
}
/// <summary>
/// 设置当前运行的业务策略
/// </summary>
/// <param name="strategy">业务策略实现</param>
public void SetStrategy(IBusinessStrategy strategy)
{
_logger.LogDebug("业务策略切换,目标环节:{PhaseName}", strategy.PhaseName);
_currentStrategy = strategy;
}
/// <summary>
/// 异步执行当前策略业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
/// <exception cref="InvalidOperationException">策略未设置抛出异常</exception>
public async Task<BusinessExecuteResultDto> RunAsync(JewelryBusinessInputDto input)
{
if (_currentStrategy is null)
{
_logger.LogError("BusinessStrategyContext未设置业务策略,BusinessId:{BusinessId}", input.BusinessId);
throw new InvalidOperationException("未指定业务处理策略实例");
}
_logger.LogInformation("开始执行业务环节:{PhaseName} BusinessId:{BusinessId}",
_currentStrategy.PhaseName, input.BusinessId);
var result = await _currentStrategy.ExecuteAsync(input);
if (result.IsSuccess)
{
_logger.LogInformation("业务环节执行成功 {PhaseName} BusinessId:{BusinessId} Msg:{Msg}",
_currentStrategy.PhaseName, input.BusinessId, result.Message);
}
else
{
_logger.LogWarning("业务环节执行失败 {PhaseName} BusinessId:{BusinessId} Code:{Code} Msg:{Msg}",
_currentStrategy.PhaseName, input.BusinessId, result.ErrorCode, result.Message);
}
return result;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : JewelryFlowApplicationService.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Services
{
/// <summary>
/// 珠宝业务流程应用服务,编排完整业务流水线,应用层协调领域、策略、弹性组件
/// 职责单一:只做业务编排,不写具体业务逻辑,业务逻辑下沉到各个Strategy
/// </summary>
public class JewelryFlowApplicationService
{
private readonly ILogger<JewelryFlowApplicationService> _logger;
private readonly BusinessStrategyContext _strategyContext;
private readonly IResilienceExecutor _resilienceExecutor;
private readonly IEnumerable<IBusinessStrategy> _allBusinessStrategies;
private readonly IBusinessFlowRecordRepository _flowRecordRepo;
private readonly IUnitOfWork _unitOfWork;
/// <summary>
/// DI构造注入全部依赖
/// </summary>
/// <param name="logger">日志</param>
/// <param name="strategyContext">策略上下文</param>
/// <param name="resilienceExecutor">弹性熔断重试执行器</param>
/// <param name="allBusinessStrategies">全部业务策略集合</param>
/// <param name="flowRecordRepo">流程流水仓储</param>
/// <param name="unitOfWork">工作单元</param>
public JewelryFlowApplicationService(
ILogger<JewelryFlowApplicationService> logger,
BusinessStrategyContext strategyContext,
IResilienceExecutor resilienceExecutor,
IEnumerable<IBusinessStrategy> allBusinessStrategies,
IBusinessFlowRecordRepository flowRecordRepo,
IUnitOfWork unitOfWork)
{
_logger = logger;
_strategyContext = strategyContext;
_resilienceExecutor = resilienceExecutor;
_allBusinessStrategies = allBusinessStrategies;
_flowRecordRepo = flowRecordRepo;
_unitOfWork = unitOfWork;
}
/// <summary>
/// 根据环节名称获取对应策略实例
/// </summary>
/// <param name="phaseName">业务环节名称</param>
/// <returns>业务策略实例</returns>
/// <exception cref="NotSupportedException">找不到策略抛出异常</exception>
private IBusinessStrategy GetStrategyByPhaseName(string phaseName)
{
var strategy = _allBusinessStrategies.FirstOrDefault(s => s.PhaseName == phaseName);
if (strategy == null)
{
_logger.LogError("无法找到业务策略,环节名称:{PhaseName}", phaseName);
throw new NotSupportedException($"不支持的业务环节:{phaseName}");
}
return strategy;
}
/// <summary>
/// 保存流程执行流水记录
/// </summary>
/// <param name="input">输入DTO</param>
/// <param name="result">执行结果</param>
private async Task SaveFlowRecordAsync(JewelryBusinessInputDto input, BusinessExecuteResultDto result)
{
var opInfo = OperatorInfo.Create(input.OperatorId, input.OperatorName, input.OperatorDepartment);
var flowStatus = result.IsSuccess ? BusinessFlowStatus.Success : BusinessFlowStatus.Failed;
long recordId = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
var record = BusinessFlowRecord.Create(
recordId: recordId,
businessId: input.BusinessId,
phaseName: input.BusinessPhase,
flowStatus: flowStatus,
message: result.Message,
errorCode: result.ErrorCode,
opInfo: opInfo);
await _flowRecordRepo.AddAsync(record);
await _unitOfWork.SaveChangesAsync();
}
/// <summary>
/// 执行单个业务环节(外层包装熔断重试)
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>业务执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteSinglePhaseAsync(JewelryBusinessInputDto input)
{
_logger.LogInformation("应用服务开始调度单环节 BusinessId:{BusinessId} Phase:{Phase}",
input.BusinessId, input.BusinessPhase);
var strategy = GetStrategyByPhaseName(input.BusinessPhase);
_strategyContext.SetStrategy(strategy);
//使用弹性适配器包装策略执行
var result = await _resilienceExecutor.ExecuteWithResilienceAsync(async () =>
{
return await _strategyContext.RunAsync(input);
}, input.BusinessId);
//写入流程流水记录
await SaveFlowRecordAsync(input, result);
_logger.LogInformation("应用服务单环节执行完成 BusinessId:{BusinessId} Success:{Success}",
input.BusinessId, result.IsSuccess);
return result;
}
/// <summary>
/// 执行珠宝完整业务流水线:原料采购核验→设计制图→加工生产→质检→包装→物流→财务
/// </summary>
/// <param name="baseInput">基础业务输入DTO</param>
/// <returns>每一步骤执行结果集合</returns>
public async Task<List<BusinessExecuteResultDto>> ExecuteFullJewelryPipelineAsync(JewelryBusinessInputDto baseInput)
{
_logger.LogInformation("==========启动珠宝完整业务流水线 BusinessId:{BusinessId} ==========", baseInput.BusinessId);
List<string> pipelinePhaseList = new List<string>
{
"原料采购核验",
"设计制图",
"加工生产",
"质检",
"包装",
"物流",
"财务"
};
var resultCollection = new List<BusinessExecuteResultDto>();
foreach (var phaseName in pipelinePhaseList)
{
var phaseInputDto = new JewelryBusinessInputDto
{
BusinessId = baseInput.BusinessId,
BusinessPhase = phaseName,
MaterialCode = baseInput.MaterialCode,
ProductNo = baseInput.ProductNo,
Quantity = baseInput.Quantity,
Amount = baseInput.Amount,
OperatorId = baseInput.OperatorId,
OperatorName = baseInput.OperatorName,
OperatorDepartment = baseInput.OperatorDepartment,
Remark = baseInput.Remark,
OccurTime = DateTime.UtcNow
};
var phaseResult = await ExecuteSinglePhaseAsync(phaseInputDto);
resultCollection.Add(phaseResult);
// 如果某一步失败,终止流水线
if (!phaseResult.IsSuccess)
{
_logger.LogError("业务流水线在环节【{PhaseName}】中断,BusinessId:{BusinessId}", phaseName, baseInput.BusinessId);
break;
}
}
_logger.LogInformation("==========珠宝完整业务流水线执行结束 BusinessId:{BusinessId} ==========", baseInput.BusinessId);
return resultCollection;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : DesignDrawStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:设计制图业务环节
/// </summary>
public class DesignDrawStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "设计制图";
private readonly ILogger<DesignDrawStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public DesignDrawStrategy(ILogger<DesignDrawStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行业务逻辑
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("设计制图环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
if (input.Quantity <= 0)
{
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 2001,
Message = "设计数量必须大于0"
};
}
//模拟3D制图耗时
await Task.Delay(10);
var designOutput = new
{
BusinessId = input.BusinessId,
ProductNo = input.ProductNo,
DesignFileId = $"DES-{input.BusinessId}",
Designer = input.OperatorName,
CreateUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"3D设计制图完成,产品编号:{input.ProductNo}",
OutputData = designOutput
};
}
catch (Exception ex)
{
_logger.LogError(ex, "设计制图环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"设计制图异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : FinanceSettleStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:财务结算业务环节
/// </summary>
public class FinanceSettleStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "财务";
private readonly ILogger<FinanceSettleStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public FinanceSettleStrategy(ILogger<FinanceSettleStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行财务结算业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("财务结算环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
if (input.Amount <= 0)
{
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 7001,
Message = "结算金额必须大于0"
};
}
await Task.Delay(10);
var financeData = new
{
BusinessId = input.BusinessId,
BillNo = $"BILL-{input.BusinessId}",
SettleAmount = input.Amount,
FinanceOperator = input.OperatorName,
SettleUtcTime = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"财务结算完成,单据号:{financeData.BillNo},结算金额:{input.Amount}",
OutputData = financeData
};
}
catch (Exception ex)
{
_logger.LogError(ex, "财务结算环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"财务结算异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : HumanResourceStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:人事业务环节(支持部门)
/// </summary>
public class HumanResourceStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "人事";
private readonly ILogger<HumanResourceStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public HumanResourceStrategy(ILogger<HumanResourceStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行人事业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("人事业务环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(5);
var hrOutput = new
{
BusinessId = input.BusinessId,
OperatorDept = input.OperatorDepartment,
OperateUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"人事业务处理完成,操作部门:{input.OperatorDepartment}",
OutputData = hrOutput
};
}
catch (Exception ex)
{
_logger.LogError(ex, "人事环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"人事业务异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : LogisticsStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:物流业务环节
/// </summary>
public class LogisticsStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "物流";
private readonly ILogger<LogisticsStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public LogisticsStrategy(ILogger<LogisticsStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行物流业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("物流环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(12);
var logisticsData = new
{
ProductNo = input.ProductNo,
ExpressNo = $"EXP-{input.BusinessId}",
ShipOperator = input.OperatorName,
ShipUtcTime = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"物流发货完成,快递单号:{logisticsData.ExpressNo}",
OutputData = logisticsData
};
}
catch (Exception ex)
{
_logger.LogError(ex, "物流环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"物流异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ManufactureProduceStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:加工生产业务环节
/// </summary>
public class ManufactureProduceStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "加工生产";
private readonly ILogger<ManufactureProduceStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public ManufactureProduceStrategy(ILogger<ManufactureProduceStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行加工生产业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("加工生产环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
if (string.IsNullOrWhiteSpace(input.ProductNo))
{
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 3001,
Message = "产品编号不能为空,无法开始加工"
};
}
await Task.Delay(15);
var manufactureResult = new
{
ProductNo = input.ProductNo,
ProcessBatchNo = $"BATCH-{input.BusinessId}",
ProduceCount = input.Quantity,
ProduceTimeUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"加工生产完成,批次号:{manufactureResult.ProcessBatchNo}",
OutputData = manufactureResult
};
}
catch (Exception ex)
{
_logger.LogError(ex, "加工生产环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"加工生产异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MarketingStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:营销业务环节
/// </summary>
public class MarketingStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "营销";
private readonly ILogger<MarketingStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public MarketingStrategy(ILogger<MarketingStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行营销业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("营销业务环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(8);
var marketingOutput = new
{
BusinessId = input.BusinessId,
ProductNo = input.ProductNo,
MarketAmount = input.Amount,
MarketUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"营销业务处理完成,产品:{input.ProductNo}",
OutputData = marketingOutput
};
}
catch (Exception ex)
{
_logger.LogError(ex, "营销环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"营销业务异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MaterialPurchaseVerifyStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using StrategyPattern.Domain.Services;
using StrategyPattern.Domain.ValueObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:原料采购核验环节
/// </summary>
public class MaterialPurchaseVerifyStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "原料采购核验";
private readonly ILogger<MaterialPurchaseVerifyStrategy> _logger;
private readonly MaterialDomainService _materialDomainService;
/// <summary>
/// 构造注入
/// </summary>
/// <param name="logger">日志对象</param>
/// <param name="materialDomainService">原料领域服务</param>
public MaterialPurchaseVerifyStrategy(ILogger<MaterialPurchaseVerifyStrategy> logger, MaterialDomainService materialDomainService)
{
_logger = logger;
_materialDomainService = materialDomainService;
}
/// <summary>
/// 执行原料采购核验业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("原料采购核验开始,物料编码:{MaterialCode}, BusinessId:{BusinessId}", input.MaterialCode, input.BusinessId);
if (string.IsNullOrWhiteSpace(input.MaterialCode))
{
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 1001,
Message = "物料编码不能为空"
};
}
var opInfo = OperatorInfo.Create(input.OperatorId, input.OperatorName, input.OperatorDepartment);
var verifiedMaterial = await _materialDomainService.VerifyMaterialAsync(input.MaterialCode, opInfo);
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"原料核验成功,物料编号:{verifiedMaterial.MaterialCode},重量:{verifiedMaterial.WeightGram}g",
OutputData = verifiedMaterial
};
}
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "原料采购核验业务校验失败 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 1002,
Message = ex.Message
};
}
catch (Exception ex)
{
_logger.LogError(ex, "原料采购核验发生未知异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"系统异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : PackageStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:包装业务环节
/// </summary>
public class PackageStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "包装";
private readonly ILogger<PackageStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public PackageStrategy(ILogger<PackageStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行包装业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("包装环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(6);
var packageData = new
{
ProductNo = input.ProductNo,
PackageBoxNo = $"PK-{input.BusinessId}",
PackageOperator = input.OperatorName,
PackageUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"珠宝产品包装完成,包装盒编号:{packageData.PackageBoxNo}",
OutputData = packageData
};
}
catch (Exception ex)
{
_logger.LogError(ex, "包装环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"包装异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : QualityInspectStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:质检业务环节
/// </summary>
public class QualityInspectStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "质检";
private readonly ILogger<QualityInspectStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public QualityInspectStrategy(ILogger<QualityInspectStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行质检业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("质检环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(8);
var inspectResult = new
{
ProductNo = input.ProductNo,
InspectNo = $"Q-{input.BusinessId}",
Inspector = input.OperatorName,
Pass = true,
InspectUtcTime = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"产品质检完成,质检单号:{inspectResult.InspectNo},检验结果:合格",
OutputData = inspectResult
};
}
catch (Exception ex)
{
_logger.LogError(ex, "质检环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"质检异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : StockManageStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:库存管理业务环节
/// </summary>
public class StockManageStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "库存管理";
private readonly ILogger<StockManageStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public StockManageStrategy(ILogger<StockManageStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行库存管理业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("库存管理环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(9);
var stockOutput = new
{
BusinessId = input.BusinessId,
MaterialCode = input.MaterialCode,
ProductNo = input.ProductNo,
StockChangeQty = input.Quantity,
StockUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"库存业务处理完成,物料:{input.MaterialCode},产品:{input.ProductNo}",
OutputData = stockOutput
};
}
catch (Exception ex)
{
_logger.LogError(ex, "库存管理环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"库存业务异常:{ex.Message}"
};
}
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : TrainStrategy.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Application.Strategies
{
/// <summary>
/// 策略:培训业务环节(支持部门)
/// </summary>
public class TrainStrategy : IBusinessStrategy
{
/// <summary>
/// 业务环节名称
/// </summary>
public string PhaseName => "培训";
private readonly ILogger<TrainStrategy> _logger;
/// <summary>
/// 构造注入日志
/// </summary>
/// <param name="logger">日志实例</param>
public TrainStrategy(ILogger<TrainStrategy> logger)
{
_logger = logger;
}
/// <summary>
/// 执行培训业务
/// </summary>
/// <param name="input">业务输入DTO</param>
/// <returns>执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteAsync(JewelryBusinessInputDto input)
{
try
{
_logger.LogInformation("培训业务环节开始执行 BusinessId:{BusinessId}", input.BusinessId);
await Task.Delay(7);
var trainOutput = new
{
BusinessId = input.BusinessId,
Remark = input.Remark,
TrainUtc = DateTime.UtcNow
};
return new BusinessExecuteResultDto
{
IsSuccess = true,
ErrorCode = 0,
Message = $"培训业务处理完成,备注:{input.Remark}",
OutputData = trainOutput
};
}
catch (Exception ex)
{
_logger.LogError(ex, "培训环节异常 BusinessId:{BusinessId}", input.BusinessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = 9999,
Message = $"培训业务异常:{ex.Message}"
};
}
}
}
}
cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : ServiceCollectionExtension.cs
*/
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Console;
using StrategyPattern.Application.Interfaces;
using StrategyPattern.Application.Services;
using StrategyPattern.Application.Strategies;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.Services;
using StrategyPattern.Infrastructure.Logging;
using StrategyPattern.Infrastructure.Repositories;
using StrategyPattern.Infrastructure.Resilience;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Infrastructure.Extensions
{
/// <summary>
/// DI扩展注册全部服务,分层注册,入口程序只调用该扩展,解耦依赖
/// </summary>
public static class ServiceCollectionExtension
{
/// <summary>
/// 注册全部领域、应用、基础设施层服务
/// </summary>
/// <param name="services">服务集合</param>
/// <param name="logRootPath">日志根目录</param>
public static void AddJewelryEnterpriseServices(this IServiceCollection services, string logRootPath)
{
//日志配置
services.AddLogging(logBuilder =>
{
logBuilder.ClearProviders();
logBuilder.AddConsole();
logBuilder.AddEnterpriseFileLogger(logRootPath);
logBuilder.SetMinimumLevel(LogLevel.Debug);
});
#region 领域层注册
services.AddScoped<MaterialDomainService>();
services.AddScoped<IJewelryMaterialRepository, MemoryJewelryMaterialRepository>();
services.AddScoped<IBusinessFlowRecordRepository, MemoryBusinessFlowRecordRepository>();
services.AddScoped<IUnitOfWork, MemoryUnitOfWork>();
#endregion
#region 应用层注册
//注册全部业务策略
services.AddScoped<IBusinessStrategy, MaterialPurchaseVerifyStrategy>();
services.AddScoped<IBusinessStrategy, DesignDrawStrategy>();
services.AddScoped<IBusinessStrategy, ManufactureProduceStrategy>();
services.AddScoped<IBusinessStrategy, QualityInspectStrategy>();
services.AddScoped<IBusinessStrategy, PackageStrategy>();
services.AddScoped<IBusinessStrategy, LogisticsStrategy>();
services.AddScoped<IBusinessStrategy, FinanceSettleStrategy>();
services.AddScoped<IBusinessStrategy, HumanResourceStrategy>();
services.AddScoped<IBusinessStrategy, TrainStrategy>();
services.AddScoped<IBusinessStrategy, StockManageStrategy>();
services.AddScoped<IBusinessStrategy, MarketingStrategy>();
services.AddScoped<BusinessStrategyContext>();
services.AddScoped<JewelryFlowApplicationService>();
#endregion
#region 基础设施层
services.AddScoped<IResilienceExecutor, CircuitBreakerResilienceExecutor>();
#endregion
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : CustomLogFormatter.cs
*/
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Text;
namespace StrategyPattern.Infrastructure.Logging
{
/// <summary>
/// 自定义日志格式化器,保证控制台输出与文件日志输出格式完全一致(Karambolo v4 回调式接口)
/// </summary>
public class CustomLogFormatter : IFileLogEntryTextBuilder
{
/// <summary>
/// 构建日志输出文本,文件日志与控制台共用一套格式
/// </summary>
public void BuildEntryText(
StringBuilder sb,
string category,
LogLevel logLevel,
EventId eventId,
string message,
Exception exception,
IExternalScopeProvider scopeProvider,
DateTimeOffset timestamp)
{
// 时间(使用服务器本地时间)
sb.Append(timestamp.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
sb.Append(" | ");
// 日志级别
sb.Append(logLevel.ToString().PadRight(5));
sb.Append(" | TID:");
sb.Append(Thread.CurrentThread.ManagedThreadId.ToString().PadLeft(3));
sb.Append(" | ");
// 分类器
sb.Append(category);
sb.Append(" | ");
// 消息
sb.Append(message);
if (exception != null)
{
sb.AppendLine();
sb.Append(exception.ToString());
}
}
}
}/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : LoggerFactoryExtension.cs
*/
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
namespace StrategyPattern.Infrastructure.Logging
{
/// <summary>
/// 日志扩展方法,统一配置文件日志,按日期分文件夹,按级别分文件
/// </summary>
public static class LoggerFactoryExtension
{
/// <summary>
/// 添加企业级结构化文件日志
/// </summary>
/// <param name="builder">日志构建器</param>
/// <param name="logRootPath">日志根目录</param>
public static void AddEnterpriseFileLogger(this ILoggingBuilder builder, string logRootPath)
{
if (!Directory.Exists(logRootPath))
{
Directory.CreateDirectory(logRootPath);
}
var customFormatter = new CustomLogFormatter();
builder.AddFile(options =>
{
options.RootPath = logRootPath;
options.Files = new[]
{
new LogFileOptions
{
Path = "info/<date:yyyy-MM-dd>/app-info.log",
MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Information },
TextBuilder = customFormatter
},
new LogFileOptions
{
Path = "debug/<date:yyyy-MM-dd>/app-debug.log",
MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Debug },
TextBuilder = customFormatter
},
new LogFileOptions
{
Path = "warn/<date:yyyy-MM-dd>/app-warn.log",
MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Warning },
TextBuilder = customFormatter
},
new LogFileOptions
{
Path = "error/<date:yyyy-MM-dd>/app-error.log",
MinLevel = new Dictionary<string, LogLevel> { ["Default"] = LogLevel.Error },
TextBuilder = customFormatter
}
};
options.FileAccessMode = LogFileAccessMode.KeepOpen;
});
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MemoryBusinessFlowRecordRepository.cs
*/
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Infrastructure.Repositories
{
/// <summary>
/// 内存实现业务流程流水仓储,多线程安全
/// </summary>
public class MemoryBusinessFlowRecordRepository : IBusinessFlowRecordRepository
{
private readonly ConcurrentBag<BusinessFlowRecord> _recordBag;
/// <summary>
/// 构造初始化
/// </summary>
public MemoryBusinessFlowRecordRepository()
{
_recordBag = new ConcurrentBag<BusinessFlowRecord>();
}
/// <summary>
/// 新增流程流水记录
/// </summary>
/// <param name="record">流水实体</param>
public Task AddAsync(BusinessFlowRecord record)
{
_recordBag.Add(record);
return Task.CompletedTask;
}
/// <summary>
/// 根据业务ID查询全部流水
/// </summary>
/// <param name="businessId">业务编号</param>
/// <returns>流水集合</returns>
public Task<List<BusinessFlowRecord>> QueryByBusinessIdAsync(long businessId)
{
var list = _recordBag.Where(r => r.BusinessId == businessId).ToList();
return Task.FromResult(list);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MemoryJewelryMaterialRepository.cs
*/
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Infrastructure.Repositories
{
/// <summary>
/// 内存实现原料仓储,并发安全,生产环境替换为EF Core/Dapper实现
/// </summary>
public class MemoryJewelryMaterialRepository : IJewelryMaterialRepository
{
/// <summary>
/// 内存存储集合,线程安全
/// </summary>
private readonly ConcurrentDictionary<long, JewelryMaterial> _storeDict;
/// <summary>
/// 按物料编码索引
/// </summary>
private readonly ConcurrentDictionary<string, long> _codeToIdIndex;
/// <summary>
/// 构造初始化
/// </summary>
public MemoryJewelryMaterialRepository()
{
_storeDict = new ConcurrentDictionary<long, JewelryMaterial>();
_codeToIdIndex = new ConcurrentDictionary<string, long>();
}
/// <summary>
/// 根据ID获取原料
/// </summary>
/// <param name="id">主键ID</param>
/// <returns>实体或null</returns>
public Task<JewelryMaterial?> GetByIdAsync(long id)
{
_storeDict.TryGetValue(id, out var entity);
return Task.FromResult(entity);
}
/// <summary>
/// 根据物料编码查询
/// </summary>
/// <param name="materialCode">物料编码</param>
/// <returns>实体或null</returns>
public Task<JewelryMaterial?> GetByCodeAsync(string materialCode)
{
if (_codeToIdIndex.TryGetValue(materialCode, out var id))
{
_storeDict.TryGetValue(id, out var entity);
return Task.FromResult(entity);
}
return Task.FromResult<JewelryMaterial?>(null);
}
/// <summary>
/// 添加原料实体
/// </summary>
/// <param name="entity">原料实体</param>
public Task AddAsync(JewelryMaterial entity)
{
_storeDict.TryAdd(entity.Id, entity);
_codeToIdIndex.TryAdd(entity.MaterialCode, entity.Id);
return Task.CompletedTask;
}
/// <summary>
/// 更新原料实体
/// </summary>
/// <param name="entity">原料实体</param>
public Task UpdateAsync(JewelryMaterial entity)
{
_storeDict[entity.Id] = entity;
return Task.CompletedTask;
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : MemoryUnitOfWork.cs
*/
using StrategyPattern.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Infrastructure.Repositories
{
/// <summary>
/// 内存版本工作单元,内存存储无真实事务,生产替换为EF Core实现
/// </summary>
public class MemoryUnitOfWork : IUnitOfWork
{
/// <summary>
/// 提交变更,内存直接返回成功行数
/// </summary>
/// <param name="cancellationToken">取消令牌</param>
/// <returns>受影响行数</returns>
public Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult(1);
}
}
}
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : CircuitBreakerResilienceExecutor.cs
*/
using Microsoft.Extensions.Logging;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Interfaces;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
namespace StrategyPattern.Infrastructure.Resilience
{
/// <summary>
/// 熔断器+指数退避重试执行器
/// 多线程安全,三态:Closed关闭、Open熔断、HalfOpen半开
/// </summary>
public class CircuitBreakerResilienceExecutor : IResilienceExecutor
{
#region 内部状态定义
/// <summary>
/// 熔断器状态枚举
/// </summary>
private enum CircuitState
{
/// <summary>
/// 关闭,正常通行
/// </summary>
Closed,
/// <summary>
/// 打开,熔断拦截
/// </summary>
Open,
/// <summary>
/// 半开,尝试放行少量请求探测恢复
/// </summary>
HalfOpen
}
#endregion
private readonly ILogger<CircuitBreakerResilienceExecutor> _logger;
/// <summary>
/// 当前熔断器状态,volatile保证多线程可见
/// </summary>
private volatile CircuitState _circuitState;
/// <summary>
/// 失败计数,线程安全集合存储业务维度失败统计
/// </summary>
private readonly ConcurrentDictionary<long, int> _failCounterDict;
/// <summary>
/// 熔断打开的UTC时间戳
/// </summary>
private long _circuitOpenTimeUtcTicks;
/// <summary>
/// 最大失败阈值,超过该次数触发熔断
/// </summary>
private const int MaxFailThreshold = 3;
/// <summary>
/// 熔断冷却时间毫秒,熔断后等待多久进入半开状态
/// </summary>
private const int CircuitCoolDownMs = 5000;
/// <summary>
/// 最大重试次数
/// </summary>
private const int MaxRetryCount = 3;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="logger">日志对象</param>
public CircuitBreakerResilienceExecutor(ILogger<CircuitBreakerResilienceExecutor> logger)
{
_logger = logger;
_circuitState = CircuitState.Closed;
_failCounterDict = new ConcurrentDictionary<long, int>();
_circuitOpenTimeUtcTicks = 0;
}
/// <summary>
/// 带熔断重试包装执行业务委托
/// </summary>
/// <param name="businessFunc">业务异步委托</param>
/// <param name="businessId">业务编号</param>
/// <returns>业务执行结果DTO</returns>
public async Task<BusinessExecuteResultDto> ExecuteWithResilienceAsync(Func<Task<BusinessExecuteResultDto>> businessFunc, long businessId)
{
//检查熔断器状态
await CheckCircuitStateAsync();
if (_circuitState == CircuitState.Open)
{
_logger.LogWarning("熔断器处于打开状态,直接拦截请求 BusinessId:{BusinessId}", businessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = -10001,
Message = "系统熔断器已熔断,当前拒绝执行业务,请稍后重试"
};
}
int currentRetry = 0;
while (true)
{
try
{
var result = await businessFunc.Invoke();
//业务成功,清除该业务失败计数
_failCounterDict.TryRemove(businessId, out _);
if (_circuitState == CircuitState.HalfOpen)
{
//半开状态下请求成功,关闭熔断器恢复正常
_circuitState = CircuitState.Closed;
_logger.LogInformation("熔断器半开探测成功,切换至Closed正常状态");
}
return result;
}
catch (Exception ex)
{
currentRetry++;
int failCount = _failCounterDict.AddOrUpdate(businessId, 1, (k, v) => v + 1);
_logger.LogWarning(ex, "业务执行发生异常,重试次数:{Retry},失败计数:{FailCount},BusinessId:{BusinessId}",
currentRetry, failCount, businessId);
//达到失败阈值,打开熔断器
if (failCount >= MaxFailThreshold)
{
_circuitState = CircuitState.Open;
_circuitOpenTimeUtcTicks = DateTime.UtcNow.Ticks;
_logger.LogError("失败次数达到阈值,熔断器切换Open熔断状态 BusinessId:{BusinessId}", businessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = -10002,
Message = $"连续失败{MaxFailThreshold}次,熔断器触发熔断"
};
}
if (currentRetry >= MaxRetryCount)
{
_logger.LogError("已到达最大重试次数,放弃重试 BusinessId:{BusinessId}", businessId);
return new BusinessExecuteResultDto
{
IsSuccess = false,
ErrorCode = -10003,
Message = $"重试{MaxRetryCount}次全部失败,业务执行失败,异常:{ex.Message}"
};
}
//指数退避休眠
int sleepMs = (int)(Math.Pow(2, currentRetry) * 100);
await Task.Delay(sleepMs);
}
}
}
/// <summary>
/// 检查熔断器状态,处理Open→HalfOpen状态流转
/// </summary>
private Task CheckCircuitStateAsync()
{
if (_circuitState == CircuitState.Open)
{
var nowTicks = DateTime.UtcNow.Ticks;
long elapsedMs = (nowTicks - _circuitOpenTimeUtcTicks) / TimeSpan.TicksPerMillisecond;
if (elapsedMs >= CircuitCoolDownMs)
{
_circuitState = CircuitState.HalfOpen;
_logger.LogInformation("熔断器冷却时间结束,切换为HalfOpen半开探测状态");
}
}
return Task.CompletedTask;
}
}
}
调用:
cs
/*
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:策略模式 Strategy Pattern 行为模式 Behavioral Patterns
# Author : geovindu,Geovin Du 涂聚文.
# IDE : vs2026 c# .net 10
# os : windows 10
# database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j
# Datetime : 2026/08/22 22:16
# User : geovindu
# Product : Visual Studio 2026
# Project : CSharpDesignPattern
# File : StrategyBll.cs
*/
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using StrategyPattern.Application.Dtos;
using StrategyPattern.Application.Services;
using StrategyPattern.Domain.Entities;
using StrategyPattern.Domain.Enums;
using StrategyPattern.Domain.Interfaces;
using StrategyPattern.Domain.ValueObjects;
using StrategyPattern.Infrastructure.Extensions;
using System;
using System.Collections.Generic;
using System.Text;
namespace BLL
{
public class StrategyBll
{
public async Task Demo()
{
//构建主机
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
string logBase = Path.Combine(AppContext.BaseDirectory, "Logs");
services.AddJewelryEnterpriseServices(logBase);
})
.Build();
//获取服务
var scope = host.Services.CreateScope();
var sp = scope.ServiceProvider;
var flowService = sp.GetRequiredService<JewelryFlowApplicationService>();
var materialRepo = sp.GetRequiredService<IJewelryMaterialRepository>();
//初始化测试原料数据
var testMaterial = JewelryMaterial.Create(
id: 10001,
materialCode: "MAT‑GEM‑0001",
materialName: "天然蓝宝石原石",
weightGram: 12.5m,
qualityGrade: MaterialQualityGrade.GradeA,
purchaseCost: Money.CreateCny(28600.00m));
await materialRepo.AddAsync(testMaterial);
//构建业务输入DTO
var businessInput = new JewelryBusinessInputDto
{
BusinessId = 90001,
BusinessPhase = "原料采购核验",
MaterialCode = "MAT‑GEM‑0001",
ProductNo = "PRO‑GEM‑0001",
Quantity = 1,
Amount = 52000.00m,
OperatorId = 8001,
OperatorName = "张工艺师",
OperatorDepartment = "珠宝生产部",
Remark = "蓝宝石首饰完整业务流水线测试",
OccurTime = DateTime.Now
};
Console.WriteLine("==========开始执行珠宝完整业务流水线==========");
var resultList = await flowService.ExecuteFullJewelryPipelineAsync(businessInput);
foreach (var res in resultList)
{
Console.WriteLine($"成功:{res.IsSuccess} | 错误码:{res.ErrorCode} | 消息:{res.Message}");
}
Console.WriteLine("==========流水线执行完毕,按任意键退出==========");
Console.ReadKey();
}
}
}
输出:
