重新看面向对象设计

栏目: 后端 · 前端 · 发布时间: 6年前

内容简介:本文最初由来自陈皓《左耳听风》付费课程,建议先看下java 语言的动态性在面向对象编程里,计算机程序会被设计成彼此相关的对象,独立而又相互调用。传统程序主张将程序看做一系列指令,或一系列函数。面向对象设计中的每一个对象 都应该能够接受数据、处理数据并将数据传递给其它对象。

简介

本文最初由 apollo client源码分析 引发,后来加入了 陈皓《左耳听风》教程的相关内容。

左耳听风

来自陈皓《左耳听风》付费课程,建议先看下 java 语言的动态性

在面向对象编程里,计算机程序会被设计成彼此相关的对象,独立而又相互调用。传统程序主张将程序看做一系列指令,或一系列函数。面向对象设计中的每一个对象 都应该能够接受数据、处理数据并将数据传递给其它对象。

面向对象的缺点:通过对象来达到抽象效果, 把代码分散在不同的类里面。那要让它们执行起来,就需要将这些类粘合起来。设计模式以及ioc 等虽然精巧,但不得不怀疑点歪了科技树。一段代码的执行路径 obj1.func1 ==> obj2.func2 ==> obj3.func3 在函数式编程中 func1(func2(func3)) 就解决了。

自己的一些总结和心得:

重新看面向对象设计

换个角度想一下,架构设计从单体演化到微服务架构,固然一部分是单机无法负载,另一个原因就是单体 在维护和运维上的困难,比如一个小改动导致整个项目的重启。也就是说,架构设计之初,就越来越考虑可维护性和扩展性。 架构设计不只考虑实现功能,可维护性和扩展性影响了架构设计,对应的,可维护性和扩展性影响了代码结构。 指令序列或函数序列被解构,分散在各个对象中,以减少修改对整体的影响。但从上图可以看到,面向对象的优点 也直接导致了其缺点。

宏观上的系统设计与类设计

重新看面向对象设计

可以认为,db 就是controller-service-dao 这些类的状态。

微观上的类实现与系统模块实现

重新看面向对象设计

你设计一个controller-service-dao 项目 制定http api 时,肯定会想业务层面会有哪些调用,绝不会一个http api 干了一半的活儿 然后让调用方自己 访问两个 http api 自己聚合数据。对应的,我们在设计类时,根据类持有的数据/状态,一个对象可以访问数据库、可以内部操作线程,但其对外提供的interface function 应该是自洽的(对外隐藏掉不必要的细节)。类似的概念可以看 ddd(一)——领域驱动理念入门

一个神奇的例子

void business(){
	Lock lock = xx;
	if(condition){
		return;
	}
	business code;
	lock.unlock();
}

这里有一个问题, 符合condition 情况下代码提前退出,则没有执行unlock 操作。但如果condition 很多,到处都是 lock.unclock() 也比较乱。则可以

class LockGuard{
	Lock lock
	构造函数{
		lock = new Lock();
	}
	析构函数{
		lock.unLock()
	}
}
void business(){
	LockGuard lockGuard = new xx;
	if(condition){
		return;
	}
	business code;
}

从分析apollo client 得来的

2018.7.12 补充

面向对象和基于对象

大部分人写出的java 代码,可能只是基于对象。

基于对象,通常指的是对数据的封装,以及提供一组方法对封装过的数据操作。比如 C 的 IO 库中的 FILE * 就可以看成是基于对象的。

面向对象的程序设计语言必须有描述对象及其相互之间关系的语言成分。这些程序设计语言可以归纳为以下几类:

  1. 系统中一切事物皆为对象;
  2. 对象是属性及其操作的封装体;
  3. 对象可按其性质划分为类,
  4. 对象成为类的实例;
  5. 实例关系和继承关系是对象之间的静态关系;
  6. 消息传递是对象之间动态联系的唯一形式,也是计算的唯一形式;
  7. 方法是消息的序列。

笔者曾看到一篇如何分析源码的文章,文中提到的一个重要建议就是画类图,并将类图比作一个地图的各个山头,山头虽然不是地图的全部,但却撑起了类图的骨架。然后再由一条 业务逻辑的主线 串起来各个山头(即各个山头的相互调用)

面向对象的渊源

面向对象的编程产生的历史原因: 由于面向过程编程在构造系统时,无法解决重用,维护,扩展的问题, 而且逻辑过于复杂,代码晦涩难懂。PS:笔者第一次看到这句话时没有感觉,后来忘记了,看《左耳听风》时自己总结了这句,再看到这句早就看到的话时,知己二字不能形容。

《面向对象分析与设计》读书笔记 (1)- 关键的思想 要点如下

  1. 复杂性是面向对象主要解决的问题,复杂系统的5个属性

    • 层次结构,复杂性常常以层次结构的形式存在,层次结构的形式

      • 组成(”part of“)层次结构
      • 是一种“(“is a”)层次结构
    • 相对本原,这里是指构建系统的最小单位。你不需要担心基础组件是如何实现的,只要利用其外部行为即可。举个例子,你要盖一个房子,你需要砖,水泥等,这些都是一些基础组件,但是你不要自己去生产砖,水泥。
    • 分离关注,组件内的联系通常比组件间的联系更强。这一事实实际上将组件中高频率的动作(涉及组件的内部结构)和低频率的动作(涉及组件间的相互作用)区分开来
    • 共同模式,复杂系统具有共同的模式。比如小组件的复用,比如常用方案提炼为 设计模式
    • 稳定的中间形式(注意不是中间件),复杂系统是在演变中诞生的,不要一开始就期望能够构建出一个复杂的系统。要从简单系统逐步迭代到复杂的系统。
  2. 思考分解的方式

    1. 系统中每个模块代表了某个总体过程的一个主要步骤。邮寄快递时,我们先将物品准备好,找到快递员,填写快递信息,进行邮寄。在这个过程中,我们分成了4个步骤,我们更注重的是事件的顺序,而非主要关注参与者。
    2. 根据问题域中的关键抽象概念对系统进行分解。针对上面的快递邮寄的例子,采用面向对象分解时,我们分解成4个对象:物品,快递单,快递员,我。我拥有物品,然后向快递员发出请求,快递员给我快递单让我填写快递信息。然后快递员进行邮递。
  3. 编程风格,Bobrow将编程风格定义为“一种组织程序的方式,基于某种编程概念模型和一种适合的语言,其目的是使得用这种风格编写的程序很清晰”

  4. 对象模型的4个主要要素:抽象;封装;模块化;层次结构;3个次要要素:类型、持久、并发

  5. Shaw对于抽象的定义:”对一个系统的一种简单的描述或指称,强调系统的某些细节或属性同时抑制另一些细节或属性。好的抽象强调了对读者或者用户重要的细节,抑制了那些至少是暂时的非本质细节或枝节” (我以前的思维漏洞 就是不知道 抑制非本质细节)
  6. 封装的意义,复杂系统的每一部分,都不应该依赖于其他部分的内部细节。要让抽象能工作,必须将实现封装起来
  7. 模块化的意义
  8. 层次结构的意义

实例分析

关联 apollo client源码分析 阅读

所以,我们讲面向对象,重点不是业务流程(不是说不重要,而是不论怎么写代码,都要按业务顺序执行,这点无疑问)。就好比,apollo client,重点也不是 向服务端 获取数据更新本地数据 这些事儿。而是

  1. apollo client 在给开发人员的接口 是什么样的,包括配置 变化时 驱动listener 执行。
  2. 向服务端 申请数据(推拉)以及更新本地数据 这些事儿 如何抽象
  3. 两个 抽象域 如何 交集

apollo client 一个牛逼之处 在于 第二个 抽象域,提取出 ConfigRepository 的抽象,RemoteRepository LocalRespository 并标记 每个ConfigRepository 有一个parent

多线程与对象的 关系

我以前的认知,线程只是一个 驱动者,驱动代码执行,对象跟线程没啥关系。一个典型的代码是

class XXThread extends Thread{
	private Business business;
	public XXThread(Business business){
		this.business = business;
	}
	public void run(){
		business code
	}
}

在apollo client 中,RemoteRepository 内部聚合线程 完成配置的周期性拉取,线程就是一个更新数据的手段,只是周期性执行下而已。

class Business{
	private Data data;
	public Business(){
		Executors.newSingleThread().execute(new Runnable(){
			public void run(){
				acquireDataTimely();
			}
		});
	}
	public void acquireDataTimely(){}
	public void useData(){}
	public void transferData(){}

}

从两段代码 看,线程与对象的 主从关系 完全相反。 程序的本质复杂性和元语言抽象 指出:程序=control + logic。 同步/异步 等 本质就是一个control,只是拉取数据的手段。因此,在我们理解程序时,不应成为本质的存在。

笔者个人微信订阅号

重新看面向对象设计


以上所述就是小编给大家介绍的《重新看面向对象设计》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

如何不在网上虚度人生

如何不在网上虚度人生

[美] 肯尼思·戈德史密斯 / 刘畅 / 北京联合出版公司 / 2017-9 / 39.80元

我们平时上网多大程度上是浪费时间,多大程度是在学习、关心社会、激发创造力?我们真能彻底断网,逃离社交网络吗? 手机把都市人变成一群电子僵尸,是福是祸? 浏览记录就是我们将来的回忆录吗?文件归档属于一种现代民间艺术? 不自拍、P图、发朋友圈,我还是我吗? 美国知名概念艺术家戈德史密斯认为:上网绝不是浪费时间,而是一种创造性的活动。在本书中他以跨学科角度、散文式语言进行论证,涉及大众传播学、计算......一起来看看 《如何不在网上虚度人生》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具