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

基于装饰器模式的传感器架构中,如何查找特定类型的装饰器?

基于装饰器模式的多传感器架构实现方案

看起来你这个思路完全没问题啊!针对多传感器的不同行为组合需求,装饰器模式简直是量身定做的——它既能让你动态给基础传感器叠加功能,又能避免传统继承带来的类爆炸问题,完美适配你说的「装饰器本身也属于传感器、可互相包装」的架构要求。

下面我给你拆解一下具体的实现步骤,用代码示例帮你理清楚逻辑:

1. 定义核心传感器接口

首先得有一个所有传感器(包括装饰器)都要遵守的契约,保证装饰和被装饰的对象行为统一:

public interface IMeasureSensor
{
    // 核心测量方法,所有传感器都必须实现
    double TakeMeasurement();
    // 获取传感器描述信息,方便跟踪组合后的功能
    string GetSensorInfo();
}

2. 实现基础传感器类

这些是最底层的「原始」传感器,只负责最基础的测量功能,没有额外附加行为:

// 基础温度传感器
public class TemperatureSensor : IMeasureSensor
{
    public double TakeMeasurement()
    {
        // 模拟硬件读数逻辑,实际项目替换为真实硬件调用
        return new Random().NextDouble() * 50; // 输出0-50℃的随机值
    }

    public string GetSensorInfo()
    {
        return "基础温度传感器";
    }
}

// 基础湿度传感器
public class HumiditySensor : IMeasureSensor
{
    public double TakeMeasurement()
    {
        return new Random().NextDouble() * 100; // 输出0-100%RH的随机值
    }

    public string GetSensorInfo()
    {
        return "基础湿度传感器";
    }
}

3. 编写装饰器基类

为了避免每个具体装饰器重复写「持有被装饰对象」的逻辑,我们先做一个抽象基类,它本身实现IMeasureSensor,同时封装通用的转发逻辑:

public abstract class SensorDecorator : IMeasureSensor
{
    // 持有被装饰的传感器实例
    protected readonly IMeasureSensor _wrappedSensor;

    public SensorDecorator(IMeasureSensor wrappedSensor)
    {
        _wrappedSensor = wrappedSensor ?? throw new ArgumentNullException(nameof(wrappedSensor));
    }

    // 默认把调用转发给被装饰的传感器,子类可按需重写
    public virtual double TakeMeasurement()
    {
        return _wrappedSensor.TakeMeasurement();
    }

    public virtual string GetSensorInfo()
    {
        return _wrappedSensor.GetSensorInfo();
    }
}

这个基类帮你省掉重复代码,让每个具体装饰器只需要专注于自己要添加的功能就行。

4. 实现具体功能装饰器

每个装饰器只负责单一功能,比如校准、过滤、日志记录,既符合单一职责原则,又能灵活组合:

// 校准装饰器:给测量值添加偏移量校准
public class CalibrationDecorator : SensorDecorator
{
    private readonly double _calibrationOffset;

    public CalibrationDecorator(IMeasureSensor wrappedSensor, double offset) : base(wrappedSensor)
    {
        _calibrationOffset = offset;
    }

    public override double TakeMeasurement()
    {
        var rawValue = _wrappedSensor.TakeMeasurement();
        return rawValue + _calibrationOffset;
    }

    public override string GetSensorInfo()
    {
        return $"{_wrappedSensor.GetSensorInfo()} + 校准(offset:{_calibrationOffset})";
    }
}

// 过滤装饰器:过滤超出合理范围的异常测量值
public class FilterDecorator : SensorDecorator
{
    private readonly double _minValidValue;
    private readonly double _maxValidValue;

    public FilterDecorator(IMeasureSensor wrappedSensor, double min, double max) : base(wrappedSensor)
    {
        _minValidValue = min;
        _maxValidValue = max;
    }

    public override double TakeMeasurement()
    {
        var value = _wrappedSensor.TakeMeasurement();
        // 值超出范围时返回默认合理值,也可抛出异常或返回上一次有效值
        if (value < _minValidValue || value > _maxValidValue)
        {
            return (_minValidValue + _maxValidValue) / 2;
        }
        return value;
    }

    public override string GetSensorInfo()
    {
        return $"{_wrappedSensor.GetSensorInfo()} + 范围过滤({_minValidValue}-{_maxValidValue})";
    }
}

// 日志装饰器:记录每次测量的时间和数值
public class LoggingDecorator : SensorDecorator
{
    public LoggingDecorator(IMeasureSensor wrappedSensor) : base(wrappedSensor)
    {
    }

    public override double TakeMeasurement()
    {
        var value = _wrappedSensor.TakeMeasurement();
        // 模拟日志输出,实际项目可替换为日志框架调用
        Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 传感器测量值:{value:F2}");
        return value;
    }

    public override string GetSensorInfo()
    {
        return $"{_wrappedSensor.GetSensorInfo()} + 测量日志";
    }
}

5. 实际使用示例

现在你可以任意组合这些装饰器,实现不同的传感器行为组合,完全符合「装饰器之间可互相包装」的要求:

// 示例1:使用基础温度传感器
IMeasureSensor basicTempSensor = new TemperatureSensor();
Console.WriteLine($"基础传感器信息:{basicTempSensor.GetSensorInfo()}");
Console.WriteLine($"基础测量值:{basicTempSensor.TakeMeasurement():F2}");

// 示例2:给基础温度传感器叠加校准+日志功能
IMeasureSensor calibratedLoggedTempSensor = new LoggingDecorator(new CalibrationDecorator(basicTempSensor, -2.0));
Console.WriteLine($"\n装饰后传感器信息:{calibratedLoggedTempSensor.GetSensorInfo()}");
Console.WriteLine($"装饰后测量值:{calibratedLoggedTempSensor.TakeMeasurement():F2}");

// 示例3:给湿度传感器叠加过滤+校准+日志的全功能组合
IMeasureSensor fullyDecoratedHumiditySensor = new LoggingDecorator(
    new CalibrationDecorator(
        new FilterDecorator(new HumiditySensor(), 10, 90), 
        5.0));
Console.WriteLine($"\n全装饰传感器信息:{fullyDecoratedHumiditySensor.GetSensorInfo()}");
Console.WriteLine($"全装饰测量值:{fullyDecoratedHumiditySensor.TakeMeasurement():F2}");

这种架构的优势很突出:

  • 灵活性高:想给传感器加什么功能,套对应装饰器即可,无需修改现有传感器代码
  • 扩展性强:新增功能只需写新的装饰器类,完全符合开闭原则
  • 职责清晰:每个装饰器只做一件事,代码易维护、易测试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:37:48