From mud to Structure

From mud to Structure: 从无到有规划新的服务

规划软件服务的过程比实作来的重要,在还未规划完整直接开始,很容易造成开发出来的产品不符合客户的需求。但怎麽规划又是一个问题,在现实生活中,不少Application 开发後使用者完全不买单的案例…因此如何规划就是一个重点。

根据POSA v4[1] 针对从零规划软题服务所给出的建议(From mud to Structure):

“Create a model that defines and scopes a system’s business responsibilities and their variations: model elements are abstractions meaningful in the application domain, while their roles and interactions reflect the domain workflow.”

从上述这段话归纳出三个重点,1. Business responsibilities、2. A model that defines and scopes、3. Elements are abstractions meaningful in the application domain。首先需要定义好所需要的Domain Feature,根据Domain Feature进一步将软件中的Entity、Value Object 规划出来,并由这些Elements 组成可以跑得Service。

Business responsibilities

在传统开方上商业逻辑的时候通常是经历过层层关卡慢慢传递到工程师,然而需求收敛的过程中,许多潜在动机将无法顺利传递,使得工程师所产出的程序法跟Domain knowledge 对不上,使得开发出来的产品不符预期的机会大大提昇。因此工程师须参与整个软件设计的过程。

此外沟通所使用的工具也是相当的重要。由於工程师、客户、专案管理员...等参与人事的背景不尽相同,可能造成沟通上的困难。像是透过UML统一建模语言,与Prototype 的实作多次的确认需求,才能有效的确认商业逻辑。

但不限於只能使用UML,只要团队自行约定好即可。

举例,像是Ontology、Data Flow Diagram (DFD)等工具都是很好表达系统的方式,然而也可以透过心智图等等的非正规软件用的工具也可,总而言之表达清楚软件设计,减少沟通所造成的消耗。

From personal blog

A model that defines and scopes

如何从Business Responsibilities则需要先厘清问题本身,将会发现一个大问题可以被拆分成多个小问题这些小问题则称为Model。往往定义Model应该与软件架构同时被考虑,不因软件的限制,导致整体架构无法将Model 行为抽象化,也不能为了Model 的功能而忽略软件的限制。 换句话说,希望可以从Model具有的意义也同时在软件架构中也看得出来,但也不能完全忽略软件的限制。

什麽是软件的限制?往往在开发的时候,已经先决定使用哪个工具,就应该充分的利用工具的优势。举例来说,当已经决定使用Socket.io 其本身具有Broadcast的功能与房间管理,那因此在设计聊天室等功能,则必须尽量贴近Socket.io的特性,也不能一昧的依照domain的需求,完全忽略所使用工具的优势或劣势。

Extract Model From Business Responsibilities (Domain)

一般来说软件上可以分为四层,UI、API、Logic、Essential 这四层,同时也遵守Layers Architecture Pattern 的规范,层层之间可互相存取,但不可以跨层存取。其中Domain是指对应Business Responsibility ,在软件上需要做到Domain则须要根据fundamental 进行实作。

当软件实作时,可以如上图Class Diagram,透过API层只与Domain 有interaction,然而Domain 还可细分成Domain、Model 两种Component。而需要做到Domain 的功能则必要使用 Model 才能达成。而Model 则透过 Fundamental 的交互作用达成。

在实务上的工程师可能会问,需要了解到什麽程度呢? 难道需要变成另一个domain的专家才可以开始做嘛? 事实上,工程师只要确认将要研发的软件架构,是符合domain 知识的即可,因此在软件设计的过程,需要时常与domain 专业人士进行对焦确认,并不需要变成另一个领域的专业人士。

Elements are abstractions meaningful in the application domain

当在规划软件服务的时候,共分成Entity、Value Object、Service 等三种角色,而Service的概念是对应到Model的概念,然而Entity、Value Object 对应到Fundamental。Entity 就是一个就有Unique ID之类的可辨别的属性,而Value Object 则是用於控制Entity 物件的物件,Service 则是Entity + Value Object 所组成的功能。

以物流车负责运送多个订单的实作功能为例,如上图Class Diagram,LogisticVehicle 属於Object Value 物件,Order 属於Entity 物件。因为对於使用者而言,LogisticVehicle 并无法区分,但Order 则是具备特定意义且能够区分出来。

结论

在软件开发中,Domain know how 须与实际的设计一起被思考。程序设计师不仅应该参与Feature 的讨论,也应该针对Domain Knowledge 进行进一步的了解,使所产出的程序设计与Domain know how尽可能贴近。此举除了日後更好维护之外,同时也能够降低日後扩充新功能的难度,因为越贴近Domain Know How所定义出来的Entity 物件越不容易有大的更动。

除此之外,设计时不用一昧的使用UML将整体设计画的非常详细,因为往往系统发展之後,会过於庞大以至於无法明显表达出设计的意含,不过之前所有规划的设计脚本,也应该被归档,让日後接手维护的开发者能更快速的了解程序的架构,才不会越修改却离Domain 越远。

参考资料

[1] Frank, Buschmann, Henney Kevlin, and C. Schmidt Douglas. Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4). Wiley, 2007.
[2] 赵俐、盛海艳、刘霞译,Domain-Driven Design领域驱动设计, 博硕文化,2019。


<<:  Day-8 Geeker 们最爱的工程型怀旧游戏神器 OSSC

>>:  Day 9 专案目录结构

day20: immuable

今天提到 immuable,对於程序当中储存的资料来说, 如果你存的资料可以被更改,那你永远不知道谁...

企划实现(29)

使用自定义的listview 第四部:创建listview的adapter package com....

Microsoft Azure Machine Learning - Day 2

Chap.I Practical drill 实战演练 以下内容来自这里 Prat1. Create...

[Day09] Flutter with GetX gallery_saver 照片影片存到相簿

Gallery saver 取得权限的前置作业 iOS Info.plist内新增 NSPhotoL...

并购(Mergers and acquisitions)-安全评监(Security assessment)

-10 步并购清单(来源:CFI Education Inc.) 在考虑剥离提议时,进行安全评监以...