当前位置:首页 > 单片机 > CPP开发者
[导读]在现代操作系统的结构设计中,经常利用“机制与策略分离”的原理来构造OS结构。

在现代操作系统的结构设计中,经常利用“机制与策略分离”的原理来构造OS结构。所谓机制,是指实现某一功能的具体执行机构。而策略,则是在机制基础上,借助于某些参数和算法来实现该功能的优化,或达到不同的功能目标。通常,机制处于一个系统的基层,而策略则处于系统的高层。

在程序设计中,机制与策略分离的思想可以提高程序的可复用性可维护性可调试性使程序更具有高内聚低耦合性。如果说机制是砖,那么策略就是房子,同样的砖可以建不同的房子,我们不能把建砖和建房子混在一起实现。
策略的变化要远远大于机制的变化。将两者分离,可以使机制相对保持稳定,而同时支持策略的变化。
在代码大全中提到“隔离变化”的概念,以及设计模式中提到的将易变化的部分和不易变化的部分分离也是这个思路。
在《Unix编程艺术》第一章就深刻讨论这个编程哲学:
“在我们对 Unix 错误的讨论中,我们观察到 X window的设计者做出了一个基本决定来实现“机制,而不是策略” —— 使 X 成为一个通用的图形引擎,并将有关用户界面风格的决定留给工具包和其他级别的系统。我们通过指出政策和机制倾向于在不同的时间尺度上发生变异来证明这一点,政策的变化比机制快得多,GUI 工具包的外观和感觉上的时尚可能来来去去,但光栅操作和合成是永恒的。
因此,将策略和机制硬连接在一起会产生两个负面影响:它使策略变得僵化并且更难以响应用户需求而改变,这意味着试图改变策略有很强的破坏机制稳定的倾向。
另一方面,通过将两者分开,我们可以在不破坏机制的情况下试验新策略。我们还使为机制编写好的测试变得更加容易。
实现这种分离的一种方法是,例如,将应用程序编写为由嵌入式脚本语言驱动的 C服务例程库,应用程序控制流是用脚本语言而不是 C 编写的。这种模式是Emacs编辑器,它使用嵌入式 Lisp解释器来控制用 C 编写的编辑原语。
另一种方法是将您的应用程序分成协作的前端和后端进程,这些进程通过套接字上的专用应用程序协议进行通信;前端执行策略,后端实现机制。这样的全局复杂性通常远低于实现相同功能的单进程单体的复杂性,从而减少您对错误的脆弱性并降低生命周期成本(提高健壮性)。”

一些例子

GUI框架
MVC(Model-View-Controller)作为最经典的GUI架构,MVC模式的核心思想是数据层(Domain)与表现层(Presentation)的隔离。
  • 模型(Model) 用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“ Model ”有对数据直接访问的权力,例如对数据库的访问。“Model”不依赖“View”和“Controller”,也就是说, Model 不关心它会被如何显示或是如何被操作。但是 Model 中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此 Model 的 View 必须事先在此 Model 上注册,从而,View 可以了解在数据 Model 上发生的改变。
  • 视图(View)能够实现数据有目的的显示(理论上,这不是必需的)。在 View 中一般没有程序上的逻辑。为了实现 View 上的刷新功能,View 需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。
  • 控制器(Controller)起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。
View,Model属于策略,在系统中属于可变部分,Controller属于机制,不会随着view的变化而变化,属于系统中不变的部分,构建一个系统要尽肯能分离可变部分和不可变部分。
netfilter框架
netfilter框架是一个典型将机制和策略分离好例子:

Netfilter是一个设计良好的框架,之所以说它是一个框架是因为它提供了最基本的底层支撑,而对于实现的关注度却没有那么高,这种底层支撑实际上是5个HOOK点:
PREROUTING:数据包进入网络层路由前FORWARD:数据包路由之后确定要转发之后INPUT:数据包路由之后确定要本地接收之后OUTPUT:本地数据包发送POSTROUTING:数据包发出去之前
Netfilter拥有几乎无限的可扩展性, Liuux中使用的仅仅是它的一个很小的部分,大部分的内容作为可插拔的module处于待命状态Netfilter的机制集成在Linux内核中, 然而它的策略扩展却处于一个独立的空间,我们说这种所谓的机制也仅仅是5个HOOK点。我们浏览netfilter.org就会知道,它里面融合了大量的策略,我们最熟悉的就是iptables了,上图的ebtables,arptables,nft也是Netfilter的扩展之一, 足以看出,Netfilter有多强大,内核仅仅给出钩子点而已, 如果你嫌某些不好,你可以自己实现一个更好的,事实上,Netfilter中有很多的东西并没有集成在Linux内核。

TCP拥塞控制框架

Linux系统中的TCP拥塞控制采用面向对象的设计思想,提供拥塞控制接口用于实现不同的拥塞控制策略,成功把拥塞控制解耦了:


eBPF框架
  • 内核实现BPF虚拟机执行核心引擎,属于机制部分;
  • 用户态可以编写各种BPF程序,实现不同策略功能;

游戏引擎


游戏引擎架构
游戏引擎便是专门为游戏而设计的工具及技术集成,之所以称为引擎,如同交通工具中的引擎,提供了最核心的技术部分--游戏机制,然后可以通过脚本语言或者关卡设计来插入策略逻辑,重用性是游戏引擎的一个重要设计目标,这样很多游戏开发都可以通过"换皮策略"来快速开发新游戏。

最后一些问题

1、透过现象看本质,机制与策略到底是什么?为什么要将机制与策略分离?
机制可以认为是业务通用的核心模型(框架),不易变化;策略可以认为是某个功能的具体实现方案,可以被框架使用;机制与策略分离,是一种可扩展性设计的重要方法,提供一个继承接口,用于提供不同的实现,这也就是策略模式和接口隔离原则。机制关联一个抽象的策略(也就是接口),用不同的具体策略初始化抽象策略,就能调用具体策略的处理流程。
2、假如不分离,会出现什么问题?
把策略同机制揉成一团有两个负面影响:一来会使策略变得死板,难以适应用户需求的改变,二来也意味着任何策略的改变都极有可能动摇机制,对原来稳定的框架造成污染,引入风险。
所以我们在设计系统的时候,可以参考这种机制和策略模式,让系统具有更好的扩展性和更好的稳定性。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭