第二周 - 学习总结
从语言的发展谈面向对象设计
面向机器进行编程,进行机器指令,程序员自己控制硬件
面向过程的语言,按人类习惯的思维方式进行编程。是线性的,线性逻辑开发复杂、大规模的系统时,线性逻辑之间难免会耦合起来,耦合随着复杂程度增加,像意大利面条
面向对象语言解决上面问题,编程的时候不该是看到一根一根逻辑线条,而是看到的一个个对象,对象之间进行合理的交互,来完成合理的交互和设计。将对象设计出来(真实的,映射现实对象)、对象之间的交互设计出来
面向对象编程更符合我们对问题的理解,更符合对编程的认知
编程目的:用计算机来解决现实世界的问题。
思考
用一样技术、学习一个技术。需要思考技术是如何走到现在的、是想解决什么问题的、为什么过往技术没有完美解决,我们实际工作是否真的在实现技术要达到的目的。
设计模式、设计原则、领域驱动设计,它的真正的背后的东西是什么?需要去思考。
不然只学到一些表面的、现象的东西,学到的都是一些手段,抓不住真正的本质,当遇到问题时就开始怀疑,找不到本质的点,不会去变通,只能用已有的方式去解决问题。
领域问题
包含与系统所要解决的问题相关的实物和概念。
开关和灯泡的例子
用机器语言:用机器指令控制开关,抽象级别是将问题抽象成计算机本身能理解的一个描述
结构化的高级编程语言:对计算处理逻辑抽象,抽象成人能理解的逻辑语句,用到判断、if else 等
面向对象的抽象:直接将问题本身进行抽象,表达空间问题中的元素。灯(turn on, turn off),通过消息和对象本身进行通信解决问题,内部如何实现、逻辑问题不重要。对象的边界、交互的接口是需要抽象的点。
面向对象的编程更能反映要解决问题的真实领域,也能更好的对问题进行抽象,所以是今天最主流的编程方式。
而今天大多数时候我们都是在用面向对象编程语言提供的特性进行编程,没有做到问题领域与现实世界的抽象对应关系,进行开发。
如何进行面向对象设计
万物皆对象,类是需要有行为的,不能交互、没有行为的东西是不能称为对象的。
面向对象分析是将客观世界,即编程的业务领域进行对象分析。
封装,构建对象的边界
继承,实现重用
多态,对象互换的魔法,子类实现父类,使用抽象类(父类)进行编程。面向对象编程不是使用面向对象的语言进行编程,而是利用多态特性进行编程。
目标 - 强内聚和低耦合(扩展性、健壮性、可移植、更简单)
框架设计
架构师用框架保证架构的落地、保证整体的程序的运行流程和结构,用工具提升效率(复用)
用来实现某一类应用的结构性的程序,是对某一类架构方案可复用的设计与实现。框架是大厦的框架结构,框架搭起来后,工程师可以需求将框架装修成酒店、游乐场、图书馆等不同大厦。
框架决定了系统的整体的结构。完成了整个系统骨干、最基础程序运行流程,构建了整个系统的整体结构。
具体写的代码由框架调用,框架来控制整体的程序运行结构。代码依附框架,支撑起程序整体结构。
框架是怎么设计出来的,框架设计的原则是什么。
只停留在会用框架、技能点在应用是不够的。理解框架背后的规律、框架的设计方法、理解框架是如何运行的,才能真正用好这些技术。
开发原则
设计是否好需要放到上下文环境中去判断。变化的需求变更,设计能否满足。
开闭原则
对扩展开放、对更改关闭,不需要修改软件实体(已存在的类、模块、函数等代码不被修改),就应该能实现功能的扩展。
关键是抽象。定义各种抽象,对抽象接口进行编程,当变更的时候,变更的是抽象接口的实现,而接口本身不变,接口的调用不变。
“拨打电话” 实战
按下数字按钮,屏幕显示号码,扬声器发出按键音
按下 “Send” 按钮,系统接通无限网络,屏幕上显示正在拨号
原始设计
改进一:
抽象 Button 类,创建 DigitButton, SendButton 两个类,这样 Button 添加就不会影响已有的 Button 类
改进二:
Dailor 改变会影响 Button 类,Button 类不容易复用。
策略模式,应用程序不直接依赖要依赖的目标对象,通过定义一个策略接口,去依赖策略接口,而我们依赖的目标对象去实现这个接口。
从而使对象依赖策略接口,而不依赖具体的对象
改进三:
策略模式使用之后,是将选择的操作放到了 Dailor 中了,Dailor 需要根据 token 的不同执行不同的方法。
将对 Dailor 的不同实现,通过适配器模式,创建不同的适配器,由适配器将 buttonPressed 方法转换为 Dailor 的不同方法,
这样需求改动后 Dailor 也不会变得复杂了。
改进四:
通过观察者模式,使得按钮和拨号器安全解耦,可以灵活的添加更多的操作
依赖倒置原则
DIP Dependency Inversion Principle.
高层模块不能依赖底层模块,而是大家都依赖于抽象。
高层面向接口/抽象编程,底层面向接口/抽象编程,高层和低层通过接口/抽象来联系,且底层只能面向高层接口/抽象去实现逻辑,
不允许底层自己定义新的接口/抽象。
抽象不能依赖实现,而是实现依赖抽象
抽象属于高层模块,倒转层次依赖关系,倒转了程序控制流程
框架设计的核心
框架不依赖代码、它依赖规范和接口进行设计,框架定义了接口,业务实现规范和接口,然后被框架调用。
如 Tomcat 依赖抽象(J2EE\Servlet 规范),不依赖底层的实现。应用程序不会去调用框架,底层实现接口,框架就能调用接口实现类。
里氏替换原则
子类能够替换掉任何地方出现的基类。
在 Java/C++ 这样的静态类型语言中,实现 OCP 的关键在于抽象,而抽象的威力在于多态和继承。
IS-A 关系是基于行为的,需要在开发的上下文去判断,比如马是用来骑的,白马是马,但是幼马不是马,因为它不能骑。
里氏替换原则是用来解决继承问题的。使用组合解决不必要的继承,组合优于继承。
单一职责原则(内聚性原则)
一个类只有一个引起它变化的原因,相同的功能、职责聚合在一起。
接口隔离原则
不应该强迫客户程序依赖它们不需要的方法,通过接口隔离不同客户端依赖实现类的方法
比如下面的 Modem
接口隔离后
版权声明: 本文为 InfoQ 作者【Yangjing】的原创文章。
原文链接:【http://xie.infoq.cn/article/37f4d5c8a60a4be5d96fab480】。文章转载请联系作者。
评论