前面的章节里,我们一步步构建了机械手的功能。现在有个新需求:想给机械手的移动操作加上日志记录和计时功能。遵循面向对象的设计模式原则,我们不应该频繁地去修改已有的 Robot 类。那么,如何实现这个需求呢?能否动态地为现有对象添加这些额外功能?这正是装饰模式大显身手的时候!
一、什么是装饰模式
装饰器模式(Decorator Pattern) 允许你向一个现有的对象添加新的功能,同时又不改变其结构。这种设计模式属于结构型模式,它通过将对象包装在装饰器类中,以便动态地修改其行为。
简单来说,该模式创建了一个装饰类,用来包装原有的类。它在保持类方法签名完整性的前提下,提供了额外的功能。其核心作用是:给一个现有对象“增加功能”,但不修改原类,也不创建大量子类。
二、装饰模式的核心组成
一个典型的装饰模式包含以下角色:
- 抽象组件(Abstract Component):定义所有具体组件和装饰器都必须实现的接口。在项目中,这就是
RobotBase.lvclass。
- 具体组件(Concrete Component):继承于抽象组件,是我们要装饰的对象。对应项目里的
AuboRobot 和 DobotRobot。
- 装饰器基类(Abstract Decorator):继承自抽象组件
RobotBase,其内部持有一个 RobotBase 类型的成员变量。这是实现装饰功能的关键。
- 具体装饰器(Concrete Decorator):继承自装饰器基类,是真正“加功能”的那一层。例如:
LogDecorator(日志装饰)、TimeDecorator(计时装饰)。
三、装饰模式的实现步骤
假设我们已有的 RobotBase、AuboRobot、DobotRobot 类保持不变,以下是实现装饰模式的步骤:
第一步:创建“装饰器基类”(DecoratorBase)
这个类继承自 RobotBase,并在其私有属性中包含一个 RobotBase 对象。我们还添加了一个字符串用户事件(主要用于打印信息,非必需)。

(DecoratorBase.lvclass 的数据成员视图,其中包含了对 RobotBase 对象的引用)
第二步:创建 TimeDecorator 装饰类
该类继承自 DecoratorBase,并重写 Move 方法。在重写的方法中,先调用内部 RobotBase 对象的 Move 方法,然后计算并记录执行耗时。

第三步:创建 LogDecorator 装饰类
同样继承自 DecoratorBase,并重写 Move 方法。在方法执行前后,添加日志输出功能。

第四步:主程序调用
在主程序中,我们可以根据需要,灵活地组合和嵌套装饰器。例如,可以先为机械手实例包裹一个 LogDecorator,再包裹一个 TimeDecorator,从而同时获得日志和计时功能。

最终的程序运行界面如下,Listbox 中清晰地显示了带有时戳的日志信息和执行时间。

四、总结
装饰器模式绝非“花架子”,它是项目开发中实现“低成本功能扩展”的利器。它无需重构原有核心代码,只需通过装饰器包装,就能为所有核心动作统一添加日志、校验、计时等附加功能。这种方法完美兼顾了OOP的简洁性和系统的可扩展性,落地简单,后续维护也非常方便。
希望这个结合 LabVIEW 的具体案例,能帮助你更深刻地理解装饰模式的价值。想了解更多此类实战干货与编程思想,欢迎来云栈社区的知识库交流探讨。
|