系统分析与设计课程知识点总结

一.前言
我们课程采用的课本是《设计模式解析》(第二版),老师讲的内容以书为基础,在此之上做了一些扩展。这里记录一下期末时我总结的知识点,有不对的地方欢迎指正,欢迎转载。
每一章的标号是采用老师的PPT编号。
博客中的图片来自老师PPT或者《设计模式解析》(第二版)。

二.知识点总结


02-OO设计样式
设计方法:
在这里插入图片描述
· 解耦(decouple):是指让各种事物相互独立地行事,或者至少明确地声明之间的关系。
· 抽象(abstraction):是指不同事物之间概念上的联系方式。

耦合性:两个模块间的关联程度;
内聚性:机能相关的程序组合成一个模块的程度。
涟漪效应(ripple effects):强耦合时,一个方法的改变会导致很多相关联的变化。
结构化编程(a.k.a.功能分解,顺序、循环、分支)、函数式编程(a.k.a.声明式编程,面向过程)、逻辑编程(a.k.a.声明式编程,事实+规则=结果)、OO编程。
· 功能分解:将大问题分解成小问题来解决。目标:目标是将问题分割到一个粒度级别,这个级别的问题可以通过几个步骤轻松解决。然后将这些步骤按顺序排列,以解决所有确定的子问题,很快,大问题就解决了。
· 功能分解的问题:以主程序为中心创建设计;创建的设计不能很好地适应变化(需求经常会要求主函数改动)。弱内聚,紧耦合。问题存在的原因:
不好的抽象、封装、模块化。不好的抽象->难以添加新的元素;
封装性和模块性很差,更改会渗透到代码中,依赖关系。

· 关于变化:基于过程的解决问题方法常常导致程序结构不能很好地适应变化。为什么重视变化:代码的改变是软件错误之源;变化是永恒的。
举例子:一个展示形状的程序:增加要展示的形状、改变展示的方法、增加新的功能比如说移动形状。
· 什么是多态:使用基类的形式来引用其派生类的对象,并能够表示出派生类的行为。
优点:提高了代码的可扩展性,提高可维护性(多态前提所保证的)
缺点:无法直接访问子类特有的成员
· 派生类的优点:隐藏各对象之间的差异,以适应需求的变化,增强可扩展性
· 抽象和封装的区别:抽象,是指从众多的事物中抽取出具有共同的、本质性的特征作为一个整体。是共同特质的集合形式。
封装,是将通过抽象所得到的数据信息和操作进行结合,使其形成一个有机的整体。对内执行操作,对外隐藏细节和数据信息。(隐藏实现,开放接口)。
· 对待变更的需求:我们需要改进设计系统和编写代码的方式,以便能够管理更改。给变化留有余地。
· 分析的视角:
概念:职责的集合;规约:方法的集合;实现:代码和数据的集合。
在这里插入图片描述


09-UP and requirements
· UP(unified process):工业标准过程,软件工程过程。过程:将需求转化为软件。
UP Axioms(公理):Use Case and Risk driven用例和风险驱动、Architecture Centric以体系结构为中心、Iterative and incremental 迭代递增。
UP以用户需求user requirements和风险risk驱动。
· UP四个阶段:开端、精心策划、构建、交接;每个阶段一到多次迭代,每次迭代持续时间两到三个月,每次迭代有五个核心工作流:需求、分析、设计、实现、测试。
在这里插入图片描述
其中,大部分工作都在开端和精心设计两个阶段。

· 需求分为功能性需求和非功能性需求。功能性需求:描述系统的行为,与系统的功能性有关;
非功能性需求:描述系统的性能特点比如:架构、扩展性、维护性、可靠性、容错性等。
· 需求的书写:
在这里插入图片描述
用例的写法:
在这里插入图片描述
在事件流中,可以用for和while。


10-Analysis
· 分析工作流Analysis Workflow主要目的:生成分析模型。分析模型只关注类,是问题域(可以理解为business requirements)的一部分。
· 分析的经验法则:使用领域的内行语言;每个图必须展示系统的部分行为;关注大的方面而不是细节;区分问题域和求解域;关联最小化;找出继承关系;尝试给出模型并保持模型的简洁。(这些可以用来作为评价的标尺)
· CRC分析:Class-Responsibility-Collaborators
和名词动词分析一起使用。名词:类名和属性;动词:指责和操作。
· 实现用例:协作图、顺序图。一个例子如下:并行的事件流可以用A、B来区分,数字用来表示发生的顺序:
在这里插入图片描述
(更多UML图的总结,请见我的这篇博客)


11-Design Class
· 设计模型:一个设计系统包含多个子系统,要体现子系统。设计模型是分析模型的细化和求精。
· 设计工作流的工件(Artifacts): 设计子系统、设计类、设计接口、设计的用例实现(设计均为名词)
· 分析类(分为边界类、控制类和实体类。Ppt上没有??)和设计类(图)的区别:
一个分析类可能被分解成一个或多个设计类或接口;在分析阶段类图研究领域的概念,可以理解为从需求中获取,而在设计阶段类图重点描述类与类之间的接口;分析类的三高:高于设计实现(不必理会复杂的设计要求比如系统框架)、高于语言实现(不必理会采用哪一种特性的语言来编写)、高于实现方式(不必考虑采用哪一种具体的实现方式)。
· 设计类的来源:问题域和解决方案域
在这里插入图片描述
· 分析类转为设计类:细化分析类(分析类的抽象更加细节化、增加新的属性以使类能够完整地实现)、将大的分析类拆分、好的分析类应该小巧、自包含?、内聚单元?
细化分析关系:拆分出整体和部分(用组合或聚合连接)
注意标出数据结构的特点如indexed、sorted、set:
在这里插入图片描述
· 设计类应当:指明每个模块的指责、具有完整的属性和完全的描述(可见性、属性名、类型、默认值)、完整的实现方法(可见性、方法名、变量列表、属性、返回值)。例如:
在这里插入图片描述
对类图进行解释说明可以按以下格式:
在这里插入图片描述


12-Design Subsystems
· 接口:用于分离功能;提供统一的插座、接受外部连接;设计实现:通过将特定的类连接在一起进行设计、接口由任意数量的类实现、无法实例化接口
接口应包括:完整的操作名、属性的名称和类型;不允许操作的实现和关系。例如:
在这里插入图片描述
在这里插入图片描述
上例也可用继承实现:
在这里插入图片描述
继承的标志性描述“is a”,图中父类名称“可借条目”,继承和接口都体现多态性
一个更优美的继承设计:
在这里插入图片描述
一个再好一点的设计:继承+接口 , 接口体现了图书馆的“可借阅”功能
在这里插入图片描述
找出接口:关联关系可能需要接口(如果关联需要更好的灵活性)、消息传递可能需要接口(不止一种消息类)、可重用的操作集、相同角色的类、可能需要扩展的类(接口有利于将来扩展)
· 接口的优点:
增加设计和体系结构的的灵活性和可扩展性、一个模型可以被整齐地划分为内聚的子系统(使用接口支持低耦合,减少依赖项的数量);
缺点:
增加复杂性和成本、固定的部件不需要接口(易变性部件需要)。
· 组件:是系统的一个模块,封装它的内容,它在环境中的显示是可替代的
就像一个“黑箱”,外部行为完全由接口定义;因此,它可以被任意具有同样功能(协议)的组件替代。
组件常常依赖于其他组件,为了降低组件间的耦合,常常使用接口:
在这里插入图片描述
· 子系统是一个组件(对一个更大的系统来说,充当分解的一个单元);子系统通过接口连接;子系统用于:独立的设计问题、代表大粒度组件、包装遗留系统。
子系统提供一个高级视图(high-level-view),一个更高级别的抽象


13-Design Patterns
· (非设计模式)模式提供了一个高质量的解决问题的方法。亚历山大指出模式的四要素:
名称、目的(解决什么问题)、如何解决问题、约束。多个模式结合起来可以解决复杂问题。
· 为什么学习设计模式(重要意义)?
重用过去成功的解决方案,不必花费时间重造轮子;
对软件设计而言有一个通用的描述,有利于设计者之间的沟通;
启发思路,帮助我们得到更好的设计;
许多设计模式都使系统易于扩展和维护;
设计模式使我们对OO原则有更深的理解。
· 设计模式不提供代码重用,而是提供经验重用。
· 一个例子:有一个鸭子类,分为很多种鸭子,叫声不同,有的能飞,如何实现?
将能叫和能飞设计成接口,采用多重继承,让鸭子们实现这些接口。
在这里插入图片描述
策略:将变化的方法从基类种取走(例如飞和叫,不是所有子类都能执行);对不同的行为,用接口封装并实现;增加行为不会影响其他类或其他行为。
新的设计:采用代理(优先于继承)
在这里插入图片描述
Delegation代理: Duck代理了FlyBehavior和QuackBehavior这两个行为,将这两个类写入Duck的成员中。(Duck直接调用它们的函数)


14-Façade&Adapter 外观模式和适配器模式
· Façade:为子系统中的一组接口提供统一接口(定义了一个更高级的接口,使子系统更容易使用)。当访问子系统功能的子集时,使用Façade效果好:例如需要从数据库中的部门中获取员工信息,Façade提供的接口可以直接访问员工。Façade减少了处理的方法的数量,减少了类的数量。属于结构型模式。
· 总结:外观模式的作用:主要为访问子系统提供一个更简单的接口(更高级的接口),可以将整个子系统看成一个组件,外观模式为其提供接口,隐藏系统的复杂性。
Facade 类能够将系统作为自己的私有成员包含进来
类图例:
在这里插入图片描述
课本图:
在这里插入图片描述
Adapter 适配器:将一个类的接口转换成客户希望的另一个接口。Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作。
属于结构型模式。
适配器模式举例:火鸡鸭子。
书上图:
(对象适配器):Adapter采用关联方式连接Adaptee
在这里插入图片描述
类适配器:Adapter采用多重继承方式连接Adaptee
在这里插入图片描述
在这里插入图片描述
适配器模式和外观模式的异同:Façade模式简化了接口,而Adapter模式将一个已有的接口转换成另一个接口。
在这里插入图片描述


15-Expanding Horizons
· 对对象的新观点:
对象是“有责任的事务“;不要关注数据;随着实现不断发展以满足非功能约束,它可能会发生更改(这就是我们在默认情况下将属性设置为private的原因);职责来自需求;职责帮助设计、总有实施者、分析就是找出职责、设计就是找出责任的位置;
· 对封装的新观点:
封装可以隐藏任何东西,特别是变化的东西
· 类型的封装:在抽象类的派生或接口实现时,隐藏了类型;此时要求多态性;设计模式中所指的封装更多的就是这种类型的封装。
· 对继承的新观点:相同的行为构成了抽象的子类;通常我们强调的继承是特例化。
· 本书提倡的A&D方法:
这本书提倡的A&D方法经常被称为“预先设计”方法
确定与解决问题相关的主要领域概念
识别系统的用户;
然后开发一个使用这些领域概念的设计,以允许用户完成他们的任务
迭代并充实设计,直到设计可以实现为止
· 敏捷方法(Agile methods):
敏捷方法是开发软件系统所依赖的技术/过程,包括:
经常与客户沟通
采取小步骤(功能明确)
在继续之前,与客户确认这些小步骤
他们强调迭代、反馈和沟通,而不是前期设计、详细分析、图表等
设计模式产生灵活的代码,敏捷代码可以以一种直接的方式改变。

代理模式Proxy
· 定义:一个类代表另一个类的功能,为其他对象提供一种代理以控制对这个对象的访问。
在这里插入图片描述
举例:中介代理房地产商,用户依赖于中介进行买房。


16-Bridge and Factory
· 补充策略模式(Strategy)
定义一系列的算法,把它们一个个封装起来,并且使他们可互相替换,使算法可独立于使用它的客户而变化。意图:根据所处上下文,使用不同的业务规则或算法。行为型模式
原则:对象都具有职责;这些职责不同的具体实现是通过多态的使用完成的;概念上相同的 算法具有多个不同的实现,需要进行管理。
书中类图:
在这里插入图片描述
应用举例:税额计算算法。在一个电子商务系统中,不同的国家使用不同的税额计算算法,可以用Strategy模式将这些规则(算法)封装在一个抽象类中,然后派生出一系列具体类。
加减乘除四个运算,封装在一个抽象类中,派生出一系列具体类,用户根据不同的上下文选择使用不同的运算。
类图特点:一个组成上下文的类具有多个相似的派生类。用户常常依赖Context类
本章习题:
在这里插入图片描述
答案:

  1. 复制和粘贴(对已有代码进行重用);使用switch或if语句,用一个变量指定各种情况;
    使用函数指针或者代理;继承(让派生类用新的方式处理);将整个功能代理给新的对象。

在这里插入图片描述
补充第二题的答案:针对接口而不是实现设计

Bridge 桥模式---------------------------------------------------------------------------------------------------------------
· 意图:将抽象与其实现解耦,使它们可以独立地变化。解耦:让各种事物互相独立地行事,或者至少明确地声明之间的关系;抽象:不同事物之间概念上的联系方式
· 问题:一个抽象类需要有多个派生类的实现,但是会导致类数目出现爆炸增长
· 效果:实现与使用实现的对象解耦,提供了可扩展性,客户对象无需操心实现问题。
· 实例:draw原本是shape类中的方法,现将之解耦
在这里插入图片描述
书上一般结构图:
在这里插入图片描述
例子:将形状这个抽象类和画形状这个实现分离。

· Abstract Factory-------------------------------------------------------------------------------------------------------
抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类
意图:需要为特定的客户提供对象组;问题:需要实例化一组相关的对象
效果:抽象工厂模式将“使用哪些对象”的规则与“如何使用这些对象”的逻辑分开
课本上的通用结构图:
在这里插入图片描述
成员角色:
 抽象工厂(AbstractFactory):客户端直接引用,由未实现的工厂方法组成,子类必须实现其工厂方法创建产品家族。
 具体工厂(ConcreteFactory):实现抽象工厂接口,负责实现工厂方法,一个具体工厂可以创建一组产品。
 抽象产品(AbstractProduct):产品家族的父类,由此可以衍生很多子产品。
 具体产品(Product):衍生自抽象产品,由工厂方法直接创建。


18-How Do Experts Design?========================================
· 模式的角色:每一个模式都是差异运算子,若干算子之后,得到完整的设计。具有一般性也具有特殊性,每个模式都使整体有所差异。
· 添加特征的创建模式:首先给出最简单的系统描述,然后逐个添加模式进行差异化操作(变化、增加、细化),直到最后形成整体。
· CVA(commonality and variability analysis, CVA):共性和可变性分析。
· MVC模式(model-view-controller):模型-视图-控制器模式。用于应用程序的分层开发。

OO设计六大原则

  1. 单一职责原则SRP:对于一个类,有且仅有一个引起它变化的原因。
  2. 开放封闭原则OCP:一个软件实体应该对扩展开放,对修改关闭。
  3. 里氏替换原则LSP:所有引用基类的地方必须能透明地使用其子类的对象。(只要父类能出现的地方子类就可以出现,而且替换为子类也不会 产生任何错误或异常,反过来不一定)
  4. 依赖倒置原则DIP:高层模块不应该依赖低层模块,两个都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
  5. 接口隔离原则ISP:一个类对另一个类的依赖应该建立在最小的接口上,客户端不应该依赖它不需要的接口。
  6. 迪米特法则LOD:一个软件实体应当尽可能少地与其他实体发生相互作用。
    其他的OO设计原则:面向接口编程;封装变化;类是关于行为的;代理优先于继承。

装饰者模式Decorator Pattern
· 定义:动态地给一个对象添加一些额外的职责,同时不改变其结构。就添加功能来说,Decorator模式比生成子类更为灵活。
在这里插入图片描述
类图特点:装饰器和组件之间,既有泛化(或实现),又有组成。


Observer 模式=============================================
· 定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并更新。
· 结果:将观察者与被观察者解耦,使得它们之间的依赖性更小。
· 例子:用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
类图特点:两个泛化,一个是观察者,一个是中心对象,形成一个环。


Template Method=模板方法======================================
· 定义:定义一个操作中算法的骨架,而将一些步骤延迟到子类中。不改变算法的结构而重定义它的步骤。
· 通用模式结构图:

在这里插入图片描述
特点:继承关系,派生类和父类的方法完全一致


各种工厂模式(创建型模式)
· 包括:Abstract Factory抽象工厂;Builder建造者;Factory Method 工厂方法;Prototype原型;Singleton单例。
· 工厂的定义:工厂是用来实例化其他对象的方法(静态或非静态)、对象或其他任何实体。
· 工厂的优点:能够提高内聚性、松散耦合、使集成更加容易,并有助于测试。
· 一条管理对象创建的准则:对象要么构造其他对象,要么使用其他对象,决不要两者兼顾。

单例模式Singleton------------------------------------------------------------------------------------------------------------
· 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
· 工作原理:调用这个方法时,检查对象是否被实例化;如果是,该方法仅仅返回对该对象的一个引用;如果尚未实例化,该方法实例化该对象并返回对此新实例的一个引用。
· 通用结构图:
在这里插入图片描述
结构特点:私有成员一般包括一个静态成员instance。

Object Pool对象池模式----------------------------------------------------------------------------------------------------
· 定义:对象池模式(The Object Pool Pattern)是单例模式的一个变种,提供获取一系列相同对象实例的入口。当我们需要对象来代表一组可替代资源的时候就变的很有用,每个对象每次可以被一个组件使用。
· 意图:在创建对象比较昂贵,或者对于特定类型能够创建的对象数目有限制时,管理对象的重用。
· 通用结构图:
在这里插入图片描述
特点:命名中一般带有pool,resource等字眼,方法一般是getInstance等。
效果:使管理实例创建的逻辑与实例被管理的类分离,可以内聚出更好的设计。
Factory Method工厂方法---------------------------------------------------------------------------------------------------
· 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。(派生类对实例化哪个类做出决策)
· 通用结构图:
在这里插入图片描述
· 和抽象工厂的区别:抽象工厂是针对产品族概念,而工厂方法只生产一种产品,抽象工厂是工厂方法的一种推广。

享元模式Flyweight-----------------------------------------------------------------------------------------------------------
· 定义:主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
· 实现:尝试重用现有的同类对象,如未找到匹配的对象,则创建新对象。
· 例子:
在这里插入图片描述


状态模式:类的行为是基于它的状态改变的,属于行为型模式。
上下文决定状态,状态决定行为。
在这里插入图片描述


25-Refactoring重构
· 什么是重构:外部行为不变,内部结构优化。完成后再提升设计。
· 如何使重构安全:重构需要系统化、递增式、安全。
· 重构是需要的:一次性完成良好的设计是困难的;重构改善软件的设计;重构使得软件/代码更易于理解;重构帮助寻找bug;重构有利于更快的编程。
· 重构以增量推进系统的设计,优点是:减少代码、简化混乱结构。
· 重构的原理规则:改变内部结构使其易于修改;再不改变系统外部行为的情况下重整内部结构;(性能优化往往使代码更难理解但运行更快,这和重构相反,重构目的是使代码易读易修改);使用重构模式;经常测试。
· 什么时候重构:在添加功能前后;在修正错误时重构;在检查代码时重构。
· 在什么地方重构:重复的代码;长方法的代码;大的类;过长的参数表;扩散的变化;特性嫉妒(一个方法使用了其他类的大量信息);数据团;分治语句;并行的继承层次;不值得拥有的类;临时变量;注释;数据类。


常见设计模式优缺点及应用总结:

  1. 外观模式:查找数据库部门中的职员信息
    优点:减少系统相互依赖;提高灵活性和安全性。
    缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
  2. 适配器模式:火鸡和鸭子问题
    优点:可以让两个没有关联的类一起运行;提高了类的复用;增加了类的透明度;灵活性好。
    缺点:过多地使用适配器,会让系统非常零乱,不易进行整体把握。
  3. 代理模式:客户中介房地产商
    优点:职责清晰;高扩展性;智能化。
    缺点:由于在客户端和真实主体之间增加了代理对象,因此有些类型的代理模式可能造成请求的处理速度慢;实现代理模式需要额外的工作,有些代理模式的实现很复杂。
  4. 策略模式:加减乘除封装在一个抽象类中,派生出具体类,根据上下文选择不同的策略。
    优点:算法可以自由切换;避免使用多重条件判断;扩展性良好。
    缺点:策略类会增多;所有策略类都需要对外暴露。
  5. 桥模式:将画图(draw)这个功能实现与形状(shape)这个抽象类解耦
    优点:抽象和实现的分离;优秀的扩展能力;实现细节对客户透明。
    缺点:桥模式的引入会增加系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者对抽象进行设计与编程。
  6. 抽象工厂:
    优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
    缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的Creator中加代码,又要在具体的工厂中加代码。

学习的过程中,配合课本后面的思考题可以有更好的理解。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值