基于装饰器模式的传感器架构中,如何查找特定类型的装饰器?
基于装饰器模式的多传感器架构实现方案
看起来你这个思路完全没问题啊!针对多传感器的不同行为组合需求,装饰器模式简直是量身定做的——它既能让你动态给基础传感器叠加功能,又能避免传统继承带来的类爆炸问题,完美适配你说的「装饰器本身也属于传感器、可互相包装」的架构要求。
下面我给你拆解一下具体的实现步骤,用代码示例帮你理清楚逻辑:
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
相关产品推荐
相关产品推荐

