Week 2 作业 02

用户头像
Croesus
关注
发布于: 2020 年 09 月 27 日

学习总结



软件编程的本质是为了更有效率解决现实世界的问题。架构师需要抓住技术背后的规律和本质,不能仅仅会看着文档写代码。



程序=控制+逻辑+数据结构

https://qiankunli.github.io/2018/07/14/nature_of_code.html



问题领域(Problem Domain)

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



面向对象编程(Object-oriented programming, OOP)

能够更好的解决问题,能更好的对问题进行抽象,我们现在还没有掌握好,我们只是使用了面向对象编程语言。



编程的核心要素



面向对象编程:

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

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

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

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



对象具有状态、行为和标识。

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

  • 行为:每个对象可以产生行为。

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



面向对象编程的三要素(特征)

  • 封装性(Encapsulation)

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

  • 定义接口

  • 继承性(Inheritance)

  • IS-A关系

  • HAS-A关系(组合)

  • 多态性(Polymorphism)

  • 后期绑定(虚函数)

  • 向上转形(Up Casting)



面向对象设计的目的是做到强内聚、低耦合,从而使系统

  • 易扩展 - 易于增加新的功能

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

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

  • 更简单 - 容易理解、容易维护



设计模式(Design Patterns)

设计模式是用于解决某一种问题的通用的解决方案。 设计模式也是语言中立的。 设计模式贯彻了设计原则。 Gang of Four(Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides)提出了三 大类23种基本的设计模式:

  • 创建模式

  • 行为模式

  • 结构模式



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

  • 并发编程模式

  • Java EE模式



框架(frameworks) 框架是用来实现某一类应用的结构性的程序, 是对某一类架构方案可复用的设计与实现。如同框架结构的大厦的框架,简化应用开发者的工作,实现了多种设计模式,使应用开发者不需要花太大的力气,就能设计出结构良好的程序来。



框架 VS 工具 框架调用应用程序代码 应用程序代码调用工具 架构师用框架保证架构的落地 架构师用工具提高开发效率。



代码的臭味

  • 僵硬 - 不易增加、修改:

  • 增加一种 Button 类型,就需要对 Button 类进行修改;

  • 修改 Dialer,可能会影响 Button。

  • 脆弱 - switch case/if else语句是相当脆弱的。

  • 当我想修改 Send 按钮的功能时,有可能不小心破坏数字按钮;

  • 当这种函数很多时,我很有可能会漏掉某个函数,或其中的某个条件分支。

  • 不可移植 - 设想我们要设计密码锁的按钮,它只需要数字按键,但 Button 的设计使它必须 “附带”一个“Send”类型的按钮。



软件设计的最终目的,是使软件达到“强内聚(High cohesion)、松耦合 (Loose coupling)”,从而使软件:

  • 易扩展 - 易于增加新的功能

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

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

  • 更简单 - 容易理解、容易维护

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

  • 僵硬 - 不易改变。

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

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

  • 导致误用的陷阱 - 做错误的事比做正确的事更容易,引诱程序员破坏原有的设计。

  • 晦涩 - 代码难以理解。

  • 过度设计、copy-paste 代码。



http://teddy-chen-tw.blogspot.com/2011/12/1.html



OOD (Object-oriented design) 原则一:

开/闭原则(OCP) OCP - Open/Closed Principle

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

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

  • 简言之:不需要修改软件实体(类、模块、函数等),就应该能实现功能的扩展。 传统的扩展模块的方式就是修改模块的源代码。如何实现不修改而扩展呢?

  • 关键是抽象!



OOD 原则二:

依赖倒置原则(DIP) DIP - Dependency Inversion Principle

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

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

DIP 倒置了什么?

  • 模块或包的依赖关系

  • 开发顺序和职责

软件的层次化

  • 高层决定低层

  • 高层被重用



遵循 DIP 的层次依赖关系



违反 DIP 案例



OOD 原则三:

Liskov替换原则(LSP) 在 Java/C++ 这样的静态类型语言中,实现 OCP 的关键在于抽象,而抽象的威力在于多态和继承。一个正确的继承要符合Liskov 替换原则 1988年,Barbara Liskov 描述这个原则:

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

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



不符合替换原则。举例:当小马继承马的时候,虽然还是马,可是小马是无法给人骑。



继承 vs. 组合 继承和组合是 OOP 的两种扩展手段

继承的优点:

  • 比较容易,因为基类的大部分功能可以通过继承直接进入子类。

继承的缺点:

  • 继承破坏了封装,因为继承将基类更多的细节暴露给子类。因而继承被称为“白盒复用”。

  • 当基类发生改变时,可能会层层影响其下的子类。

  • 继承是静态的,无法在运行时改变组合。

  • 类数量的爆炸。

应该优先使用组合



OOD 原则四:

单一职责原则(SRP) SRP - Single Responsibility Principle (又被称内聚性原则 Cohesion )

一个模块的组成元素之间的功能相关性。将它与引起一个模块改变的作用力相联,就形成了如下描述: 一个类,只能有一个引起它的变化的原因。职责:一个职责是一个变化的原因。



违反 SRP 原则的后果后果

  • 脆弱性 - 把绘图和计算功能耦合在一起,当修改其中一个时,另一个功能可能会意外受损。

  • 不可移植性 - 计算几何应用只需要使用“计算面积”的功能,却不得不包含 GUI 的依赖。



OOD 原则五:接口分离原则(ISP) ISP - Interface Segregation Principle

  • 不应该强迫客户程序依赖它们不需要的方法。 ISP 和 SRP 的关系

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

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

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



用户头像

Croesus

关注

还未添加个人签名 2019.01.05 加入

还未添加个人简介

评论

发布
暂无评论
Week 2 作业 02