`

模型驱动设计(MDD)之灵活设计

阅读更多

  灵活设计可以使我们随着项目开发的进行,感到速度越来越快,而不是越来越慢,甚至 停滞不前。灵活设计是对领域建模的补充,当我们从领域中抓住那些隐隐约约的线索和概念原型后,就象准备好原料;下面就是通过迭代将原料锤炼成一定具体的形状,可以俗称“打铁”,那么打铁打到什么形状算可以了呢? 也就是最终希望达到什么样的设计呢?

  有些软件打着“灵活性”旗号,却出现很多多余的抽象和间接层次,从而导致了复杂性,灵活性可能导致复杂性, 但是灵活性不是导致复杂性的必然原因,如何将灵活性的发展通往简单,其中精湛技巧就需要学习和不断实践, 正确的理论指导是必不可少的,模型驱动设计(MDD)提供这样一个科学的方法论。

  在Eric Evans的“领域驱动设计”一书中专门探讨了这样提供灵活设计的模式和方法,下面简要述说如下:

明显意图的接口

  接口的名称必须表达明显意图,而不是模棱两可,接口虽然是抽象,但是也不能抽象到别人不知你所云, 如果其他开发人员必须查看接口的实现子类才能搞清楚你这个接口的意图,那么你的接口抽象无疑是失败的,

  使用明显意图的接口可以将整个子领域切分成一个个单独模块,每个模块使用带有明显意图的接口封装起来, 这种切割方式用来调整项目的焦点和对付大型系统的复杂性。

  如果仅仅有大型系统开发经验,但是没有大型系统的分割经验,更重要的是良好设计理论基础,那些大型 系统开发经验也只是如过眼烟云,不会在你的程序生涯中占据多大的重要位置。

  下面我们聚焦被划分成单个模块的内部设计模式:

边界影响
  在软件中,操作分为:命令和查询,命令就是能够使 系统状态发生改变的操作,如增删改等操作。这些操作都可能需要有副功能,如希望增删改完成后还要返回一些结果,这些主要功能之外的副业,也称为边界影响(side effect)。一些传统过程经验的程序员经常喜欢搞“一机多用”,喜欢将很多功能揉合在一起。

  大多数操作会调用其他操作,造成任意深度的嵌套,这样形成一个树形结构的调用关系,这就容易使我们很难 预测调用一个操作会产生什么样的结果,调用一个操作变得谨慎,甚至战战兢兢,虽然Ioc或DI container使 得这种嵌套关系的管理变得容易,但是不能保证每个操作本身的设计能降低复杂性,后者就是我们现在关注的。

  为什么我们调用一个操作时会变得小心,因为这个操作设计时可能不执行主要功能,还有其他副功能,这些 副功能可以认为是一种多余副作用,解决办法很简单:设计这个操作时消灭副作用;如果不能消灭,就将其 分离显式分离并单独表达出来。

  所以,我们设计增删改命令和查询功能时,尽可能分离它们到不同操作中实现,不要在增删改命令执行的同时 返回任何领域数据。

  如果边界影响不能通过设计避免,那么我们就直面它,在增删改等命令执行同时返回数据,当这样做的同时, 我们就使用断言assertion来约束我们这样的设计,通过断言能够易于使用单元测试Junit等工具测试。从而 保证你的命令简单有规则。

  总之还是那句有些哲学意义的话:对于边界功能,首先要去除它,如果不能回避它,就承认它,但是同时会约束它。

  边界影响主要的是Service接口怎么做的问题。在实际项目中,Model和Service是相互结合不断重构的。那么Model和Service粒度是如何界定的?

粒度界定

  对象的粒度到底是多大?这没有一个统一的规律,哪些属性或行为属于A对象,哪些属于B对象,有时又需要将这些属性和行为分离以便能够灵活组合。我们一般很难确定类的粒度到底是怎样规模表示达到设计目的?

  首先,粒度不能太大,造成重复和冗余,很多概念混在一起;当然粒度也不能太细,以至于太碎,不能完整表达一个领域概念,例如半个铀原子就不再是铀。

  类需要尽量准确表达领域概念,大多数领域中都包含某种逻辑上的一致性,而很多程序员有时只注意单纯的设计原则,忽视领域逻辑,设计思考时需要两条腿走路,实现平衡,比如JdonFramework的缓存设计主要应对企业领域大量查询都是在时间上相对集中的查询(如本月度),因为领域中某种逻辑存在(时间上相对集中的查询),才使得我们决定采取某种设计方案,如果没有这个前提,任何设计方案都是可行的,这也是我们通常讨论的业务场景。

  每个人对业务领域中很多概念都可能不一致,但不能否认:领域中一定在某个地方存在一种旋律,我们的模型肯定能够与领域某个部分发生共振,问题关键是:我们需要通过不断发现的过程来寻找这种共振,这过程就依赖反复的重构重整refactoring。

  通过重构,使我们的设计适应我们重新理解了的领域概念和业务需求,概念轮廓(Conceptual Contour)就会浮现。

  注意“概念轮廓”是指对领域中概念的主要轮廓,大概样子,需要忽视不重要的细节,设计人员必须理解领域中概念在哪些地方会发生改变?哪些地方保持相对稳定,然后使设计的模型尽量与领域中概念稳定面结合起来,这样,当业务领域中概念发生变化时,我们的模型才会随之一起翩翩起舞,发生共振,从而达到模型设计反应领域本质的目的。

  所以,类的粒度是要能够反应领域的概念轮廓,将能够反应概念轮廓的那些重要元素聚合到当前正在设计的类中,这也是设计中高聚合原则的体现。

  高聚合、低关联是两个设计基本原则,上面我们谈了如何做到高聚合,实际上,也是反映一种类或模块的粒度设计规模。下面谈谈低关联:

消灭依赖

  复杂的依赖关系无疑提高了系统的复杂性,加剧我们大脑负载,所以,我们的模型之间关系必须精练,减少依赖,最后保留下来的依赖代表了领域概念之间某种根本的关系。有的系统中,甚至是0关联,从而得到一个个被完全孤立的单独的类(standalone Class),这才是方向(也有利于我们简化配置Hibernate这些模型持久化框架,无需考虑一对多等关联配置)。

  每个依赖都是值得怀疑的,这是我们思考的前提,重构时,一个个去消灭那些象蜘蛛网一样密集的关系,斩断它们,低关联时减轻概念过载问题的基本方法,孤立类是低关联达到极致的一种标志。

  减少依赖不是意味不考虑业务领域场景概念,武断实现,依赖和之前描述的边界影响一样,有时确实不能消灭,那么我们就承认它,但是会又有一套设计原则来约束它。

分享到:
评论

相关推荐

    领域驱动设计与模型驱动开发

    模型驱动开发(Model-Driven Development,MDD)是指一种软件开发方式,它主要关注于创建和利用模型来指导软件的设计和实现。在模型驱动开发中,模型不仅仅是一个简单的辅助工具,而是成为开发过程中的中心元素。...

    DDD领域驱动设计学习框架简介PPT

    MDD(Model-Driven Development)则是一个更广泛的概念,包括DDD在内,强调用模型来驱动整个开发流程,通过模型来指导软件的各个阶段,包括分析、设计和实现。DDD则侧重于设计范畴,它关注如何通过领域模型来组织和...

    模型驱动开发的误解和挑战

    模型驱动开发(MDD)是一种先进的软件开发方法,旨在通过使用模型来抽象和管理软件复杂性,从而提高生产力和质量。然而,MDD在实际应用中并未达到预期的效果,主要面临一些误解和挑战。 首先,关于MDD的一个挑战是...

    Agile模型驱动开发BorCon China- Raising the level

    Agile模型驱动开发是一种在软件工程领域广泛应用的高级开发方法,它结合了敏捷开发的灵活性与模型驱动架构(MDD)的效率。在"Agile模型驱动开发BorCon China- Raising the level"这个主题中,我们探讨的是如何在中国...

    RUP过程与UML模型驱动开发方法在证券研发项目中的应用实践

    模型驱动开发(Model Driven Development, MDD)就是利用UML模型作为软件开发的主要载体,通过自动化工具将模型转换为实际代码,降低了代码编写错误的风险。 在证券研发项目中,RUP与UML的结合应用通常遵循以下步骤...

    模型驱动下的软件开发模式

    模型驱动开发(MDD)是一种新的软件开发模式,它将应用程序指定为一个高层次的抽象模型,通过对模型的解释/执行或产生的代码,抽象模型会自动转化为可工作的软件应用。这种开发模式有很多优势,以下是十五个理由: ...

    多维关注分离的模型驱动过程框架设计方法

    在当前的软件开发领域,模型驱动开发(Model-Driven Development, MDD)已经成为了一种趋势,尤其随着OMG MDA (Model Driven Architecture) 和 UML (Unified Modeling Language) 规范的推广和发展。然而,在实际的...

    问卷模板资料-mdd文档

    在IT行业中,MDD(Model Driven Development,模型驱动开发)是一种先进的软件开发方法论,它强调使用模型作为软件开发的核心。在这个“问卷模板资料-mdd文档”中,我们可以推测内容可能涉及MDD如何应用于创建和管理...

    Windows Embedded从入门到精通系列课程(7) Windows Embedded CE 6.0 MDD_PDD Camera Driver Model.rar

    它提供了灵活的驱动程序模型,使得开发者可以根据硬件特性定制适合的驱动解决方案。 MDD(Middleware Device Driver)是介于硬件驱动和应用程序之间的一层软件,它的主要任务是提供一个标准化的接口,使得应用程序...

    基于S3C6410与FPGA通讯的SPI接口驱动设计.pdf

    驱动程序在Windows CE6.0系统中,是以分层的结构存在,它包括平台相关驱动(PDD)和模型设备驱动(MDD)两部分。 文章中提及的S3C6410是一款基于ARM926EJ-S核心的高性能微处理器,广泛应用于移动设备和嵌入式系统。...

    行业分类-设备装置-模型驱动、适合不同接口和平台技术的融合业务生成方法.zip

    阅读这份文档,读者可以深入理解如何运用模型驱动方法来设计和实现跨平台的设备装置业务,以及如何有效地融合不同接口技术,以实现高效、灵活的业务生成。 总的来说,这个压缩包文件的内容对于那些从事设备装置开发...

    模型驱动开发工具的自动化测试技术研究.pdf

    模型驱动开发(Model Driven Development, MDD)是一种先进的软件开发方法,它强调将软件的逻辑和结构模型作为开发的核心,而不是直接编写源代码。在MDD中,开发者使用建模语言来描述软件的行为和结构,然后通过模型...

    WindowsCE电池驱动采样算法的改进设计

    本文采用的是分层驱动程序设计模式,该模式下驱动程序分为两层:模型设备驱动程序(MDD)和依赖平台的驱动程序(PDD)。其中,MDD负责提供通用接口,而PDD则专注于处理与具体平台相关的硬件操作。这样的设计使得OEM...

    Windows CE操作系统的触摸屏驱动程序模型.txt

    Windows CE操作系统为触摸屏设备提供了强大的支持,其触摸屏驱动程序模型不仅灵活而且高效。通过对MDD和PDD层次结构的理解,开发者可以更容易地为不同类型的硬件平台编写定制化的驱动程序。此外,Windows CE还提供了...

    PragmaticMDD:务实的模型驱动开发方法

    该项目背后的想法是提供概念证明并开发一套实用的模型驱动开发方法的最佳实践。 它不应该以任何现有的MDD技术为基础(从OAW,没有ATL,没有Xpand,没有Xtend,没有Epsilon,通常没有Eclipse),应该尽可能简单地...

    wince中蓝牙驱动的实现

    这种驱动程序模型非常适合于实现蓝牙仿真串口,因为它可以提供更加灵活和简单的编程接口。 #### 蓝牙仿真串口驱动程序的设计 蓝牙仿真串口是利用蓝牙协议栈来实现无线串口通信的一种方法。在Wince中,实现蓝牙仿真...

Global site tag (gtag.js) - Google Analytics