跳至主要内容

软件概要设计与详细设计的区别

概要设计与详细设计的区别

    概要设计就是设计软件的结构,包括组成模块,模块的层次结构,模块的调用关系,每个模块的功能等等。同时,还要设计该项目的应用系统的总体数据结构和数据库结构,即应用系统要存储什么数据,这些数据是什么样的结构,它们之间有什么关系。 
    详细设计阶段就是为每个模块完成的功能进行具体的描述,要把功能描述转变为精确的、结构化的过程描述。

    概要设计阶段通常得到软件结构图
    详细设计阶段常用的描述方式有:流程图、N-S图、PAD图、伪代码等


概要设计和详细设计

    在软件设计中,大家经常问到的一个问题是:概要设计应该怎样一个概要法,详细设计应该怎样一个详细法?
这个问题在公司内部经常有人问。现在陈述一下。
    我们公司的研发流程是瀑布型的,这个模型中的分析、设计阶段是基于经典的结构化方法。 

    结构化设计方法的基本思路是:按照问题域,将软件逐级细化,分解为不必再分解的的模块,每个模块完成一定的功能,为一个或多个父模块服务(即接受调用),也接受一个或多个子模块的服务(即调用子模块)。模块的概念,和编程语言中的子程序或函数是对应的。
 
   
这样一来,设计可以明显地划分成两个阶段: 

    概要(结构)设计阶段:把软件按照一定的原则分解为模块层次,赋予每个模块一定的任务,并确定模块间调用关系和接口。
    详细设计阶段:依据概要设计阶段的分解,设计每个模块内的算法、流程等。

概要设计阶段:
 
    在这个阶段,设计者会大致考虑并照顾模块的内部实现,但不过多纠缠于此。主要集中于划分模块、分配任务、定义调用关系。模块间的接口与传参在这个阶段要定得十分细致明确,应编写严谨的数据字典,避免后续设计产生不解或误解。概要设计一般不是一次就能做到位,而是反复地进行结构调整。典型的调整是合并功能重复的模块,或者进一步分解出可以复用的模块。在概要设计阶段,应最大限度地提取可以重用的模块,建立合理的结构体系,节省后续环节的工作量。 

    概要设计文档最重要的部分是分层数据流图、结构图、数据字典以及相应的文字说明等。以概要设计文档为依据,各个模块的详细设计就可以并行展开了。

详细设计阶段:

    在这个阶段,各个模块可以分给不同的人去并行设计。在详细设计阶段,设计者的工作对象是一个模块,根据概要设计赋予的局部任务和对外接口,设计并表达出模块的算法、流程、状态转换等内容。这里要注意,如果发现有结构调整(如分解出子模块等)的必要,必须返回到概要设计阶段,将调整反应到概要设计文档中,而不能就地解决,不打招呼。详细设计文档最重要的部分是模块的流程图、状态图、局部变量及相应的文字说明等。一个模块一篇详细设计文档。

    概要设计文档相当于机械设计中的装配图,而详细设计文档相当于机械设计中的零件图。文档的编排、装订方式也可以参考机械图纸的方法。
    我们公司对模块的认识和传统定义有所不同,认为是较大的软件功能单元才可以称作模块。这种认识使大家对概要设计和详细设计的分工产生了混乱的理解,降低了文档的可用性,应该予以纠正。
    概要设计中较顶层的部分便是所谓的方案。方案文档的作用是在宏观的角度上保持设计的合理性。

    有的项目采用面向对象的分析、设计方法。可能在概要设计、详细设计的分工上疑问更多。其实,面向对象的分析、设计方法并没有强调结构化方法那样的阶段性,因此一般不引入概要、详细设计的概念。如果按照公司的文档体系,非要有这种分工的话,可以将包的划分、类及对象间的关系、类的对外属性、方法及协作设计看做概要设计;类属性、方法的内部实现看做详细设计。

   1.需求分析--产生软件功能规格说明书,需要确定用户对软件的需求,要作到明确、无歧义。不涉及具体实现方法。用户能看得明白,开发人员也可据此进行下面的工作(概要设计)。 
   2.概要设计--产生软件概要设计说明书,说明系统模块划分、选择的技术路线等,整体说明软件的实现思路。并且需要指出关键技术难点等。   
   3.详细设计--产生软件详细设计说明书,对概要设计的进一步细化,一般由各部分的担当人员依据概要设计分别完成,然后在集成,是具体的实现细节。理论上要求可以照此编码。


概要设计和详细设计的区别与联系

    软件设计采用自顶向下、逐次功能展开的设计方法,首先完成总体设计,然后完成各有机组成部分的设计。

    根据工作性质和内容的不同,软件设计分为概要设计和详细设计。概要设计实现软件的总体设计、模块划分、用户界面设计、数据库设计等等;详细设计则根据概要设计所做的模块划分,实现各模块的算法设计,实现用户界面设计、数据结构设计的细化,等等。

    概要设计是详细设计的基础,必须在详细设计之前完成,概要设计经复查确认后才可以开始详细设计。概要设计,必须完成概要设计文档,包括系统的总体设计文档、以及各个模块的概要设计文档。每个模块的设计文档都应该独立成册。

    详细设计必须遵循概要设计来进行。详细设计方案的更改,不得影响到概要设计方案;如果需要更改概要设计,必须经过项目经理的同意。详细设计,应该完成详细设计文档,主要是模块的详细设计方案说明。和概要设计一样,每个模块的详细设计文档都应该独立成册。

   概要设计里面的数据库设计应该重点在描述数据关系上,说明数据的来龙去脉,在这里应该结合我们的一下结果数据,说明这些结果数据的源点,我们这样设计的目的和原因。详细设计里的数据库设计就应该是一份完善的数据结构文档,就是一个包括类型、命名、精度、字段说明、表说明等内容的数据字典。

   概要设计里的功能应该是重点在功能描述,对需求的解释和整合,整体划分功能模块,并对各功能模块进行详细的图文描述,应该让读者大致了解系统作完后大体的结构和操作模式。详细设计则是重点在描述系统的实现方式,各模块详细说明实现功能所需的类及具体的方法函数,包括涉及到的sql语句等。

 


概要设计,详细设计之间的关系是什么?

Q:
我的看法:
    概要设计只说明系统有多少个模块,各模块之间的接口和个模块本身的功能
    详细设计说明某个具体模块如何实现,粒度应该比程序略高一些

    但是问题来了,各个模块之间是有层次关系的,也有先后逻辑关系。这就说明,在概要设计中,还必须考虑模块的实现细节,否则,你怎么知道这个模块下面要划分子模块?你怎么知道各子模块的调用顺序?
    这就说明,概要设计和详细设计是重叠进行的,而软件工程书上说的确是顺序进行的,不知道是不是我的理解有问题。


举个例子,例如排序程序,如果设计2个模块:
一个主模块用于排序子模块用于交换2个变量,主模块调用子模块,但是子模块是怎么设计出来的呢?肯定是你先想到了用冒泡等排序方式的时候需要交换数据,这已经考虑了主模块足够多的细节,似乎属于"详细设计"了,但是目前进行的是概要设计,这就产生了我所说的重叠的情况。

A:

看看上面的帖子,有意思的居多。

上面也有朋友说到用建筑的例子来比喻。

软件的概要设计,主要是建立软件系统的整体架构,也就是我们在盖房子时候,需要先将房子的整个架子构建起来。

软件的详细设计,主要是将软件系统的各个部分的具体设计方法、逻辑、功能采用文字方式进行表述。这样在实现过程中,Coding人员原则上严格按此进行代码实现即可。

这样的一个最为简单的例证:我们可以将代码交付第三方来做。验证与跟踪采取设计来。

我看上面还有一个朋友说:快速做代码。这个本身没有值得批评之处。但只要想一下,你写的代码没有任何设计思想、文档留下的情况,一旦你离开,如何维护?重新设计吗?还是花费几倍人力去研究你写的几千/万,甚至几十万行代码?如果是这样的,你没错,关键是你们老板太对了,钱算什么。

另外的一个问题是:中国人如此聪明,但中国为什么没有出现巨型软件产品呢?个人英雄主义依然很严重,老板的短视利益行为大行其道。

评论

此博客中的热门博文

【转】AMBA、AHB、APB总线简介

AMBA 简介 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大。数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用。在基于IP复用的SoC设计中,片上总线设计是最关键的问题。为此,业界出现了很多片上总线标准。其中,由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构。AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。   AMBA 片上总线        AMBA 2.0 规范包括四个部分:AHB、ASB、APB和Test Methodology。AHB的相互连接采用了传统的带有主模块和从模块的共享总线,接口与互连功能分离,这对芯片上模块之间的互连具有重要意义。AMBA已不仅是一种总线,更是一种带有接口模块的互连体系。下面将简要介绍比较重要的AHB和APB总线。 基于 AMBA 的片上系统        一个典型的基于AMBA总线的系统框图如图3所示。        大多数挂在总线上的模块(包括处理器)只是单一属性的功能模块:主模块或者从模块。主模块是向从模块发出读写操作的模块,如CPU,DSP等;从模块是接受命令并做出反应的模块,如片上的RAM,AHB/APB 桥等。另外,还有一些模块同时具有两种属性,例如直接存储器存取(DMA)在被编程时是从模块,但在系统读传输数据时必须是主模块。如果总线上存在多个主模块,就需要仲裁器来决定如何控制各种主模块对总线的访问。虽然仲裁规范是AMBA总线规范中的一部分,但具体使用的算法由RTL设计工程师决定,其中两个最常用的算法是固定优先级算法和循环制算法。AHB总线上最多可以有16个主模块和任意多个从模块,如果主模块数目大于16,则需再加一层结构(具体参阅ARM公司推出的Multi-layer AHB规范)。APB 桥既是APB总线上唯一的主模块,也是AHB系统总线上的从模块。其主要功能是锁存来自AHB系统总...

【转】VxWorks入门

1.VxWorks开发方式:交叉开发,即将开发分为主机(host)和目标机(target)两部分。 类似于dos下C语言程序的开发。 合并开发的优点:简单 缺点:资源消耗量大,CPU支持,非标准体系的支持 host (Tornado) target(vxWork) 小程序模块 vxWorks实际采用开发模式 Tornado提供:编辑,编译,调试,性能分析工具,是vxWorks的开发工具 vxWorks:面向对象可以剪裁的实际运行操作系统 2.vxWorks启动方式 <1>Rom方式 (vxWork_rom) vxWorks直接烧入rom <2>Rom引导方式(bootrom+vxWorks) 其中bootrom烧入rom,vxWorks可以通过从串口,网口,硬盘,flash等下载!这里的bootrom不是开发环境中的bootable,在开发环境里bootable指的是vxWorks,downloadable指application 3.调试 <1>attachs/20060907_164540_564.rar 用来在多任务调试时将调试对象绑定到某个任务 <2>任务级调试(attachs/20060907_164540_564.rar taskName) 单个任务的调试不会影响到其他任务的运行,主要用来调用户的应用程序。 全局断点:在调另一任务或本任务时,系统运行本任务断点,则停下。各任务要配合使用。 任务断点:调本任务时,系统运行到本任务断点,则停下。如果没有attachs/20060907_164540_564.rar到本任务,不起作用。 一次性断点:跑到一次之后自动删除。 <3>系统级调试(attachs/20060907_164540_564.rar system) 把所有task和系统core、中断看成一个整体,可用于调试系统和中断。对中断调试,如果不是系统级调试,无论是那种断点都不起作用 !wdbAgent不在调试范围内,当任务级调试时工作在中断方式,系统级调试工作在轮询方式。 !可是使用命令行方式的调试,参看crossWind教程。 4.调度 优先级调度(无条件) 时间片:同优先级,如果时间片没有打开,任务采取先到先运行,运行完毕在交出cpu,如果打开,则轮流使用cpu。 !死循环使比它...

【转】C++/CLI程序进程之间的通讯

 现在,把大型软件项目分解为一些相交互的小程序似乎变得越来越普遍,程序各部分之间的通讯可使用某种类型的通讯协议,这些程序可能运行在不同的机器上、不同的操作系统中、以不同的语言编写,但也有可能只在同一台机器上,实际上,这些程序可看成是同一程序中的不同线程。而本文主要讨论C++/CLI程序间的通讯,当然,在此是讨论进程间通讯,而不是网络通讯。    简介   试想一个包含数据库查询功能的应用,通常有一个被称为服务端的程序,等待另一个被称为客户端程序发送请求,当接收到请求时,服务端执行相应功能,并把结果(或者错误信息)返回给客户端。在许多情况中,有着多个客户端,所有的请求都会在同一时间发送到同一服务端,这就要求服务端程序要更加高级、完善。   在某些针对此任务的环境中,服务端程序可能只是众多程序中的一个程序,其他可能也是服务端或者客户端程序,实际上,如果我们的数据库服务端需要访问不存在于本机的文件,那么它就可能成为其他某个文件服务器的一个客户端。一个程序中可能会有一个服务线程及一个或多个客户线程,因此,我们需小心使用客户端及服务端这个术语,虽然它们表达了近似的抽象含义,但在具体实现上却大不相同。从一般的观点来看,客户端即为服务端所提供服务的"消费者",而服务端也能成为其他某些服务的客户端。    服务端套接字   让我们从一个具体有代表性的服务端程序开始(请看例1),此程序等待客户端发送一对整数,把它们相加之后返回结果给客户端。   例1: using namespace System; using namespace System::IO; using namespace System::Net; using namespace System::Net::Sockets; int main(array<String^>^ argv) { if (argv->Length != 1) { Console::WriteLine("Usage: Server port"); Environment::Exit(1); } int port = 0; try { port = Int32::Parse(argv[0]); } catch (FormatException^ e) { Console::Wri...