策略模式(Strategy Pattern)+ 模板方法模式(Template Method Pattern)的组合使用

发布于:2025-07-24 ⋅ 阅读:(20) ⋅ 点赞:(0)
using Microsoft.Extensions.DependencyInjection;

namespace ConsoleApp9
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            // 创建并配置依赖注入容器
            var _serviceProvider = new ServiceCollection()
                .AddScoped<IStrategyService, CarStrategyService>()  // 注册 Car Travel 策略
                .AddScoped<IStrategyService, PublicTransportationStrategyService>() // 注册 Public Transport 策略
                .AddScoped<IStrategyService, BicycleStrategyService>() // 注册 Bicycle 策略
                .BuildServiceProvider();

            //我改写的
            IStrategyService _strategyService;
            _strategyService = new CarStrategyService();
            var result = _strategyService.ReplaceDefaultReference("Hello [身份证] 祝您 [出行方式] 愉快");

            Console.WriteLine(result);

            Console.WriteLine();

            IStrategyService _strategyService_2;

            //客户选择出行方式为开车
            var TravleMode = CTravelFlag.Bicycle;
            using (var scope = _serviceProvider.CreateScope())
            {
                _strategyService_2 = scope.ServiceProvider.GetService<IEnumerable<IStrategyService>>().FirstOrDefault(s => s.TravelFlag == TravleMode);
                if (_strategyService_2 == null)
                {
                    Console.WriteLine("No matching travel strategy found.");
                    return;
                }
                var result_2 = _strategyService_2.ReplaceDefaultReference("Hello [身份证] 祝您 [出行方式] 愉快_2");
                Console.WriteLine(result_2);
            }
        }
    }

    public interface IStrategyService
    {
        CTravelFlag TravelFlag { get; }
        Task<string> ReplaceReference(string content);
        string ReplaceDefaultReference(string content);
    }

    [Flags]
    public enum CTravelFlag
    {
        None = 0,
        Car = 1,
        PublicTransportation = 1 << 1,      //2
        Bicycle = 1 << 2,                   //4
        Walking = 1 << 3,                   //8
        Taxi = 1 << 4,                      //16
        Train = 1 << 5,                     //32

        All = Car | PublicTransportation | Bicycle | Walking | Taxi | Train,
    }

    public abstract class StrategyService : IStrategyService
    {
        public virtual CTravelFlag TravelFlag => CTravelFlag.All;

        public virtual string ReplaceDefaultReference(string content)
        {
            //throw new NotImplementedException();
            Console.WriteLine("所有出行方式都得带身份证和钱包");
            content = content.Replace("[身份证]", "王先生");
            return content;
        }

        public virtual Task<string> ReplaceReference(string content)
        {
            throw new NotImplementedException();
        }
    }

    public class CarStrategyService : StrategyService
    {
        public override CTravelFlag TravelFlag => CTravelFlag.Car;
        public override string ReplaceDefaultReference(string content)
        {
            Console.WriteLine("客户选择了开车出行");
            content = base.ReplaceDefaultReference(content);
            return content.Replace("[出行方式]", "驾车出行");
        }
        public override async Task<string> ReplaceReference(string content)
        {
            throw new NotImplementedException();
        }
    }
    public class PublicTransportationStrategyService : StrategyService
    {
        public override CTravelFlag TravelFlag => CTravelFlag.PublicTransportation;
        public override string ReplaceDefaultReference(string content)
        {
            Console.WriteLine("客户选择了公共交通");
            content = base.ReplaceDefaultReference(content);
            return content.Replace("[出行方式]", "公共交通出行");
        }
        public override async Task<string> ReplaceReference(string content)
        {
            throw new NotImplementedException();
        }
    }
    public class BicycleStrategyService : StrategyService
    {
        public override CTravelFlag TravelFlag => CTravelFlag.Bicycle;
        public override string ReplaceDefaultReference(string content)
        {
            Console.WriteLine("客户选择了自行车");
            content = base.ReplaceDefaultReference(content);
            return content.Replace("[出行方式]", "自行车出行");
        }
        public override async Task<string> ReplaceReference(string content)
        {
            throw new NotImplementedException();
        }
    }

}

输出:

Hello, World!
客户选择了开车出行
所有出行方式都得带身份证和钱包
Hello 王先生 祝您 驾车出行 愉快

客户选择了自行车
所有出行方式都得带身份证和钱包
Hello 王先生 祝您 自行车出行 愉快_2

🧩 一、核心设计模式分析

✅ 1. 策略模式(Strategy Pattern)

定义:
策略模式定义了一系列算法或行为,将每个算法封装起来,并使它们可以互相替换。此模式让算法独立于使用它的客户端独立变化。

在你的代码中的体现:

角色 对应代码
抽象策略接口 IStrategyService
具体策略实现

CarStrategyService

PublicTransportationStrategyService

BicycleStrategyService

上下文(调用者) Main 方法中使用接口调用
IStrategyService _strategyService;
_strategyService = new CarStrategyService();

 👉 这段代码就是典型的策略模式应用 —— 在运行时可以替换不同的策略类来完成不同的行为(比如不同的证书替换策略)。


✅ 2. 模板方法模式(Template Method Pattern)

定义:
模板方法模式在一个抽象类中定义一个操作的骨架,将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

在你的代码中的体现:

角色 对应代码
抽象父类 StrategyService
钩子方法或默认实现 ReplaceDefaultReference / ReplaceReference
public abstract class StrategyService : IStrategyService
{
    public virtual CTravelFlag TravelFlag => CTravelFlag.All;

    public virtual string ReplaceDefaultReference(string content)
    {
        //throw new NotImplementedException();
        Console.WriteLine("所有出行方式都得带身份证和钱包");
        content = content.Replace("[身份证]", "王先生");
        return content;
    }

    public virtual Task<string> ReplaceReference(string content)
    {
        throw new NotImplementedException();
    }
}

 子类 CarStrategyService可以覆盖虚方法,自定义某些步骤。


✅ 总结

你的代码体现的是:

  • 策略模式(Strategy Pattern):可替换的出行方式处理策略

  • 模板方法模式(Template Method Pattern):父类提供默认实现或结构,子类定制行为

这是一种常见的组合设计,用于提供灵活可扩展的行为策略选择 + 统一结构规范的场景。


仅供学习参考,如有侵权联系我删除。 


网站公告

今日签到

点亮在社区的每一天
去签到