第二周总结

发布于: 2020 年 06 月 17 日
第二周总结

本周上课的主要核心内容是框架的设计,首先从软件开发的变迁演进中,讲解了为什么OOP会变成最流行的编程方法;其次是怎么进行面向对象编程以及软件框架的概念;最后为了让软件“强内聚、松耦合”,SOLID设计原则是怎样让软件设计变得优雅的。

一、OOP为什么变成最流行的编程方法

编程的目的是为了用计算机解决现实世界的问题,所以需要对领域问题进行抽象,然后用软件来实现抽象出来的模型,来达到解决问题的目的。

早期的编程语言(汇编)是面向机器进行抽象的;

到后来的结构化程序设计(C)是面向人的抽象(面向过程编程比较适合的人的思维);

面向对象程序设计(Java C#)是真正的直接表达问题空间内的元素

专栏:设计模式之美

面向对象编程相比起面向过程编程的优势主要有三个。

1.对于大规模复杂程序的开发,程序的处理流程并非单一的一条主线,而是错综复杂的网状结构。面向对象编程比起面向过程编程,更能应对这种复杂类型的程序开发。

2.面向对象编程相比面向过程编程,具有更加丰富的特性(封装、抽象、继承、多态)。利用这些特性编写出来的代码,更加易扩展、易复用、易维护。

3.从编程语言跟机器打交道的方式的演进规律中,我们可以总结出:面向对象编程语言比起面向过程编程语言,更加人性化、更加高级、更加智能。

二、怎么进行面向对象编程

使用了面向对象语言编程与面向对象编程是两个截然不同的概念,也是在日常开发中最容易犯的一个错误。

面向对象编程是指使用了 封装、继承、多态的特性进行编程,日常编程中常常碰到的一些情况实际上是违反面向对象编程的特性的:

专栏:设计模式之美

1. 滥用 getter、setter 方法

在设计实现类的时候,除非真的需要,否则尽量不要给属性定义 setter 方法。除此之外,尽管 getter 方法相对 setter 方法要安全些,但是如果返回的是集合容器,那也要防范集合内部数据被修改的风险。

2.Constants 类、Utils 类的设计问题

对于这两种类的设计,我们尽量能做到职责单一,定义一些细化的小类,比如 RedisConstants、FileUtils,而不是定义一个大而全的 Constants 类、Utils 类。除此之外,如果能将这些类中的属性和方法,划分归并到其他业务类中,那是最好不过的了,能极大地提高类的内聚性和代码的可复用性。

3. 基于贫血模型的开发模式

关于这一部分,我们只讲了为什么这种开发模式是彻彻底底的面向过程编程风格的。这是因为数据和操作是分开定义在 VO/BO/Entity 和 Controler/Service/Repository 中的。今天,你只需要掌握这一点就可以了。为什么这种开发模式如此流行?如何规避面向过程编程的弊端?有没有更好的可替代的开发模式?相关的更多问题,我们在面向对象实战篇中会一一讲解。

面向对象设计的目的是是系统高内聚,低耦合,从而是系统易扩展、更强壮、可移植、更简单,为了达到这个目的,前人已经总结除了常用的编程原则SOLID,以及使用这些原则的最佳实践(范式)设计模式。合理的使用设计模式,除了可以让代码更加优雅,也能让别人更加容易理解自己的代码。

常用的23种设计模式,根据作用不同,可以分成三类

  • 创建模式

  • 行为模式

  • 结果模式

三、框架相关

框架与工具最大的不同是,框架是主动调用应用程序代码的,而工具是给应用程序使用的。架构师如果想全局掌控软件的框架、规范、质量 等等,是需要定义一套框架的,用框架的规范来约束开发人员。

三、SOLID设计原则

  • 单一职责原则(Single Responsibility Principle)

一个类或者模块只负责完成一个职责(或者功能)。

很好理解,就是拆分,不要涉及大而全的类,要设计粒度小、功能单一的类。

难点:

怎么算是单一职责,这个是比较主观的,每个人得出的结论是不一样的。

有的时候不同的职责必须写在一个类中,这个时候可以把不同的职责抽象成不同的接口,来达到不同的使用方看到是不同的职责。

  • 开闭原则(Open Closed Principle)

对于扩展是开放的,对于更改是封闭的。

通过合理的抽象,在添加一个新的功能时,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

关键是找到合适的扩展点进行抽象,绝大部分的设计模式(策略、模板 等)也是符合开闭原则的。

  • 里式替换原则(Liskov Substitution Principle)

子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏。

class Father{
public void test() throws IOException{
}
}
class Son extends Father{
@Override
public void test() throws FileNotFoundException {
}
}

典型的错误的例子,父类的test方法抛出IOException,子类继承重写后抛出FileNotFoundException,实际上就是违反里式替换原则,这个时候子类也只能抛出IOException。

  • 接口隔离原则(Interface Segregation Principle)

不应该强迫客户端依赖他们不需要的方法。

跟单一职责原则有点类似,接口隔离更加侧重接口的设计,也就是说接口的设计要职责单一。

  • 依赖反转原则(Dependency Inversion Principle)

依赖倒置原则(Dependency Inversion Principle)又叫依赖反转原则,主要内容有:

  1. 高层模块(high-level modules)不要依赖低层模块(low-level);

  2. 高层模块和低层模块应该通过抽象(abstractions)来互相依赖;

  3. 高层模块和低层模块应该通过抽象(abstractions)来互相依赖;

高层根据自己的需要来定义抽象,高层和底层都依赖于抽象,这个和框架设计中的好莱坞规则非常相似。

用户头像

changtai

关注

还未添加个人签名 2018.04.30 加入

还未添加个人简介

评论

发布
暂无评论
第二周总结