CSharp: Flyweight Pattern

项目结构:

cs 复制代码
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IStaffFlyweight.cs
 */
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Core.Abstractions
{
    /// <summary>
    /// 享元抽象接口:珠宝行业岗位工作人员
    /// 内部状态:岗位名称、岗位职责、所属部门(可共享,常驻内存)
    /// 外部状态:业务流水号、业务描述(每次执行动态传入,不存入享元对象)
    /// </summary>
    public interface IStaffFlyweight
    {
        /// <summary>
        /// 执行岗位业务操作
        /// </summary>
        /// <param name="logger">日志实例</param>
        /// <param name="businessNo">业务流水号【外部状态】</param>
        /// <param name="businessContext">业务上下文描述【外部状态】</param>
        void ExecuteWork(ILogger logger, string businessNo, string businessContext);
 
        /// <summary>
        /// 获取岗位名称(内部共享状态)
        /// </summary>
        string GetPositionName();
 
        /// <summary>
        /// 获取岗位职责(内部共享状态)
        /// </summary>
        string GetDuty();
    }
}
 
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IStaffFlyweightFactory.cs
 */
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Core.Abstractions
{
    /// <summary>
    /// 享元工厂接口:负责创建、缓存岗位享元实例
    /// 保证同一岗位全局只存在唯一实例,实现对象复用,降低GC压力
    /// </summary>
    public interface IStaffFlyweightFactory
    {
        /// <summary>
        /// 根据岗位名称获取享元对象
        /// </summary>
        /// <param name="positionName">岗位名称</param>
        /// <returns>岗位享元实例</returns>
        IStaffFlyweight GetStaffFlyweight(string positionName);
 
        /// <summary>
        /// 获取当前缓存享元数量
        /// </summary>
        int GetCacheCount();
 
        /// <summary>
        /// 预加载珠宝全部业务岗位享元
        /// </summary>
        void PreloadAllJewelryPositions();
    }
}
 
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : PositionDutyModel.cs
 */
 
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Core.Models
{
    /// <summary>
    /// 岗位基础信息模型,用于初始化享元内部状态
    /// </summary>
    public class PositionDutyModel
    {
        /// <summary>
        /// 岗位名称
        /// </summary>
        public string PositionName { get; set; } = string.Empty;
 
        /// <summary>
        /// 所属部门
        /// </summary>
        public string Department { get; set; } = string.Empty;
 
        /// <summary>
        /// 岗位职责描述
        /// </summary>
        public string Duty { get; set; } = string.Empty;
    }
}
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryStaffFlyweightFactory.cs
 */
 
using FlyweightPattern.Core.Abstractions;
using FlyweightPattern.Core.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Infrastructure.Flyweight
{
    /// <summary>
    /// 珠宝岗位享元工厂实现
    /// ConcurrentDictionary 保证多线程并发安全缓存
    /// </summary>
    public class JewelryStaffFlyweightFactory : IStaffFlyweightFactory
    {
        private readonly ILogger<JewelryStaffFlyweightFactory> _logger;
 
        /// <summary>
        /// 享元对象缓存池,线程安全字典
        /// Key:岗位名称,Value:岗位享元实例
        /// </summary>
        private readonly ConcurrentDictionary<string, IStaffFlyweight> _flyweightPool = new();
 
        public JewelryStaffFlyweightFactory(ILogger<JewelryStaffFlyweightFactory> logger)
        {
            _logger = logger;
            PreloadAllJewelryPositions();
        }
 
        /// <summary>
        /// 获取岗位享元,存在直接返回,不存在抛出异常
        /// </summary>
        public IStaffFlyweight GetStaffFlyweight(string positionName)
        {
            if (string.IsNullOrWhiteSpace(positionName))
                throw new ArgumentNullException(nameof(positionName));
 
            if (_flyweightPool.TryGetValue(positionName, out var fly))
            {
                _logger.LogDebug("命中享元缓存,岗位:{Position}", positionName);
                return fly;
            }
 
            throw new KeyNotFoundException($"未预加载岗位【{positionName}】,请检查岗位配置");
        }
 
        /// <summary>
        /// 获取缓存享元总数
        /// </summary>
        public int GetCacheCount()
        {
            return _flyweightPool.Count;
        }
 
        /// <summary>
        /// 预加载珠宝全业务岗位享元
        /// </summary>
        public void PreloadAllJewelryPositions()
        {
            _logger.LogInformation("开始预加载珠宝行业所有业务岗位享元对象");
 
            List<PositionDutyModel> positionList = new List<PositionDutyModel>()
        {
            new PositionDutyModel{PositionName="原料采购核验",Department="供应链部",Duty="贵金属/宝石原料采购、入库质检、原料成色核验、供应商对账"},
            new PositionDutyModel{PositionName="设计制图",Department="研发设计部",Duty="首饰款式创意、CAD制图、3D建模、效果图输出、工艺图纸"},
            new PositionDutyModel{PositionName="加工生产",Department="生产车间",Duty="失蜡铸造、执模、镶石、抛光、电镀、半成品加工"},
            new PositionDutyModel{PositionName="质检",Department="品控部",Duty="成色检测、宝石分级、外观瑕疵检验、尺寸校验、合格判定"},
            new PositionDutyModel{PositionName="包装",Department="仓储部",Duty="首饰清洁、礼盒封装、标签粘贴、产品入库分拣"},
            new PositionDutyModel{PositionName="物流",Department="仓储部",Duty="订单打包、快递对接、物流跟踪、货品出入库管控"},
            new PositionDutyModel{PositionName="财务",Department="财务部",Duty="成本核算、应收应付、开票、工资核算、资金管理"},
            new PositionDutyModel{PositionName="营销推广",Department="市场部",Duty="线上线下推广、直播运营、活动策划、品牌宣传"},
            new PositionDutyModel{PositionName="业务",Department="销售部",Duty="客户接待、订单洽谈、零售批发、售后沟通"},
            new PositionDutyModel{PositionName="人事行政",Department="行政人事部",Duty="招聘、考勤、制度管理、后勤、办公物资管理"},
            new PositionDutyModel{PositionName="IT",Department="信息部",Duty="系统运维、服务器维护、软件故障处理、数据保障"},
            new PositionDutyModel{PositionName="培训",Department="培训部",Duty="员工技能培训、销售话术培训、工艺知识教学"}
        };
 
            foreach (var item in positionList)
            {
                var flyweight = new StaffFlyweight(item.PositionName, item.Department, item.Duty);
                _flyweightPool.TryAdd(item.PositionName, flyweight);
                _logger.LogDebug("岗位享元加载完成:{Position}", item.PositionName);
            }
 
            _logger.LogInformation("岗位享元预加载完成,缓存岗位总数:{Count}", _flyweightPool.Count);
        }
    }
}
 
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : StaffFlyweight.cs
 */
using FlyweightPattern.Core.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Infrastructure.Flyweight
{
    /// <summary>
    /// 具体享元对象:珠宝企业岗位人员
    /// 内部状态不可变,对象全局复用;外部状态通过方法参数传入
    /// </summary>
    public class StaffFlyweight : IStaffFlyweight
    {
        /// <summary>
        /// 岗位名称 - 内部状态(不可变)
        /// </summary>
        private readonly string _positionName;
 
        /// <summary>
        /// 所属部门 - 内部状态(不可变)
        /// </summary>
        private readonly string _department;
 
        /// <summary>
        /// 岗位职责 - 内部状态(不可变)
        /// </summary>
        private readonly string _duty;
 
        /// <summary>
        /// 构造函数初始化固定内部状态
        /// </summary>
        /// <param name="positionName">岗位名称</param>
        /// <param name="department">部门名称</param>
        /// <param name="duty">岗位职责</param>
        public StaffFlyweight(string positionName, string department, string duty)
        {
            _positionName = positionName;
            _department = department;
            _duty = duty;
        }
 
        /// <summary>
        /// 执行岗位业务,外部状态由调用方传入
        /// </summary>
        public void ExecuteWork(ILogger logger, string businessNo, string businessContext)
        {
            logger.LogInformation(
                "[业务单号:{BusinessNo}]【{Department}-{Position}】开始处理业务:{Context},岗位职责:{Duty}",
                businessNo, _department, _positionName, businessContext, _duty);
 
            SimulateBusinessWork(logger, businessNo);
        }
 
        /// <summary>
        /// 模拟岗位业务执行逻辑
        /// </summary>
        private void SimulateBusinessWork(ILogger logger, string businessNo)
        {
            var random = Random.Shared;
            int costMs = random.Next(50, 200);
            Thread.Sleep(costMs);
 
            if (random.NextDouble() < 0.08)
            {
                logger.LogWarning("[业务单号:{BusinessNo}]【{Position}】业务存在轻微异常风险", businessNo, _positionName);
            }
            if (random.NextDouble() < 0.03)
            {
                logger.LogError("[业务单号:{BusinessNo}]【{Position}】业务处理出现临时故障", businessNo, _positionName);
            }
 
            logger.LogDebug("[业务单号:{BusinessNo}]【{Position}】处理耗时{CostMs}ms", businessNo, _positionName, costMs);
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public string GetPositionName()
        {
            return _positionName;
        }
 
        public string GetDuty()
        {
            return _duty;
        }
    }
}
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : LoggingConfiguration.cs
 */
 
using Karambolo.Extensions.Logging.File;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
 
namespace FlyweightPattern.Infrastructure.Logging
{
    public static class LoggingConfiguration
    {
        public static void ConfigureLogger(ILoggingBuilder loggingBuilder)
        {
            loggingBuilder.ClearProviders();
 
            loggingBuilder.AddConsole(options =>
            {
                options.FormatterName = "Simple";
            });
 
            loggingBuilder.AddFile(fileBuilder =>
            {
                fileBuilder.RootPath = Directory.GetCurrentDirectory();
                string todayDate = DateTime.Now.ToString("yyyy-MM-dd");
                string logDir = Path.Combine(fileBuilder.RootPath, "Logs", todayDate);
                Directory.CreateDirectory(logDir);
 
                fileBuilder.Files = new[]
                {
                    new LogFileOptions
                    {
                        Path = $"Logs/{todayDate}/app-debug.log",
                        MaxFileSize = 50 * 1024 * 1024,
                        MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Debug },
                        IncludeScopes = true
                    },
                    new LogFileOptions
                    {
                        Path = $"Logs/{todayDate}/app-info.log",
                        MaxFileSize = 50 * 1024 * 1024,
                        MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Information },
                        IncludeScopes = true
                    },
                    new LogFileOptions
                    {
                        Path = $"Logs/{todayDate}/app-warn.log",
                        MaxFileSize = 50 * 1024 * 1024,
                        MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Warning },
                        IncludeScopes = true
                    },
                    new LogFileOptions
                    {
                        Path = $"Logs/{todayDate}/app-error.log",
                        MaxFileSize = 50 * 1024 * 1024,
                        MinLevel = new Dictionary<string, LogLevel> { [""] = LogLevel.Error },
                        IncludeScopes = true
                    }
                };
            });
 
            loggingBuilder.SetMinimumLevel(LogLevel.Debug);
        }
    }
}
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : ScheduleStartupService.cs
 */
 
using FlyweightPattern.Scheduler.Jobs;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Core;
using Quartz.Impl;
using Quartz.Util;
using Quartz.Job;
using Quartz.Impl.Calendar;
using Quartz.Impl.Matchers;
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Scheduler.HostedServices
{
    /// <summary>
    /// 调度初始化托管服务
    /// 程序启动注册触发器;程序关闭优雅停止调度器
    /// </summary>
    public class ScheduleStartupService : IHostedService
    {
        private readonly ILogger<ScheduleStartupService> _logger;
        private readonly ISchedulerFactory _schedulerFactory;
        private IScheduler? _scheduler;
        /// <summary>
        ///
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="schedulerFactory"></param>
        public ScheduleStartupService(ILogger<ScheduleStartupService> logger, ISchedulerFactory schedulerFactory)
        {
            _logger = logger;
            _schedulerFactory = schedulerFactory;
        }
 
        /// <summary>
        /// Host启动时执行
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("开始初始化Quartz定时调度器");
            _scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
 
            // 任务1:间隔30秒循环执行
            var normalJobKey = new JobKey("JewelryNormalFlowJob", "JewelryGroup");
            IJobDetail normalJob = JobBuilder.Create<JewelryScheduleJob>()
                .WithIdentity(normalJobKey)
                .StoreDurably()
                .Build();
            normalJob.JobDataMap.Put("BusinessNo", "JH-SCHED-001");
            normalJob.JobDataMap.Put("OrderTitle", "定时自动-日常首饰生产订单");
 
            ITrigger normalTrigger = TriggerBuilder.Create()
                .WithIdentity("NormalFlowTrigger", "JewelryGroup")
                .ForJob(normalJobKey)
                .StartNow()
                .WithSimpleSchedule(x => x.WithIntervalInSeconds(30).RepeatForever())
                .Build();
 
            // 任务2:Cron每日凌晨2点批量执行10单并发
            var batchJobKey = new JobKey("JewelryBatchJob", "JewelryGroup");
            IJobDetail batchJob = JobBuilder.Create<JewelryScheduleJob>()
                .WithIdentity(batchJobKey)
                .StoreDurably()
                .Build();
            batchJob.JobDataMap.Put("ConcurrentOrderCount", 10);
 
            ITrigger batchTrigger = TriggerBuilder.Create()
                .WithIdentity("BatchFlowTrigger", "JewelryGroup")
                .ForJob(batchJobKey)
                .StartNow()
                .WithCronSchedule("0 0 2 * * ?")
                .Build();
 
            await _scheduler.AddJob(normalJob, false, cancellationToken);
            await _scheduler.ScheduleJob(normalTrigger, cancellationToken);
            await _scheduler.AddJob(batchJob, false, cancellationToken);
            await _scheduler.ScheduleJob(batchTrigger, cancellationToken);
 
            await _scheduler.Start(cancellationToken);
            _logger.LogInformation("Quartz调度器启动成功,定时任务已加载");
        }
 
        /// <summary>
        /// Host停止,优雅关闭调度器
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task StopAsync(CancellationToken cancellationToken)
        {
            if (_scheduler != null && !_scheduler.IsShutdown)
            {
                _logger.LogInformation("准备停止Quartz调度器,等待运行中任务完成...");
                await _scheduler.Shutdown(waitForJobsToComplete: true, cancellationToken);
                _logger.LogInformation("Quartz调度器已正常关闭");
            }
        }
    }
}
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryScheduleJob.cs
 */
 
using FlyweightPattern.Business.Abstractions;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Core;
using Quartz.Impl;
using Quartz.Util;
using Quartz.Job;
using Quartz.Impl.Calendar;
using Quartz.Impl.Matchers;
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Scheduler.Jobs
{
    /// <summary>
    /// 珠宝业务定时任务Job
    /// Quartz托管任务,支持DI注入依赖
    /// </summary>
    public class JewelryScheduleJob : IJob
    {
        private readonly ILogger<JewelryScheduleJob> _logger;
        private readonly IJewelryBusinessScheduler _businessScheduler;
 
        public JewelryScheduleJob(ILogger<JewelryScheduleJob> logger, IJewelryBusinessScheduler businessScheduler)
        {
            _logger = logger;
            _businessScheduler = businessScheduler;
        }
 
        /// <summary>
        /// Quartz任务执行入口
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                JobKey jobKey = context.JobDetail.Key;
                _logger.LogInformation("【定时任务触发】任务Key:{JobKey}", context.JobDetail.Key);
 
                var businessNo = context.JobDetail.JobDataMap.GetString("BusinessNo");
                var orderTitle = context.JobDetail.JobDataMap.GetString("OrderTitle");
                int concurrentCount;
                context.JobDetail.JobDataMap.TryGetInt("ConcurrentOrderCount", out concurrentCount);
 
                if (!string.IsNullOrEmpty(businessNo) && !string.IsNullOrEmpty(orderTitle))
                {
                    await _businessScheduler.RunFullJewelryBusinessFlowAsync(businessNo, orderTitle);
                }
                else if (concurrentCount > 0)
                {
                    await _businessScheduler.RunMultiOrderConcurrentAsync(concurrentCount);
                }
                else
                {
                    _logger.LogWarning("定时任务未传入有效业务参数,跳过业务执行");
                }
 
                _logger.LogInformation("【定时任务执行完成】任务Key:{JobKey}", context.JobDetail.Key);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "【定时任务执行异常】任务Key:{JobKey}", context.JobDetail.Key);
                throw;
            }
        }
    }
}
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : IJewelryBusinessScheduler.cs
 */
 
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Business.Abstractions
{
    /// <summary>
    /// 珠宝业务调度器抽象
    /// 负责驱动整条珠宝业务流水线执行
    /// </summary>
    public interface IJewelryBusinessScheduler
    {
        /// <summary>
        /// 执行单条订单完整业务流程
        /// </summary>
        /// <param name="businessNo">业务流水号</param>
        /// <param name="orderTitle">订单名称</param>
        Task RunFullJewelryBusinessFlowAsync(string businessNo, string orderTitle);
 
        /// <summary>
        /// 并发批量执行多条订单
        /// </summary>
        /// <param name="orderCount">模拟订单数量</param>
        Task RunMultiOrderConcurrentAsync(int orderCount);
    }
}
 
 
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:结构型模式 Structural Patterns 享元模式Flyweight Pattern
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : JewelryBusinessScheduler.cs
 */
using FlyweightPattern.Business.Abstractions;
using FlyweightPattern.Core.Abstractions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
 
namespace FlyweightPattern.Business.Implementations
{
    /// <summary>
    /// 珠宝业务流水线调度实现
    /// 串联全流程岗位,通过享元工厂复用岗位实例
    /// </summary>
    public class JewelryBusinessScheduler : IJewelryBusinessScheduler
    {
        private readonly ILogger<JewelryBusinessScheduler> _logger;
        private readonly IStaffFlyweightFactory _flyweightFactory;
 
        public JewelryBusinessScheduler(ILogger<JewelryBusinessScheduler> logger, IStaffFlyweightFactory flyweightFactory)
        {
            _logger = logger;
            _flyweightFactory = flyweightFactory;
        }
 
        /// <summary>
        /// 单订单完整业务流水线
        /// </summary>
        public async Task RunFullJewelryBusinessFlowAsync(string businessNo, string orderTitle)
        {
            _logger.LogInformation("=====启动珠宝完整业务流程,单号:{BusinessNo},订单:{OrderTitle}=====", businessNo, orderTitle);
 
            List<string> positionSequence = new List<string>()
        {
            "原料采购核验",
            "设计制图",
            "加工生产",
            "质检",
            "包装",
            "物流",
            "财务",
            "营销推广",
            "业务",
            "人事行政",
            "IT",
            "培训"
        };
 
            foreach (var position in positionSequence)
            {
                var staff = _flyweightFactory.GetStaffFlyweight(position);
                staff.ExecuteWork(_logger, businessNo, $"订单[{orderTitle}]流程处理");
                await Task.Delay(30);
            }
 
            _logger.LogInformation("=====珠宝业务流程全部执行完成,单号:{BusinessNo}=====", businessNo);
        }
 
        /// <summary>
        /// 多订单并发执行,测试高并发场景
        /// </summary>
        public async Task RunMultiOrderConcurrentAsync(int orderCount)
        {
            _logger.LogInformation("开始并发模拟{OrderCount}条珠宝订单业务流程", orderCount);
            List<Task> taskList = new List<Task>();
 
            for (int i = 1; i <= orderCount; i++)
            {
                string orderNo = $"JH{DateTime.Now:yyyyMMdd}{i:D06}";
                string orderName = $"定制首饰订单-{i}号";
                taskList.Add(RunFullJewelryBusinessFlowAsync(orderNo, orderName));
            }
 
            await Task.WhenAll(taskList);
            _logger.LogInformation("全部并发订单处理完毕");
        }
    }
}

调用:

cs 复制代码
/*
 # encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:享元模式 Flyweight Pattern演示业务层
# 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/07/04 22:16
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : FlyweightBll.cs
 */
 
using FlyweightPattern.Business.Abstractions;
using FlyweightPattern.Business.Implementations;
using FlyweightPattern.Core.Abstractions;
using FlyweightPattern.Infrastructure.Flyweight;
using FlyweightPattern.Infrastructure.Logging;
using FlyweightPattern.Scheduler.HostedServices;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Core;
using Quartz.Impl;
using Quartz.Util;
using Quartz.Job;
using Quartz.Impl.Calendar;
using Quartz.Impl.Matchers;
using System;
using System.Collections.Generic;
using System.Text;
 
 
namespace BLL
{
 
 
    public class FlyweightBll
    {
 
 
        //Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        public async void Demo()
        {
 
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
 
            var host = Host.CreateDefaultBuilder()
                .ConfigureLogging((context, loggingBuilder) =>
                {
                    LoggingConfiguration.ConfigureLogger(loggingBuilder);
                })
                .ConfigureServices((context, services) =>
                {
                    // Core & Infrastructure
                    services.AddSingleton<IStaffFlyweightFactory, JewelryStaffFlyweightFactory>();
 
                    // Business Layer
                    services.AddTransient<IJewelryBusinessScheduler, JewelryBusinessScheduler>();
 
                    // Quartz 定时调度
                    services.AddQuartz(q =>
                    {
                        q.UseMicrosoftDependencyInjectionJobFactory();
                        q.UseInMemoryStore();
                    });
                    services.AddQuartzHostedService(opt =>   //AddQuartzHostedService
                    {
                        opt.WaitForJobsToComplete = true;   //WaitForJobsToComplete
                    });
                    services.AddHostedService<ScheduleStartupService>();
                })
                .Build();
 
            // 可选:手动测试执行
            //var businessScheduler = host.Services.GetRequiredService<IJewelryBusinessScheduler>();
            //await businessScheduler.RunFullJewelryBusinessFlowAsync("JH20260721001", "18K金钻石戒指订单");
            //await businessScheduler.RunMultiOrderConcurrentAsync(5);
 
            await host.RunAsync();
 
        }
    }
}

输出:

相关推荐
weixin_446260852 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
人邮异步社区2 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大3 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai3 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
用户8356290780513 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
用户9931441579843 小时前
微服务框架中获取用户信息
后端
এ慕ོ冬℘゜3 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa3 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio
一次旅行4 小时前
Python+大模型端到端自动化日报系统
开发语言·python·自动化