当前位置: 首页 > news >正文

对象和数据结构

文章目录

  • 前言
  • 一、从链式调用说起
  • 二、数据抽象
  • 三、数据、对象的反对称性
  • 四、得墨忒尔律
  • 五、数据传送对象
  • 总结


前言

代码整洁之道读书随笔,第六章


一、从链式调用说起

面向对象语言中常用的一种调用形式,链式调用,是一种较受推崇的编码风格,如果你调用一个实例的方法,修改了实例的状态,后续需要调用其他方法,进一步改变实例的状态,那么不需要每次都用变量接收返回值,直接链式调用即可。

例如gorm的更新可以这样实现。

result := m.tx.Model(&model.A{}).Where(&model.A{ID: id}).Updates(data)

其中Where的实现为:

// Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions, refer http://jinzhu.github.io/gorm/crud.html#query
func (s *DB) Where(query interface{}, args ...interface{}) *DB {return s.clone().search.Where(query, args...).db
}

二、数据抽象

Java的初级程序员,此处特指刚入行时的本人,喜欢为类的私有成员变量加getter/setter,在很多crud场景,其实也感觉不出有什么问题,直到你的业务场景不再满足简单的crud,例如,书中的示例中给出了一个笛卡尔平面上一个point类的实现。刚好我现在的工作就是为智能机器人做路径规划,所以对这个感触就比较深。
一个点包含X/Y轴,每次改变位置,我们不能只更新单个轴,而是要同时更新,同样,查询也不是只想查询到单个轴,那么分别为每个变量加getter/setter是没有意义的。
getter/setter的根本目的是为了隐藏实现,隐藏实现是为了让用户无需了解实现就可以操作数据本体。

三、数据、对象的反对称性

对象和数据结构之间的二分原理:

过程式代码(使用数据结构的代码)便于在不改动既有数据结构的前提下添加新函数;面向对象代码便于在不改动既有函数的前提下添加新类。
反过来:
过程式代码难以添加新数据结构,因为必须修改所有函数;面向对象代码难以添加新函数,因为必须修改所有类。

那么我们可以举例,对于机器人,如果要构造一个类,那么就可以考虑,如果你的抽象级别在机器人上,每个机器人有自己的行为,比如a类机器人是聊天机器人,b类机器人是扫地机器人,那么就做面向对象,你不需要每次增加新功能都为所有机器人增加新函数。
但是如果你们机器人都是扫地机器人,那么把能力进行抽象就是比较正确的选择,走路的能力抽象成接口,让机器人组合能力,对于走路这个能力就成了过程式代码,就算你需要增加新的机器人种类,只需要包含这种能力即可。

四、得墨忒尔律

模块不应了解它所操作对象的内部情形。

更准确的,类C的方法f只应该调用以下对象的方法。

  • C;
  • 由f创建的对象;
  • 作为参数传递给f的对象;
  • 由C的实体变量持有的对象。

书中给出了一个反例:

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

现在和开头我说的链式调用比较一下,链式调用的每次调用返回的都是类C的实例本身,那么是没有违背得墨忒尔律的,但是这个反例中,每次返回的都是不一样的对象,那么对于调用者就需要了解Options、ScratchDir的内部构造结构。

特别需要指出,这里Options、ScratchDir特指拥有行为的对象,如果他们只拥有变量,而不拥有行为,那么作者认为不需要考虑得墨忒尔律。
结合outputDir的使用:

String outFile = outputDir + "/" + className.replace('.', '/') + ".class";
FileOutputStream fout = new FileOutputStream(outFile);
BufferedOutputStream bos = new BufferedOutputStream(fout);

作者给出了修正结果:

BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);

把过程隐藏到createScratchFileStream() 中,对于调用者,就不需要了解过多类的细节。

五、数据传送对象

数据传送对象(Data Transfer Objects, DTO)是用于与数据库通信或解析套接字传递的消息等场景中的数据结构,不适合加入业务逻辑。Active Record1是一种特殊的DTO。


总结

这是代码整洁之道第六章的读书随笔,本章已完结。


  1. Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。 ↩︎

相关文章:

  • 【AI视野·今日Robot 机器人论文速览 第六十二期】Wed, 25 Oct 2023
  • debian 修改镜像源为阿里云【详细步骤】
  • Leetcode 【2342. 数位和相等数对的最大和】
  • 【Spring】AOP进阶-JoinPoint和ProceedingJoinPoint详解
  • 实力进阶,教你使用thinkphp6开发一款商城系统
  • 电力感知边缘计算网关产品设计方案-网关软件架构
  • 金融业务系统: Service Mesh用于安全微服务集成
  • 好用的开源项目地址
  • ImportError: DLL load failed while importing _iterative: %1 不是有效的 Win32 应用程序。
  • 业务架构、技术架构、项目管理的有机结合
  • 【图像处理】:Otsu算法最大类间方差法(大津算法:附源码)
  • cp: can‘t stat ‘/usr/share/zoneinfo/Asia/Shanghai‘: No such file or directory
  • PyTorch 实战之水果分类
  • 嵌入式系统中相关的高质量开源项目
  • 单片机FLASH下载算法的制作
  • python3.6+scrapy+mysql 爬虫实战
  • 0基础学习移动端适配
  • Angular 响应式表单 基础例子
  • Bootstrap JS插件Alert源码分析
  • css属性的继承、初识值、计算值、当前值、应用值
  • DOM的那些事
  • Javascript基础之Array数组API
  • java中具有继承关系的类及其对象初始化顺序
  • opencv python Meanshift 和 Camshift
  • PHP 的 SAPI 是个什么东西
  • Spring Boot MyBatis配置多种数据库
  • TCP拥塞控制
  • 从零开始在ubuntu上搭建node开发环境
  • 排序算法学习笔记
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 一份游戏开发学习路线
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 选择阿里云数据库HBase版十大理由
  • #1015 : KMP算法
  • #etcd#安装时出错
  • (八)Flask之app.route装饰器函数的参数
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)计算机毕业设计大学生兼职系统
  • (附源码)计算机毕业设计高校学生选课系统
  • (九)c52学习之旅-定时器
  • (算法二)滑动窗口
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .cfg\.dat\.mak(持续补充)
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET 5种线程安全集合
  • .NET DataGridView数据绑定说明
  • .NET delegate 委托 、 Event 事件
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .Net中ListT 泛型转成DataTable、DataSet
  • .vue文件怎么使用_vue调试工具vue-devtools的安装