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

如何在JSON Schema验证器代码中应用开闭原则?

重构JSON Schema验证器以遵循开闭原则

问题分析

你当前的代码存在两个核心问题,直接违反开闭原则:

  1. 每次新增一个topic,都要修改IsValidJson里的switch分支,还要修改RestoreJsonSchemas的加载逻辑,对修改开放,不符合开闭原则的要求
  2. JsonSchemaValidator类同时承担了schema加载、验证逻辑分发、具体验证三个职责,违反单一职责原则

下面给出基于策略模式+接口抽象的重构方案,完美契合开闭原则,同时让代码更易扩展和维护。

重构步骤

1. 抽象验证器接口

把每个topic对应的schema加载和验证逻辑抽象成统一接口,让所有具体验证器遵循相同契约:

public interface IJsonSchemaValidator
{
    // 对应topic标识
    string Topic { get; }
    // 加载schema的方法
    void LoadSchema();
    // 验证JSON的方法
    bool Validate(string json);
}

2. 实现具体验证器类

针对每个topic单独创建验证器类,把该topic的schema路径、加载逻辑、验证逻辑完全封装进去。比如connection对应的验证器:

public class ConnectionJsonValidator : IJsonSchemaValidator
{
    private const string _schemaPath = "JsonSchemas\\schemaConnection.txt";
    private JSchema _schema;

    public string Topic => "connection";

    public void LoadSchema()
    {
        try
        {
            var schemaContent = File.ReadAllText(_schemaPath);
            _schema = JSchema.Parse(schemaContent);
        }
        catch (Exception ex)
        {
            // 可添加日志记录,或根据业务需求处理异常
            throw;
        }
    }

    public bool Validate(string json)
    {
        if (string.IsNullOrWhiteSpace(json))
            return false;

        try
        {
            var jsonObj = JObject.Parse(json);
            return jsonObj.IsValid(_schema);
        }
        catch
        {
            // 处理JSON解析或验证错误
            return false;
        }
    }
}

以后新增topic,只需要新建一个实现IJsonSchemaValidator的类,完全不用修改现有代码。

3. 实现验证器管理器

创建管理器类,负责管理所有验证器、批量加载schema、分发验证请求:

public class JsonSchemaValidationManager
{
    private readonly Dictionary<string, IJsonSchemaValidator> _validators = new();

    // 构造函数注入所有验证器,便于扩展
    public JsonSchemaValidationManager(IEnumerable<IJsonSchemaValidator> validators)
    {
        foreach (var validator in validators)
        {
            _validators.Add(validator.Topic, validator);
        }
    }

    public void RestoreAllSchemas()
    {
        foreach (var validator in _validators.Values)
        {
            validator.LoadSchema();
        }
        Console.WriteLine("Restored all JSON schemas.");
    }

    public bool IsValidJson(string topic, string json)
    {
        if (string.IsNullOrWhiteSpace(topic) || string.IsNullOrWhiteSpace(json))
            return false;

        if (_validators.TryGetValue(topic, out var validator))
        {
            return validator.Validate(json);
        }

        // 未知topic的处理逻辑,比如返回false或抛出异常
        return false;
    }
}

4. 使用方式

在应用初始化时,注册所有验证器(可手动注册,也可用依赖注入框架自动扫描):

// 手动注册示例
var validators = new List<IJsonSchemaValidator>
{
    new ConnectionJsonValidator(),
    // 新增其他验证器直接加在这里即可,比如new UserJsonValidator()
};

var validationManager = new JsonSchemaValidationManager(validators);
validationManager.RestoreAllSchemas();

// 验证调用
bool isConnectionValid = validationManager.IsValidJson("connection", "{\"name\":\"test\"}");

为什么符合开闭原则?

  • 对扩展开放:新增任何topic,只需要新增一个实现IJsonSchemaValidator的类,不需要修改现有代码
  • 对修改关闭:现有验证器和管理器的代码无需改动,避免引入新bug
  • 同时拆分了职责,每个类只做一件事,代码可读性和可维护性大幅提升

可选优化

  • 用依赖注入框架(比如Microsoft DI)自动扫描所有IJsonSchemaValidator实现类,省去手动注册的麻烦
  • 添加schema缓存逻辑,避免重复加载文件
  • 统一异常处理和日志记录,方便排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:40:37