架构师训练营第二周课程笔记及心得
面向对象编程的本质与未来
面向过程的语言是面向逻辑的,开发复杂的大规模的系统时,线性逻辑之间就会变得耦合起来,并且越庞大耦合程度越高
面向对象的编程语言,看到的不是一条一条的逻辑,而是一个一个的对象,对象之间的交互形成逻辑,完成系统的开发和设计
面向对象的思维方式
程序设计的方式能更好的描述客观事物之间的交互规律
编程的过程
将计算机所能理解的模型,与现实世界之间建立某种联系;不要停留在技术表面,编程表面,设计表面等,要理解技术,以及编程,设计背后更加根本的东西(多思考,不要停留在会用,能用;找到问题的真正所在,务实的解决问题)
编程的实质
将显示世界中的领域问题,分析抽象成模型,通过模型设计、抽象、开发,实现成软件系统;当我们的模型满足了需求,那编程就编程了简单的用编程语言实现模型的过程
模型需要满足
模型的对象既要和现实世界一一对应,也要和软件系统中的对象一一对应
对象之间的交互模式既和现实世界对应,也要和软件系统对应
问题领域
包含与系统要解决的问题的相关的实物和概念的空间
抽象种类
基础的抽象:简单指令
高级的抽象:逻辑过程,沟通语句
面向对象的抽象:对问题本身进行抽象
编程的核心要素:
人(劳动者),客观业务领域(劳动对象),计算机(劳动工具)
对象
我们要解决的问题就是对象,对问题对象进行拆分,并且抽象问题对象间的交互关系,这些对象和交互关系构成了我们需要编写的系统
软件开发中对象的定位需要:
一个不能交互,只有行为的东西是不能成为对象的,对象是一个客观的存在是能够进行交互的,有功能的
一个软件的好与不好是基于开发环境的上下文来说的,软件开发的上下文,就是软件开发过程中前后端的人员,工作流程等
软件开发上下文中,我们需要开发的需求是变化的,增多的,一个软件架构设计,能否满足向上向下兼容,才是衡量一个软件架构设计好与不好的依据
面向对象三要素:封装性、继承性、多态性
封装性:隐藏实现,减少对对象的关注点,只关心对象开放出的能力,接口等即可
继承性:实现接口的重用,A中有B的应用,则A继承了B
多态性:对象互换的魔法,继承之后使得对象呈现不同的状态的一种使用方法
面向对象的分析
将客观世界,领域对象进行分析:充血与贫血模型、领域驱动设计DDD
面向对象的基本原则(强内聚、低耦合)
使系统具有下面的优势
扩展性
健壮性
可移植性
易读性
设计模式
创建模式
行为模式
结构模式
再细分还有更多的模式比如:
并发编程
JavaEE模式
etc.
框架
框架的定义
是用来实现某一类应用的结构性的程序,是对某一类架构方案可复用的设计与实现,程序必须依附于框架来进行实现
框架和工具有什么区别
框架是来调用我的代码的,不需要我们在代码里写具体的使用,是存在于我们程序外围的,负责底层实现的一套代码,运行过程中往往是优先于业务代码那一层
工具是需要我们的代码来调用的,无法自己运行的,在我们程序内得到实现的一套代码,运行过程中往往只有通过业务代码的调用才能运行,才会产生实现的一层
架构师与框架与工具
架构师,需要懂得框架,使用框架,优化框架,设计框架,让框架,来更好的匹配领域问题
架构师通过框架,来保证架构的落地,保证整体的程序的运行流程以及整体结构;通过工具,来提升开发效率,提供可复用的一些操作
一个不好的软件的特征:
僵化性:不容易改变,耦合性高,牵一发而动全身
脆弱性:改动一部分,会导致另一部分不可避免的出错
牢固性:不可移植,模块复用成都低
粘滞性:做正确的事情比做错误的事情要困难,导致误用的陷阱,错误的设计,导致开发人员在开发过程中将工具误用
不必要的复杂性:过度设计,设计气味太重偏离了需求
不必要的重复性:,欠缺设计缺乏设计直接复制粘贴前人的代码,代码中包含有重复的结构,但是这个结构本可以用一个单一的抽象进行统一
晦涩性:很难阅读、理解,没有很好的表现出意图,不容易看懂
软件开发中的OOD原则:
开闭原则
OCP,依靠抽象,使得软件对于扩展是开放的,对于修改是封闭的;是软件开发中各种对象的设计原则和思想
例:使用适配器,来扩展现有功能,也保证了修改时不用牵一发而动全身。
依赖倒置原则
DIP,高层模块不能依赖底层模块,而是依赖抽象,抽象不能依赖实现,而是实现依赖抽象;指导软件框架开发
例:高层模块通过定义接口,让低层模块来实现接口,保证了系统的扩展性的同时,也可以让高层模块的复用性更高,好莱坞规则,不要call我,我会call你,就像演员和导演,不是演员(低层)联系导演(高层)我要演(实现)什么什么,而是导演(高层)根据剧本(接口),找(调用)演员(低层)来出演(实现),不要让高层去实现低层的方法,而是让低层去实现高层定义的抽象。
里氏替换原则
LSP,子类和父类的继承关系需要放在上下文中验证继承关系的合理性;验证接口继承的合理性
从契约的角度来看里氏替换原则:凡是用到基类的地方一定也适用于其子类
解决继承问题: 1. 提取共性到基类 2. 将继承改成组合
继承和组合
继承和组合是OOP的两种扩展手段继承的优缺点:
优点:比较容易,因为基类的大部分功能可一通过继承直接进入子类。
缺点:破坏了封装,继承将更多的细节暴露给了子类,也叫白盒复用;当基类发生改变是可能会影响其下层的子类;继承是静态的,无法在运行时改变组合;会导致类的数量爆炸优先使用组合:通过组合的模式将,让子类(低层类)引入成员变量的方式使用父类(高层类),这样可以不产生继承关系,避免了继承的各种缺点。
单一职责原则
SRP,内聚性原则,一个类只能又一个引起它变化的原因(单一功能);用于高内聚类编写过程中
违反单一职责原则时会导致的问题
例:一个计算图形面积的类,既有计算方法,也有画图方法,两个不同需求问题在同一个类中实现导致具体不同模块使用这个类时需要额外实现另一个方法
接口分离原则
ISP,也是内聚性原则之一,不应该强迫客户程序依赖它们不需要的方法;用于高内聚类编写过程中
例:本身确实需要多种接口类型的类,无法拆分的,比如modem类,拨号,链接,等都需要,但是又有某些场景下确实真的只需要这个类中的单个或部分功能,这时依然是这个类,但是接口可以分开,实现类无法拆解的几个方法,通过接口暴露给不同的程序。
解决方法:比如定时门的实现类问题
案例:反应式编程框架Flower的设计
Flower框架,通过将内部类之间的消息调用来实现一个或多个service的方式,这里有两个问题:
通过队列来实现的异步消息调用中,如果发生了消息丢失,flower是如何规避这个问题的?
既然是消息,那么在实现过程中,如果有时序性消息,如何保证消费的服务实现按照规定的时间逻辑来消费队列中的消息?
版权声明: 本文为 InfoQ 作者【Airs】的原创文章。
原文链接:【http://xie.infoq.cn/article/28fe5607241288e347b0182df】。未经作者许可,禁止转载。
评论