软件设计入门1 架构设计
热爱编程才能做优秀的软件设计师!
软件设计有一些方法可以参考。但更重要的是要有好的需求分析、丰富的技术知识和设计经验(多动手!)不断追求更好的精神(多动脑!)。
遇到别人的系统想一下自己能否实现,如何实现?
一、优秀设计的标准:性价比高的设计。
1)优秀的设计都是需求驱动的,不熟悉需求就做出来的设计是不靠谱的;
2)优秀的设计应该是当前团队能理解能实现的,太超前的设计项目团队做不出来,这个设计只能是摆设;
3)优秀的设计应充分考虑当前各种限制条件,适当做出平衡,能保证达成项目的目标;
4)优秀的设计能尽量降低项目的整体工作量,让真个项目更加可控。
二、优秀的设计从需求开始
案例挑战:考勤系统的软件设计:
某公司要做一个内部的考勤系统,希望达成以下目标:
1)规范员工的上下班、请假、外出工作等行为。
2)方便计算员工的薪金。
3)方便管理各种带薪假期。
该如何设计本系统呢?
先做需求分析,确保需求分析没有问题。
分析需求,先从业务角度分析,再从软件设计的角度分析(5步走):
1)谁会用本系统?(列出所有可能的用户)
2)不同的人分别用哪些功能?(用例图)
3)还有哪些不确定或不具体的需求点?(用户场景)
4)哪些需求对技术提出了怎样的需求?(具体问题的解决方案)
5)系统的大致架构该如何考虑?(部署图、组件图、包图)
需求分析不但要做到第1)2)步还要深入分析业务(业务流程、业务数据...)
三、软件系统不是木桶型的(软件设计一般都是要整体考虑的)
用户场景之间是有关系的,如基础数据。不同的用户场景可能用到的基础数据是相同的,不能把系统做成木桶型的(每多一个用户场景就添加一份表现层、逻辑层、数据库表),这样会很恶心。
软件常见内部架构:
此图说明:
1)各个用户场景之间是有关联的,不是独立的。软件设计应该多从业务概念、业务流程的角度考虑;
2)各个用户场景的界面之间可能有重用和共享的部分(共用基础信息);
3)业务逻辑中的一些类本来就是一个整体。
四、软件设计的“大道理”
1、软件设计思路:
1)由顶而下:先假设软件已经做出来了,想好软件的外在表现,由此倒推软件的实现方法;
2)由底而上:思考程序的数据结构,先设计数据库,然后再搭建软件的上层建筑;
3)有中间至上下。
N层架构:以4层为例
UML包图,包与包之间的虚箭头表示依赖关系。
上图意思如下:
1)四层架构包括:表现层、逻辑层、数据访问层、数据层;
2)表现层依赖逻辑层,逻辑层依赖数据访问层,数据访问层依赖数据层。
依赖可以使一下情况之一:
1)A需要调用B的方法,A依赖于B;
2)A的方法中某些参数的类型是B,A依赖于B;
3)A的某些方法的返回值类型是B,A依赖于B。
各层之间是怎么传递数据的(传参数?)No!将数据保存到实体类中,各层均依赖实体类!:
。
实体类:通常是只有属性没有方法的类,通常我们将一些业务对象的数据放在一个实体类中。如:请假条的实体类(请假人姓名、请假起止日期、请假类别、请假事由等)。
2、由顶而下:先想清楚表现层,再思考逻辑层、数据访问层、数据层实现。
“需求驱动设计”哪部分需求驱动了什么设计?看图:。
本图表达的意思:1)软件设计首先要有正确的需求分析,需要将需求分解为 用例、业务流程图、业务概念图。
2)设计不同的层时主要依赖的需求不一样。
3、由底而上:
。
4、有中间到上下:(使用情况:表现层不动,数据层变动。如:将SQLServer换为Oracle)
定义实体类和数据层接口,在数据库操作层实现接口功能。接口对于逻辑层是一样的。
从中间到上下的软件架构如图:。
这样做也不是没有缺点的,这样会不能使用数据库的特性,如禁止在数据库中邪存储过程、触发器、视图等。增加了程序的复杂度和工作量。
五、规划系统的骨架——架构设计
1、软件设计至少需要4方面的设计:架构设计、数据库设计、模块设计、用户体验设计。
架构设计:通盘考虑需求后,从宏观上规划系统的各部分及各个部分的关系;
数据库设计:对需求中的业务概念进行系统分析后,设计出表和表关系、视图等数据库元素;
模块设计:架构设计将系统划分成多个模块,模块设计驾驶针对某些或某个模块的具体设计;
用户体验设计:需要考虑软件的整体假面规划、界面先后关系、文字表达、软件与用户如何交互等。由顶而下设计。
2、不要“放之四海而皆准”的架构设计
想一下架构设计的作用,下边的软件架构设计有相当于没有,就是废话:
没有体现出需求,没有体现出该系统的特殊性!
下边的系统架构犯了同样的毛病:。
3、架构设计 是考虑“全部需求”后做出来的。
1)、先通过用例图列出全部需求:
,分析图中需要重点关注的地方。
。
从关注点中发现问题,提出解决方案。
4、逐步拆解架构设计
不以解决需求为目的的软件设计就是耍流氓!
想说明一下工作流:
1)、死的工作流:代码是死的,数据库设计也是死的,流程或表单由任何变化,都可能需要改代码和数据库设计。
2)、半死不活的工作流:部分地方写死,部分地方是灵活的,能适应部分需求变化。
3)、全活的工作流:代码和数据库设计等都是灵活的,能基本适应流程及表单的变化,不需要修改代码或数据库设计,只要配置一下就可以搞定。
开发设计最好由易到难。
初步架构设计——第一层拆解
针对一个具体的项目做架构设计时,不能脱离具体的技术框架,要先确定你的开发语言、数据库种类等。架构设计要从物理设计的深度来思考,而不能仅仅是理论设计或逻辑上的设计,否则又会犯太空洞的毛病(“放之四海而皆准”的毛病)。
。
小结初步架构设计的要点:
1)、系统涉及到客户端和服务器,我们要考虑系统需要客户端和服务器做哪些事?这需要客户端和服务器具备哪些配置属性:系统属性、软件属性、硬件属性等。
2)、客户端和服务器见得物理联系方式:局域网?互联网?还是?
3)、客户端和服务器上需要我们开发什么软件?相当于第一条的软件属性。第一条更侧重于硬件及其性能。
图中需要我们开发的东西有:WebApplication、工作流定义用的客户端软件、三个数据库。
第一次架构设计就是划分系统分了几部分及各部分的关系。
继续深入拆解——第二层拆解(进入第一次划分出的每一部分再次划分)
以Web Application为例,深入设计。
分析Web Application的内部架构分几部分及他们之间的关系时,也要考虑有哪些食欲外部交互的。
这张图凸显的是Web Application模块内部的模块与外部模块的的连接关系,没有与外部模块连接的模块被隐藏了。
细分到这一步,开始发现需要解决的问题:
,一一列出每一个问题的可行的解决方案,及方案需要考虑的具体问题。
架构设计拆解小结:
1)、第一层拆解:解决“整个系统分为几块,需要开发什么软件和数据库”的问题。
2)、第二层拆解:深入到系统的一个模块,再次划分能分成几个子模块,考虑他们之间的关系,哪些子模块是和外部模块有联系的。可以参考分层架构。
3)、“第二层拆解”的结果有可能是组件、代码包、某个分层等等,可能是“物理拆分”,也可能是“逻辑拆分”。
拆分到什么程度才算合适呢?:如果在拆解下去,下一步的拆解就到类了,那么就可以认为目前的拆解粒度比较合适了。细化到类的拆解,可以在模块设计中再进一步考虑。
“物理拆分”和“逻辑拆分”:
物理拆分:解释物理上独立的部分,有可能是EXE、dll、数据库文件等。该系统可以物理拆分成5部分:Web Application、流程定义用的客户端软件、3个数据库。在对Web Application进一步进行拆分时,日历控件是物理拆分,这个控件将通过二进制的方式供程序他部分调用,二这个控件将来也可以供其他系统使用。
逻辑拆分:代码包、某个分层这些往往是逻辑拆分,物理上他们不会编译成单独的一部分,而是被整体变异近软件当中。
“第二层拆解”的目的除了更加方便我们设计出系统,另外一个重要目的是做系统的重用设计。物理拆分——二进制重用;逻辑拆分——源代码重用。这些重用会为以后其他软件开发提供便利。
5、分布式系统与单机系统的架构设计
分布式系统往往需要我们在多台设备上部署,个部分需要联调后,整个系统才能正常工作。
本文前边的系统架构就是分布式架构。