961全部内容链接
文章目录
- 软件体系结构及体系结构风格的概念
- 设计模式的概念
- 模块化设计的基本思想及概念
-
- 抽象
- 分解(逐步求精)
- 模块化
- 封装
- 信息隐藏
- 功能独立
-
- 内聚与耦合的概念
-
- 常见的内聚与耦合类型
- 软件重构的概念(再工程)
- 软件体系结构的UML建模
-
- 包图
- 类图
- 构件图
- 顺序图
- 部署图
- 接口的概念
- 面向对象设计原则
-
- 开闭原则
- Liskov替换原则
- 依赖转置原则
- 接口隔离原则
- 内聚与耦合的概念
软件体系结构及体系结构风格的概念
软件体系结构(architecture)并非是可运行的软件,是一种使设计师能够在更高层次分析“设计”是否满足需求的一种表示。常见的体系结构有单主机结构、B/S架构和C/S架构。
软件体系结构的风格:
-
数据为中心的体系结构:一些数据(比如一个文件或者数据库)保存在整个结构的中心,并且被其他部件频繁地使用、添加、删除、或者修改
-
调用和返回风格的体系结构:这种风格使一个软件设计者设计出非常容易修改和扩充的体系结构。包含:主程序/子程序风格体系结构和远程过程调用风格的体系结构。
设计模式的概念
在许多面向对象系统中,存在一些类和对象的重复出现的模式。这些模式求解特定的设计问题,使面向对象设计更灵活,并最终可复用。这些模式帮助设计者复用以前成功的设计,设计者可以把这些模式应用到新的设计中。
一个设计模式通常可用4个基本要素来描述:
- 模式名称:用于描述模式的助忆符。设计模式名应具有实际的含义,能反映模式的适用性和意图。就是设计模式的名字,如工厂模式,单例模式
- 问题:描述何时使用模式,解释设计问题以及应用模式所必须的环境和条件。
- 解决方案:描述构成设计方案的各元素、它们之间的关系、各自的职责和协作方式
- 效果:描述模式应用的效果以及使用模式时的折中问题
常见的设计模式有:
- 创建型模式:工厂模式,抽象工厂,构建器,原型,单例
- 结构型模式:适配器,桥接,组合,装饰器等
- 行为型模式:解释器,模板方法,职责链,命令,迭代器,观察者等
模块化设计的基本思想及概念
抽象
抽象,是在软件设计的规模逐渐增大的情况下,控制复杂性的基本策略。
抽象的过程是从特殊到一般的过程,上层概念是下层概念的抽象,下层概念是上层概念的精化和细化。
软件工程过程的每一步都是对较高一级抽象的解作一次具体化的描述。
两种主要的抽象手段:
- 过程抽象(也称为功能抽象):是指任何一个完成明确定义功能的操作都可被使用者当作单个实体看待,尽管这个操作实际上是由一系列更低级的操作来完成的
- 数据抽象:是指定义数据类型和施加于该类型对象的操作,并限定了对象的取值范围,只能通过这些操作修改和观察数据
分解(逐步求精)
逐步求精,把问题的求解过程分解成若干步骤或阶段,每步都比上步更精化,更接近问题的解法
抽象使得设计者能够描述过程和数据而忽略低层的细节,而求精有助于设计者在设计过程中揭示低层的细节
模块化
模块化,即把软件按照规定原则,划分为一个个较小的,相互独立的但又相互关联的部件,实际上是系统分解和抽象的过程。
模块是数据说明、可执行语句等程序对象的集合,它是单独命名的,并且可以通过名字来访问。例如,过程。函数、子程序、宏等。
- 巧合内聚(偶然内聚):将几个模块中没有明确表现出独立功能的相同程序代码段独立出来建立的模块称为巧合内聚模块
- 逻辑内聚:指完成一组逻辑相关任务的模块,调用该模块时,由传送给模块的控制型参数来确定该模块应执行哪一种功能
- 时间内聚:指一个模块中的所有任务必须在同一时间段内执行。例如初始化模块和终止模块
- 过程内聚:指一个模块完成多个任务,这些任务必须按指定的过程(procedural)执行。
- 通信内聚:指一个模块内所有处理元素都集中在某个数据结构的一块区域中。
- 顺序内聚:指一个模块完成多个功能,这些功能又必须顺序执行。
- 功能内聚:指一个模块中各个部分都是为完成一项具体功能而协同工作,紧密联系,不可分割的。
一般模块之间可能的耦合方式有七种类型:
类图
类图在上一章有详细讲解。
构件图
TODO
顺序图
这个上一章说过了
部署图
TODO
接口的概念
面向对象设计原则
面向对象设计原则参考
开闭原则
开闭原则(Open Closed Principle, OCP)是指对扩展开放,对修改关闭。通俗的话说,当你需要对功能进行变化时,可以在不更改原有源代码的情况下扩展新的代码。
实现开闭原则的常用方法:
- 抽象约束、封装变化:通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。
- 使用继承:通过继承原有类,扩展其方法。
- 使用接口:调用时尽量调用接口而非调用类。如调用排序方法时,调用 Sort接口,而非调用具体的BubbleSort类。
- 使用设计模式:如代理模式,装饰器模式等。比如可以使用Spring的AOP功能来遵循开闭原则。
- 其他各种各样的方法,开闭原则是一个原则,不同的情况使用不同的方式来遵循这个原则,考试中应该会让举几个例子,或者给出例子让考生描述如何遵循开闭原则。
开闭原则的作用:
- 对软件测试的影响:软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的测试代码仍然能够正常运行。
- 可以提高代码的可复用性:粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。
- 可以提高软件的可维护性:遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。
Liskov替换原则
Liskov替换原则(Liskov Substitution Principle,LSP)也称为里氏替换原则。里氏替换原则是针对继承提出的,原则为:子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。
总结为以下几点:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
- 子类中可以增加自己特有的方法
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松(比如父类中的方法参数为Map,则子类中就要用HashMap)
- 当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的的输出/返回值)要比父类的方法更严格或相等(比如父类方法返回Map,则子类实现父类时,该方法也返回Map,或者可以更严格,返回HashMap)
里氏替换原则的作用:
- 里氏替换原则是实现开闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
- 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
依赖转置原则
依赖倒置原则(Dependence Inversion Principle,DIP)定义为:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。核心思想为:要面向接口编程,不要面向实现编程。
依赖转置的实现方式有:
- 每个类尽量提供接口或抽象类,或者两者都具备。
- 变量的声明类型尽量是接口或者是抽象类。
- 任何类都不应该从具体类派生。
- 使用继承时尽量遵循里氏替换原则。
依赖转置原则的作用:
- 依赖转置原则可以降低类间的耦合性。
- 依赖转置原则可以提高系统的稳定性。
- 依赖转置原则可以减少并行开发引起的风险。
- 依赖转置原则可以提高代码的可读性和可维护性。
接口隔离原则
接口隔离原则(Interface Segregation Principle,ISP):尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。这里的客户指的是使用该接口的人。
接口隔离原则的实现方式:
- 接口尽量小,但是要有限度。一个接口只服务于一个子模块或业务逻辑。
- 为依赖接口的类定制服务。只提供调用者需要的方法,屏蔽不需要的方法。
- 了解环境,拒绝盲从。每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同,深入了解业务逻辑。
- 提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
接口隔离原则的优点:
- 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
- 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。
- 如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险。
- 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。
- 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码。
内聚与耦合的概念
这个在上面的功能独立中已经说明
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!