You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为.NET3.5/C#7环境下的WebForm后端代码应用设计模式?

针对你的WebForm代码的设计模式应用与泛型问题解决方案

我来帮你拆解一下怎么把Bridge、Command和Builder模式用到你的WebForm代码里,顺便解决泛型在Repository里的问题——毕竟.NET3.5和C#7的组合虽然不能用最新特性,但这些经典模式完全适配:

一、逐个应用设计模式

1. Builder模式:统一请求的构建与验证逻辑

你现在在Page_Load里分散了DTO创建、字段验证和实体构建的逻辑,用Builder模式可以把这些逻辑抽离到专门的类里,让页面代码更清爽,也方便复用和扩展。

先创建抽象Builder基类,定义通用的构建流程:

public abstract class RequestBuilder<TRequest, TDto> 
    where TRequest : StandardRequest
    where TDto : StandardRequestDTO
{
    // 从Form表单生成DTO
    public abstract TDto CreateDtoFromForm(HttpRequest form);
    // 验证DTO字段合法性
    public abstract void Validate(TDto dto);
    // 从DTO构建请求实体
    public abstract TRequest BuildRequest(TDto dto);
}

然后分别实现标准请求和特殊请求的Builder,把你页面里的验证逻辑移过来:

// 标准请求Builder
public class StandardRequestBuilder : RequestBuilder<StandardRequest, StandardRequestDTO>
{
    public override StandardRequestDTO CreateDtoFromForm(HttpRequest form)
    {
        return new StandardRequestDTO
        {
            Name = form["Name"],
            RequestType = 0
        };
    }

    public override void Validate(StandardRequestDTO dto)
    {
        if (string.IsNullOrWhiteSpace(dto.Name))
            throw new InvalidOperationException("请求名称不能为空");
        // 其他标准请求的验证规则
    }

    public override StandardRequest BuildRequest(StandardRequestDTO dto)
    {
        return StandardRequest.Create(dto);
    }
}

// 特殊请求Builder
public class SpecialRequestBuilder : RequestBuilder<SpecialRequest, SpecialRequestDTO>
{
    public override SpecialRequestDTO CreateDtoFromForm(HttpRequest form)
    {
        return new SpecialRequestDTO
        {
            Name = form["Name"],
            RequestType = 1,
            Desc = form["Desc"]
        };
    }

    public override void Validate(SpecialRequestDTO dto)
    {
        if (string.IsNullOrWhiteSpace(dto.Desc))
            throw new InvalidOperationException("特殊请求描述不能为空");
        // 其他特殊请求的验证规则
    }

    public override SpecialRequest BuildRequest(SpecialRequestDTO dto)
    {
        // 注意:你原来的Create方法写错了,应该返回SpecialRequest实例
        return SpecialRequest.Create(dto);
    }
}

2. Bridge模式:分离请求类型与持久化逻辑

Bridge模式的核心是抽象与实现分离,这里可以把请求实体(抽象部分)和数据库操作(实现部分)拆开,解决你Repository里多个Save方法的冗余问题,同时方便后续新增请求类型。

先定义持久化操作的接口:

public interface IRequestPersistence<T> where T : StandardRequest
{
    void Save(T request);
}

然后为两种请求实现各自的持久化逻辑:

// 标准请求持久化实现
public class StandardRequestPersistence : IRequestPersistence<StandardRequest>
{
    public void Save(StandardRequest request)
    {
        var query = $"INSERT INTO Requests (Name, RequestType) Values(@{nameof(request.Name)}, @{nameof(request.RequestType)})";
        // 你的SQLCommand执行代码放在这里
    }
}

// 特殊请求持久化实现
public class SpecialRequestPersistence : IRequestPersistence<SpecialRequest>
{
    public void Save(SpecialRequest request)
    {
        var query = $"INSERT INTO Requests (Name, RequestType, Desc) VALUES(@{nameof(request.Name)}, @{nameof(request.RequestType)}, @{nameof(request.Desc)})";
        // 你的SQLCommand执行代码放在这里
    }
}

最后改造Repository,用泛型方法统一处理保存,同时通过字典注册不同的持久化实现:

public class Repository
{
    private readonly Dictionary<Type, object> _persistenceHandlers = new Dictionary<Type, object>();

    public Repository()
    {
        // 注册两种请求的持久化处理器
        _persistenceHandlers.Add(typeof(StandardRequest), new StandardRequestPersistence());
        _persistenceHandlers.Add(typeof(SpecialRequest), new SpecialRequestPersistence());
    }

    public void SaveRequest<T>(T request) where T : StandardRequest
    {
        if (_persistenceHandlers.TryGetValue(typeof(T), out var handler))
        {
            // 转换成对应的泛型持久化接口并执行保存
            ((IRequestPersistence<T>)handler).Save(request);
        }
        else
        {
            throw new NotSupportedException($"暂不支持保存{typeof(T).Name}类型的请求");
        }
    }
}

3. Command模式:封装保存操作的执行逻辑

Command模式适合把操作封装成独立的对象,这样你可以轻松添加日志、异常处理、甚至撤销(如果需要的话)等扩展逻辑,而不用修改核心的保存代码。

先定义Command接口:

public interface IRequestCommand
{
    void Execute();
}

然后实现两种请求的保存命令:

// 标准请求保存命令
public class SaveStandardRequestCommand : IRequestCommand
{
    private readonly StandardRequest _request;
    private readonly Repository _repository;

    public SaveStandardRequestCommand(StandardRequest request, Repository repository)
    {
        _request = request;
        _repository = repository;
    }

    public void Execute()
    {
        _repository.SaveRequest(_request);
        // 这里可以添加日志:比如记录标准请求保存成功
    }
}

// 特殊请求保存命令
public class SaveSpecialRequestCommand : IRequestCommand
{
    private readonly SpecialRequest _request;
    private readonly Repository _repository;

    public SaveSpecialRequestCommand(SpecialRequest request, Repository repository)
    {
        _request = request;
        _repository = repository;
    }

    public void Execute()
    {
        _repository.SaveRequest(_request);
        // 这里可以添加日志:比如记录特殊请求保存成功
    }
}

再写一个命令执行器,统一处理命令的执行和异常:

public class CommandInvoker
{
    public void ExecuteCommand(IRequestCommand command)
    {
        try
        {
            command.Execute();
        }
        catch (Exception ex)
        {
            // 统一记录异常日志
            throw new InvalidOperationException("保存请求失败", ex);
        }
    }
}

二、改造后的Page_Load代码

现在把上面的模式整合起来,你的页面后端代码会变得非常简洁:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) return;

    string requestTypeStr = Request.Form["requestTypeStr"];
    if (string.IsNullOrEmpty(requestTypeStr) || !int.TryParse(requestTypeStr, out int requestType))
        return;

    IRequestCommand command = null;
    switch (requestType)
    {
        case 0:
            var stdBuilder = new StandardRequestBuilder();
            var stdDto = stdBuilder.CreateDtoFromForm(Request);
            stdBuilder.Validate(stdDto);
            var stdRequest = stdBuilder.BuildRequest(stdDto);
            command = new SaveStandardRequestCommand(stdRequest, _repository);
            break;
        case 1:
            var specialBuilder = new SpecialRequestBuilder();
            var specialDto = specialBuilder.CreateDtoFromForm(Request);
            specialBuilder.Validate(specialDto);
            var specialRequest = specialBuilder.BuildRequest(specialDto);
            command = new SaveSpecialRequestCommand(specialRequest, _repository);
            break;
        default:
            return;
    }

    var invoker = new CommandInvoker();
    invoker.ExecuteCommand(command);
}

三、关于泛型的问题说明

你之前在Repository里调用泛型方法遇到困难,主要是因为原来的Repository没有抽象出持久化逻辑。现在通过Bridge模式的改造,我们用SaveRequest<T>泛型方法统一处理,同时通过字典注册不同类型的持久化处理器,完美适配.NET3.5的泛型支持——这个版本对泛型的基础特性支持是完全没问题的,C#7的语法也可以正常使用。

另外,注意修正你原来SpecialRequest.Create方法的错误:原来的代码返回了SpecialRequestDTO实例,应该返回SpecialRequest,不然会出现类型错误。

内容的提问来源于stack exchange,提问作者Kristianne Nerona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:32:04