架构师训练营第二周总结

发布于: 2020 年 06 月 17 日

1.软件的本质与未来

1.1编程语言的发展历史

二进制

汇编语言

basic

perl

c

c++

Java

1.2编程语言的本质

编程的目的:用计算机解决现实世界的问题

编程的过程即:在计算机所能理解的"模型”( 解空间)和现实世界(问题空间)之间,建立一种联系。

编程语言是一种“抽象”的机制,问题是对“谁”来抽象:

问题领域:

包含与系统所要解决的问题相关的实物和概念的空间。

抽象的种类:

- 机器代码和汇编语言

对机器进行抽象

- 非结构化语言的高级语言(Basic , Fortran等)

对计算机的逻辑进行抽象

- 结构化程序设计

开始对问题领域进行一定程度的抽象

- 面向对象的程序设计

直接表达问题空间内的元素

1.2.1 编程方法的演进:

汇编语言->高级语言-> 结构化语言->面向对象语言

编程的核心要素:

1.2.2 什么是面向对象编程?

1. 第一个成功的面向对象的语言Smalltalk 描述:

- 万物皆为对象

- 程序是对象的集合,它们通过发送消息来告知彼此所要做的。

- 每个对象都有自己的由其他对象所构成的存储。

- 每个对象都拥有其类型。

- 某一特定类型的所有对象都可以接收同样的消息。

C++和Java等后期的面向对象语言,都是在这个定义的基础、上设计的。

2. 什么是对象?

Booch对于对象的描述:对象具有状态、行为和标识。

- 状态:表明每个对象可以有自己的数据。

- 行为:表明每个对象可以产生行为。

- 标识:表明每个对象都区别于其它的对象。( 唯一的地址)

3. 面向对象编程的三要素(特征)封装性( Encapsulation )

隐藏实现细节( 访问控制)

定义接口

继承性( Inheritance )

IS一A关系

· HAS一A关系(组合)

多态性( Polymorphism)

后期绑定(虚函数)

向上转形(Up Casting)

1.2.3 面向对象编程与面向对象分析

面向对象编程不是使用面向对象的编程语言进行编程,而是利用多态特性进行编程。面向对象分析是将客观世界,即编程的业务领域进行对象分析。

充血模型与贫血模型

领域驱动设计DDD

1.2.4 面向对象设计的目的和原则

面向对象设计的目的

强内聚、低耦合,从而使系统

易扩展一易于增加新的功能

更强壮一不容易被粗心的程序员破坏

可移植一能够在多样的环境下运行

更简单一容易理解、 容易维护

面向对象设计的原则

为了达到上述设计目标,有人总结出了多种指导原则

“原则”是独立于编程语言的,甚至也可以用于非面向对象的编程语言中。

1.2.5 设计模式( design patterns )

设计模式是用于解决某一种问题的通用的解决方案。

设计模式也是语言中立的,

设计模式贯彻了设计原则。

GangofFour (Erich Gamma, Richard Helm, Ralph Johnson and John Visides)提出了三大类23种基本的设计模式

创建模式

行为模式

结构模式

在更细分的领域当中还可以总结出许多设计模式:

并发编程模式

Java EE模式

1.2.6 框架(frameworks )

框架是用来实现某一类应用的结构性的程序,是对某 类架构方案可复用的设计 与实现如同框架结构的大厦的框架

简化应用开发者的工作

实现了多种设计模式,使应用开发者不需要花太大的力气,就能设计出结构良好的程序来不同领域的框架

微软公司为Windows编程开发了MFC框架。

Java为它的GUI (图形用户界面)开发了AWT框架。

还有许多开源的框架: MyBatis, Spring等。

Web服务器也是框架: Tomcat

1.2.7 框架VS工具

框架调用应用程序代码应用程序代码调用工具

架构师用框架保证架构的落地架构师用工具提高开发效率

2.面向对象设计原则

2.1软件设计的“臭味"

软件设计的最终目的,是使软件达到“ 强内聚、松耦合",从而使软件:

易扩展一易于增加新的功能

更强壮一不容易被粗心的程序员破坏

可移植一能够在多样的环境下运行

更简单一容易理解、容易维护

与之相反,一个“不好的”软件,会发出如下”臭味”:

僵硬一不易改变。

脆弱一只想改A,结果B被意外破坏。

不可移植一 不能适应环境的变化。

导致误用的陷阱一 做错误的事比做正确的事更容易,引诱程序员破坏原有的设计。晦涩一代码难以理解。

过度设计、copy一paste代码。

僵化性(Rigidity) :很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的改动。

如果单一的改动会导致依赖关系的模块中的连锁改动,那么设计就是僵化的,必须要改动的模块越多,设计就越僵化。

脆弱性(Fragility) :对系统的改动会导致系统中和改动的地方无关的许多地方出现问题。

出现新问题的地方与改动的地方没有概念上的关联。要修正这些问题又会引出更多的问题,从而使开发团队就像一只不停追逐自己尾巴的狗一样。

牢固性(Immobiliy) :很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。

设计中包含了对其他系统有用的部分,而把这些部分从系统中分离出来所需的努力和风险是巨大的。

粘滞性(Viscosity):做正确的事情比做错误的事情要困难。

面临一个改动的时候,开发人员常常会发现会有多种改动的方法。有的方法会保持系统原来的设计,而另外一些则会破坏设计,当那些可以保持系统设计的方法比那些破坏设计的方法跟难应用是,就表明设计具有高的粘滞性,作错误的事情就很容易。

不必要的复杂性(Needless Complexity) :设计中包含有不具任何直接好处的基础结构

如果设计中包含有当前没有用的组成部分,他就含有不必要的复杂性。当开发人员预测需求的变化,并在软件中放置了处理那些潜在变化的代码时,常常会出现这种情况。

不必要的重复(Needless Repetition) :设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。

当copy, cut, paste 编程的时候,这种情况就会发生。

晦涩性(Opacity) :很难阅读、理解。没有很好的表现出意图。

代码可以用清晰、富有表现力的方式编写,也可以用晦涩、费解的方式编写。一般说来,随着时间的推移,代码会变得越来越晦涩。

2.2 OO设计原则

2.2.1 O0D原则一:开/闭原则(OCP)

OCP 一 Open/Closed Principle

对于扩展是开放的(Open for extension )

对于更改是封闭的( Closed for modification )

简言之:不需要修改软件实体(类、模块、函数等) ,就应该能实现功能的扩展。

传统的扩展模块的方式就是修改模块的源代码。如何实现不修改而扩展呢?

关键是抽象!

2.2.2 O0D原则二:依赖倒置原则(DIP)

DIP 一 Dependency Inversion Principle

高层模块不能依赖低层模块,而是大家都依赖于抽象;

抽象不能依赖实现,而是实现依赖抽象。

DIP倒置了什么?

模块或包的依赖关系

开发顺序和职责

软件的层次化

高层决定低层

高层被重用

框架的核心

好莱坞规则:

Don't call me, Ill call you.

倒转的层次依赖关系

2.2.3 O0D原则三: Liskov替换原则(LSP )

在Java/C++这样的静态类型语言中,实现OCP的关键在于抽象,而抽象的威力在于多态和继承。

一个正确的继承要符合什么要求呢?

答案: Liskov 替换原则

1988年,Barbara L iskov描述这个原则:

·若对每个类型T1的对象01,都存在一个类型T2的对象o2,使得在所有针对T2编写的程序P中,用o1替换02后,程序P的行为功能不变,则T1是T2的子类型。

· 简言之:子类型(subtype) 必须能够替换掉它们的基类型(base type) 。

2.2.4 O0D原则四:单一职责原则(SRP )

SRP 一 Single Responsibilit Principle

又被称为“内聚性原则( Cohesion)” , 意为:

➢一个模块的组成元素之间的功能相关性。

将它与引起一个模块改变的作用力相联,就形成了如下描述:➢一个类,只能有一个引起它的变化的原因。

什么是职责?

单纯谈论职责,每个人都会得出不同的结论

因此我们下一个定义:

➢一个职责是一个变化的原因。

2.2.5 O0D原则五:接口分离原则(ISP)

ISP 一 Interface Segregation Principle

不应该强迫客户程序依赖它们不需要的方法。

ISP和SRP的关系

ISP和SRP是相关的,都和“内聚性”有关。

SRP指出应该如何设计一个类一只能有一种原因才能促使类发生改变。

ISP指出应该如何设计一个接口一从客户的需要出发,强调不要让客户看到他们不需要的方法。

发布于: 2020 年 06 月 17 日 阅读数: 16
用户头像

关注

还未添加个人签名 2018.04.25 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第二周总结