系统软件设计中模块划分案例
一、系统设计
根据工程实践经验,系统设计总体来说可以精简提炼分为两个核心阶段,即总体设计和详细设计。
1、总体设计
总体设计的主要任务是把需求分析得到的结果转换为软件结构和数据结构,也就是确定软件的主体系统结构。
设计软件结构的具体任务是将一个复杂系统按功能进行模块划分、建立模块的层次结构及调用关系、确定模块间的接口和人机界面等。
概要设计方法的主要目标是根据特定维度确定各个子系统和模块的划分,将由一个或多个功能(或目标)密切相关或相似的应用程序所组成的程序集合抽象出来。根据经验概要设计方法主要包括模块化方法、功能分解方法、面向数据流和面向数据结构的设计方法。按照面向服务架构
(SOA)或者比较时髦的观点,概要设计的主要工作就是提取和整合微服务及业务逻辑,按照领域抽取展示层,最终拆分出功能独立的子系统。举例来说,按照一般的模块化或者功能拆分方法,我们可以将一个完善的电商系统分解为商品、库管、订单、支付、财务、结算、配送、搜索、CRM、虚拟货币、优惠票券、短信、邮件、活动等子系统。而子系统可以再次按照模块或者功能细分,比如订单系统可以按商品品类或者活动类型或者线上线下等维度拆分;支付系统可以按照内外部支付方式、支付和风控策略、支付模式(如跳转或直连等)等不同维度进行划分。从SOA的角度看,不论子系统划分维度是什么,SOA都会对各种服务进行布局和整合,发布服务和数据契约,其最主要的目的就是对子系统服务进行复用。当然,SOA如何和子系统设计布局和整合联系起来这是另一个话题了,本文不展开讨论。
2、详细设计
细节决定成败(Idea is cheap,detail is devil.),详细设计是实现系统模块的关键步骤。
程序=算法+数据结构,虽然我认为这个公式不完全正确,但是突出了算法和数据结构的重要性。
详细设计的主要任务就是根据总体设计中确定的业务子系统,设计每个子系统功能或模块的实现算法和数据结构,但根据一般的业务系统开发经验,详细设计涉及的具体内容可能还包括数据库设计、界面设计、子系统互联设计等。
详细设计非常考验程序员的基本编程水平和经验。我认为任何详细设计的最终目标都是通过可编程的手段实现软件系统,所以,对于开发人员,代码是第一重要的作品,其次才是文档,手册,图表,再其次是PPT等等这些副产品。
在实现业务子系统的过程中,必然会涉及到各种方法论,比如面向过程,面向对象等等。那么通过哪种方法论如何实现一个可正常工作功能强大适应变化的子系统呢?
在系统具体实现这一块,我个人接触最多的是面向对象编程(OOP)。成功设计开发一个子系统,我的个人开发经验可以总结为如下几条:
a、分而治之,划分模块,子系统还可以拆分子系统,服务还可以拆分子服务,这里涉及到一个粒度的问题,非常考验开发者的水平和经验,否则很容易过度设计
b、分层,这个不用说了,如果你真正理解分层的含义,那么在很多情况下,N层不如经典三
层,谁写谁知道
c、保证隔离,划清界限,不要过多假设,不要拖泥带水,任何模块或服务只做它该做的事情
d、实现隔离的最佳方法,就是针对接口,而不是对具体实现编程(Programming to an Interface, not an Implementation)
e、多态,多态,多态,如果一定要复用类,请优先使用对象的组合而非继承
f、提取变化剧烈的变化点,定期重构,核心业务逻辑必须单元测试
g、UI变化最大,其次业务逻辑,而且很多时候UI变化会直接影响后端业务逻辑,所以,你的接口设计要向UI和业务逻辑倾斜,反而是基础框架和基础服务非常稳定,不需要过度设计
做到上面这几点,绝大多数的开发问题都会迎刃而解,反正在我多年开发经历中屡试不爽。
当然,归根结底,成功的子系统的设计与开发还是看具体开发者的水平,如果逻辑和抽象能力差,或者不认真没有追求看上去就不那么让人放心,说什么都是白搭。
二、平台化设计
我们可以把以提供统一的公共服务为主要职责的软件或系统叫做平台软件。比如常见的框架基础平台、应用管理平台、工作平台(OA系统等)、MDM、运维平台、财务平台、结算平台、支付平台、配送平台、决策平台、客户管理平台、CTI平台、开放平台、云平台等等。
纵观软件发展历程,围绕着“复用”,各种方法论和工具层出不穷,比如:结构化开发中,函数和过程(表示一段代码)的复用;面向对象设计(OOP)中的类和对象的复用 ,COM和COM+中的组件标志着模块的复用;SOA架构中某个业务服务(子系统)的复用等等。
主流的软件开发模式中,复用成了系统设计的一个重要目标,平台化是复用软件产品的一套成熟解决方案,开发和运营的性价比也较高,而且相对有利于扩展。
为什么说平台化设计有利于扩展呢?下面的段落中我将讲一个发生在自己身上的真实案例。
三、多商户或多租户系统
两年前某司新扩张了业务,大致需求就是相当于注册一个新公司同时该新公司可以使用已有
的很多系统,但某些核心业务(如财务等)需要独立运营,然后就涉及到我这里说讲的多商户或多租户的系统。
平台化的软件产品有多种多样,其中,又以多商户或多租户的系统设计与实现最为复杂,而且随着需求的变化,扩展性很容易成为瓶颈,多商户或多租户的系统数据存储我曾经有过简单总结。
具体到某司的系统扩展,我给出的是两种方案,方案一是可以为新公司独立部署一套应用实例然后修改配置搞定,方案二是可以通过增量增加代码重新实现一遍已有的功能。
从维持系统稳定的角度,两种方案在理论上而言都相对的不会改动原有系统的实现代码,第一种直接拷贝原有的部署结构重新实施改改数据库配置就行了,第二种则是不改动任何已有代码而是通过增加新代码实现功能(这种不改动任何已有代码仅限理论上,考虑到业务复杂性,可能还是需要对已有逻辑做些微调)。对于这两种实现方案,很显然会有人有不同意见,好了,我知道你们要说重复是魔鬼,不要重复你自己等等等等。要是在2010年之前,我一定也有类似的看法,我甚至还可能写篇博客之类的洋洋洒洒批驳一番,但是经过多年工作和编程实践考验,再碰到有人说重复我就呵呵对待了。
无数事实证明理论和实践不是一回事,歪果仁也流行说theory is ugly,idea is cheap,talk is 所以我们需要大胆实践,验证口头上的理论在现实环境下到底行不行得通。模块化设计的产品举例