软考-软件设计基础

软件设计概述

一、软件设计基本原则

1 . 模块

是指执行某一特定任务的数据结构和程序代码。

  • 将模块的接口和功能定义为其外部特性
  • 将模块的局部数据和实现该模块的程序代码称为内部特性。

在模块设计时,最重要的原则就是实现信息隐蔽和模块独立。

2 . 信息隐蔽

将每个程序的成分隐蔽或封装在一个单一的设计模块中,并且尽可能少地暴露其内部的处理过程。
信息隐蔽可以提高软件的可修改性、可测试性和可移植性。

3 . 模块独立

模块独立是指每个模块完成一个相对独立的特定子功能,并且与其他模块之间的联系最简单。
通常用耦合(模块之间联系的紧密程度)和内聚(模块内部各元素之间联系的紧密程度)两个标准来衡量,我们的目标是“高内聚低耦合”。

4 . 内聚

指模块内部各元素之间联系的紧密程度。模块的内聚类型分为7种,根据内聚度从高到低的排序。
在这里插入图片描述

  • (1)功能内聚:指模块内所有元素共同完成某一功能,联系紧密 ,缺一不可,是最强的内聚类型。
  • (2) 顺序内聚:指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素输出是下一功能元素的输入。即一个模块完成多个功能,这些模块又必须顺序执行。
  • (3) 通信内聚:指模块内所有处理元素都在同一个数据结构上操作,或者指各处理使用相同的输入数据或者产生相同的输出数据。
  • (4) 过程内聚:构件或者操作的组合方式是,允许在调用前面的构件或操作之后,马上调用后面的构件或操作,即使两者之间没 有数据进行传递。
  • (5)时间内聚:把需要同时执行的动作组合在一起形成的模块为时间内聚模块,所有的动作需在同一个时间段内执行。
  • (6) 逻辑内聚:把几种相关的功能组合在一起, 每次被调用时, 由传送给模块参数来确定该模块应完成哪一种功能。
  • (7) 偶然内聚:模块内各部分之间没有联系,或者有联系,这种联系也很松散,是内聚度最低的模块。

例:某模块实现两个功能:向某个数据结构区域写数据和从该区域读数据。该模块的内聚类型为( D )内聚。
A. 过程 B. 时间 C. 逻辑 D. 通信

5 .耦合

指模块之间联系的紧密程度。模块的耦合类型分为7种,根据耦合度从低到高排序。
在这里插入图片描述

  • (1)非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。这种模块的耦合度最低、模块独立性最强。
  • (2)数据耦合:指两个模块之间有调用关系,传递的是简单的数据值,相当于高级语言的值传递。
  • (3)标记耦合: 指两个模块之间传递的是数据结构,如高级语言中的数组名、记录名、文件名等这些名字即标记,其实传递的是这个数据结构的地址。
  • (4)控制耦合:指一个模块调用另一个模块时,传递的是控制变量(如开关、标志等),被调模块通过该控制变量的值有选择地执行模块内某一功能。
  • (5)外部耦合:一组模块都访问同一全局简单变量而不是同一全 局数据结构,而且不是通过参数表传递该全局变量的信息。
  • (6)公共耦合:指一组模块都访问同一个公共数据环境,如全局数据结构,共享通信区。
  • (7)内容耦合 : 一个模块直接使用另一个模块的内部数据,或通过非正常入口而转入另一个模块内部。是最差的耦合。

6 .深度

表示软件结构中控制的层数,它往往能粗略地标志一个系统的大小和复杂程度。如果层数过多则应该考虑是否有许多管理模块过分简单,能否适当合并。

7 .宽度

是软件结构内同一个层次上的模块总数的最大值。宽度越大系统越复杂。对宽度影响最大的因素是模块的扇出。

8 .扇出

模块的扇出是指一个模块直接控制(调用)的下层模块数目。扇出过大意味着模块过分复杂,需要控制和协调过多的下级模块;扇出过小也不好。设计得好的系统平均扇出是3或4。

9 .扇入

是指有多少个上级模块调用它,扇入越大则共享该模块的上级模块数目越多。

在模块分解时需要注意:

  • 保持模块的大小适中
  • 尽可能减少调用的深度
  • 直接调用该模块的次数应该尽最多,但调用其他模块的次数则不宜过多(扇入大,扇出小)。好的软件设计结构顶层高扇出 ,中间扇出较少,底层高扇入。
  • 保证模块是单入口、单出口的
  • 模块的作用域应该在模块之内
  • 功能应该是可预测的

二、结构化设计方法

一、软件设计

从工程管理的角度,将软件设计分为:

  • 概要设计阶段
  • 详细设计阶段

从技术的角度,将软件设计分为:

  • 体系结构设计
  • 数据设计
  • 接口设计
  • 过程设计

在这里插入图片描述

一般通过功能划分过程来完成软件结构设计。功能划分过程从需求分析确立的目标系统的模型出发,对整个问题进行分割,使其每一部分用一个或几个软件模块加以解决,整个问题就解决了。
在这里插入图片描述

二、模块的分类

1.传入模块:从下属模块取数据,进行某些处理,再将其传送给上级模块。
2.传出模块:从上级模块取得数据,进行某些处理,传送给下属模块。
3.变换模块:从上级模块取来数据,进行特定处理后,送回原上级模块。
4.协调模块:对其下属模块进行控制和管理的模块。
在这里插入图片描述

例:模块A提供某个班级某门课程的成绩给模块B,模块B计算平均成绩、最高分和最低分,将计算结果返回给模块A,则模块B 在软件结构图中属于( C )模块。
A. 传入 B. 传出 C. 变换 D. 协调

三、McCabe复杂性度量

McCabe方法是一种软件质量度量方法,它是基于对程序拓扑结构复杂度的分析。

二种方法计算复杂度:

  • 流图G的圈复杂度V(G),为V(G)=E-N+2,E是流图中边的数量,N是流图中结点的数量
  • 流图中区域的数量等于圈复杂性
    在这里插入图片描述
    在这里插入图片描述
    将程序流程图简化成控制流图时,应注意:
  • 在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。
  • 对区域计数时,图形外的区域也应记为一个区域。

在这里插入图片描述

例1:采用McCabe度量法计算下列程序图的环路复杂性为 ( )。
A. 2 B. 3 C. 4 D. 5
在这里插入图片描述

三、面向对象设计

一、基本概念

对象   类    继承    封装    消息    多态性
  • 对象(Object)

    有意义的一切事物都是对象
    
    • 它是系统用来描述客观事物的一个实体,是构成系统的一个基本单位。
    • 对象包括:对象名、属性(静态特征)和方法(动态特征)
    • 对象之间通过消息进行通信。
  • 类(Class)

    • 具有相同属性和相同操作的对象的集合
    • 对象是类的实例,没有实例的类称为抽象类
  • 继承(Inheritance)

    • 它使子类可以继承父类的属性和方法
    • 继承增加了软件复用的机会
  • 单一继承与多重继承

  • 封装(Encapsulation)

    • 就是把对象的属性和方法结合成一个独立的系统单位, 并尽可能隐蔽对象的内部细节。
  • 封装使对象具有2个部分:接口部分和实现部分
    在这里插入图片描述

  • 多态(polymorphism)

    • 指同一个操作作用于不同的对象时可以有不同的解释, 并产生不同的执行结果。
  • 多态分两种:

    • 通用多态
    • 特定多态

通用多态又分为参数多态和包含多态

  • 参数多态:采用参数化模板,通过给出不同的类型参数, 使得一个结构有多种类型。
  • 包含多态:同样的操作可用于一个类型及其子类型。(注 意是子类型,不是子类。)包含多态一般需要进行运行时 的类型检查。

特定多态分为强制多态和过载多态。

  • 强制多态:编译程序通过语义操作,把操作对象的类型强行加以变换,以符合函数或操作符的要求。
  • 过载多态:同一个名(操作符﹑函数名)在不同的上下文中有不同的类型。

例1:在面向对象技术中,不同的对象在收到同一消息时可以 产生完全不同的结果,这一现象称为(),它由()机制来 支持。利用类的层次关系,把具有通用功能的消息存放在高层次,而不同的‘实现这一功能的行为放在较低层次,在这 些低层次上生成的对象能够给通用消息以不同的响应。
A. 绑定 B. 继承 C. 消息 D. 多态
A. 绑定 B. 继承 C. 消息 D. 多态

例2:在多态的几种不同形式中,( 37) 多态是一种特定的 多态,指同一个名字在不同上下文中可代表不同的含义。
A.参数 B.包含 C.过载 D.强制

  • 消息(Message)
    • 是指向对象发出的服务请求
    • 对象直接用消息的方式传递信息,而不是参数
    • 包括:接收对象名、调用的操作名和适当的参数(如有必要)
  • 对象间的消息传递是OO方法的基本原则
  • 消息包括
    • 同步消息,请求者需要等待响应者返回
    • 异步消息,请求者不需要等待响应者返回,发出消息后可以继续自己的后续工作(和函数调用有本质区别)

二、面向对象设计

面向对象设计的基本准则是:

复制代码

模块化     抽象     信息隐藏     高内聚、低耦合

面向对象设计(含设计模式)的原则:

(1)单一职责原则。
(2)开放–封闭原则。
(3)李氏(Liskov)替换原则。
(4)依赖倒置原则。
(5)接口隔离原则。
(6)组合重用原则。
(7)迪米特(Demeter)原则。

四、用户界面设计

用户界面设计的原则:

  • (1)置于用户控制之下
  • (2)减少用户的记忆负担
  • (3)保持界面的一致性

五、设计模式

一、设计模式(Design pattern)

是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

  • 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性;
  • 设计模式使代码编制真正工程化;
  • 设计模式是软件工程的基石脉络,如同大厦的结构一样。

二、设计模式分为三大类

  • 创建型模式主要用于创建对象。共五种:工厂方法模式、抽象 工厂模式、单例模式、建造者模式、原型模式。
  • 结构型模式主要用于处理类或对象的组合。共七种:适配器 模式、装饰器模式、代理模式、外观模式、桥接模式、组合模 式、享元模式。
  • 行为型模式主要用于描述类或对象怎样交互和怎样分配职责。 共十一种:策略模式、模板方法模式、观察者模式、迭代子模 式、责任链模式、命令模式、备忘录模式、状态模式、访问者 模式、中介者模式、解释器模式。

1.工厂方法模式(Factory Method)

也叫虚拟构造器模式,它定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。 在工厂方法模式中,工厂父类负责定义创建产品对象的公共 接口,而工厂子类则负责生成具体的产品对象,这样做的目 的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

工厂方法模式结构
在这里插入图片描述

工厂方法模式包含如下角色: 
    Product:抽象产品 
    ConcreteProduct:具体产品 
    Factory:抽象工厂 
    ConcreteFactory:具体工厂

2.抽象工厂模式(Abstract Factory)
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。属于对象创建型模式。
抽象工厂模式与工厂方法模式最大的区别:工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个 产品等级结构。
在这里插入图片描述
在这里插入图片描述

3.建造者模式(Builder Pattern、生成器模式)
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。
在这里插入图片描述
在这里插入图片描述

4.原型模式(Prototype)
用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。 原型模式允许一个对象再创建另外一个可定制的对象,无须知道任何创建的细节。
在这里插入图片描述
在这里插入图片描述

5.单例模式(Singleton)
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务。
在这里插入图片描述

6.适配器模式(Adapter Class/Object)
将一个类的接口转换成客户希望的另外一个接口。使得原本不相容的接口可以协同工作。
适用性:

  • 想使用一个已经存在的类,而它的接口不符合你的需求。
  • 想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
    在这里插入图片描述
    在这里插入图片描述

7.桥接模式(Bridge)
将抽象部分与它的实现部分分离,使它们都可以独立地变化。 如果要绘制矩形、圆形、椭圆、正方形,至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色、绿色、 蓝色等。
在这里插入图片描述

8.组合模式(Composite)
将对象组合成树形结构以表示“部分-整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。
组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容 器对象和叶子对象。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

9.装饰模式(Decorator)
动态地给一个对象添加一些额外的职责。提供了用子类扩展功能的一个灵活的替代,但比生成子类更为灵活。
装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

10.外观模式(Facade)
定义了一个高层接口,为子系统中的一组接口提供一个一致的界面,从而简化子系统的使用。
在这里插入图片描述

11.享元模式(Flyweight)

提供支持大量细粒度对象共享的有效方法。

面向对象技术可以很好地解决灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。

如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。

享元模式通过共享技术实现相同或相似对象的重用。

12.代理模式(Proxy)
给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
在这里插入图片描述
在这里插入图片描述

13.解释器(Interpreter)
定义语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”意思是使用规定格式和语法的代码。
例:构造一个语言解释器,使得系统可以执行整数间的乘、除和求模运算。如用户输入表达式“3 * 4 / 2 % 4”,输出结果为2。
在这里插入图片描述

14.模板方法(Template Method)

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
在这里插入图片描述
在这里插入图片描述

例:银行业务办理流程在银行办理业务时,一般包含几个基本步骤,首先取号排队,然后办理具体业务,最后对银行工作人员进行评分。无论具体业务是取款、存款还是转账,基本流程都一样。
在这里插入图片描述

15.责任链(Chain of Responsibility)
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
在这里插入图片描述
在这里插入图片描述

16.命令模式(Command)

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
对命令进行封装,将发出命令的责任和执行命令的责任分割开。请求的一方不必知道接收请求的一方的接口,也不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
在这里插入图片描述
在这里插入图片描述

17.迭代器模式(Iterator)
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
怎样遍历一个聚合对象,又不需要了解聚合对象的内部结构, 还能够提供多种不同的遍历方式,这就是迭代器模式所要解决的问题。
在这里插入图片描述

18.中介者模式(Mediator)
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
在这里插入图片描述

19.备忘录模式(Memento)
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
为了使软件更加人性化,对于误操作,需要提供一种类似“后悔药”的机制,让软件可以回到误操作前的状态,因此需要保存用户每一次操作后系统的状态,一旦出现误操作,可以把存储的历史状态取出即可回到之前的状态。
在这里插入图片描述

20.观察者模式(Observer)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
在这里插入图片描述

21. State模式(状态)
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
在这里插入图片描述
在这里插入图片描述

22.策略模式(Strategy)
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
在这里插入图片描述
在这里插入图片描述

23.访问者模式(Visitor)
表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值