clean code-代码整洁之道 阅读笔记(第十一章)

news2024/11/28 1:41:58

第十一章 系统

“复杂要人命,它消磨开发者的生命,让产品难以规划、构建和测试。”

 --RayOzzie,微软公司首席技术官

11.1 如何建造一个城市

        每个城市都有一组组人管理不同的部分,有些人负责全局,其他人负责细节。

        城市能运转,还因为它演化出恰当的抽象等级和模块,好让个人和他们所管理的“组件”即便在不了解全局时也能有效地运转。

11.2 将系统的构造与使用分开

        软件系统应将启始过程启始过程之后的运行时逻辑分离开,在启始过程中构建应
用对象,也会存在互相缠结的依赖关系。

        下例就是典型的情形:延迟初始化/赋值

public Service getService(){
    if(service==null)
        service = new MyServiceImpl(...); // Good enoughdefault for most cases?
    return service;
}

        应当将这个过程从正常的运行时逻辑中分离出来,确保拥有解决主要依赖问题的全局性一贯策略。

11.2.1 分解main

        将构造与使用分开的方法之一是将全部构造过程搬迁到main或被称之为main的模块中,设计系统的其余部分时,假设所有对象都已正确构造和设置。

11.2.2 工厂

        有时应用程序也要负责确定何时创建对象。

        比如,在某个订单处理系统中,应用程序必须创建LineItem实体,添加到Order对象。在这种情况下,我们可以使用抽象工厂模式让应用自行控制何时创建LineItems,但构造的细节却隔离于应用程序代码之外。

11.2.3 依赖注入

        有一种强大的机制可以实现分离构造与使用,那就是依赖注入(Dependency Injection,DI),控制反转(Inversion of Control,IoC)在依赖管理中的一种应用手段。控制反转将第二权责从对象中拿出来,转移到另一个专注于此的对象中,从而遵盾了单一权责原则。

        在依赖管理情景中,对象不应负责实体化对自身的依赖。反之,它应当将这份权责移交给其他"有权力"的机制,从而实现控制的反转。因为初始设置是一种全局问题题,这种授权机制通常要么是main例程,要么是有特定目的的容器。

11.3 扩容

        “一开始就做对系统”纯属神话。反之,我们应该只去实现今天的用户故事,然后重构,明天再扩展系统、实现新的用户故事。这就是迭代和增量敏捷的精髓所在。测试驱动开发、重构以及它们打造出的整洁代码,在代码层面保证了这个过程的实现。

        软件系统与物理系统可以类比。它们的架构都可以递增式地增长,只要我们持续将关注面恰当地切分。

        横贯式关注面

        AOP是一种恢复横贯式关注面模块化的普适手段。

        在AOP中,被称为方面(aspect)的模块构造指明了系统中哪些点的行为会以某种方式被修改,从而支持某种特定的场景。这种说明是用某种简洁的声明或编程机制来实现的一致的。

11.4 Java代理

        Java代理适用于简单的情况,例如在单独的对象或类中包装方法调用。然而,JDK提供的动态代理仅能与接口协同工作。对于代理类,你得使用字节码操作库,比如CGLIB、ASM或Javassist。

11.5 纯 Java AOP 框架

        幸运的是,编程工具能自动处理大多数代理模板代码。在数个Java相架中,代理都是内嵌的,如SpringAOP和JBossAOP等,从而能够以纯Java代码实现面向方面编程。在Spring中,你将业务逻辑编码为旧式Java对象。POJO自扫门前雪,并不依赖于企业框架(或其他域)。因此,它在概念上更简单、更易于测试驱动。相对简单性也较易于保证正确地实现相应的用户故事,并为未来的用户故事维护和改进代码。

        使用描述性配置文件或API,你把需要的应用程序构架组合起来,包括持久化、事务、安全、缓存、恢复等横贯性问题。在许多情况下,你实际上只是指定Spring或Jboss类库,框架以对用户透明的方式处理使用Java代理或字节代码库的机制。这些声明驱动了依赖注入(DI)容器,DI容器再实体化主要对象,并按需将对象连接起来。

11.6 AspectJ 的方面

        通过方面来实现关注面切分的功能最全的工具是AspectJ语言,一种提供“一流的”将方面作为模块构造处理支持的Java扩展。在80%~90%用到方面特性的情况下,SpringAOP和JBossAOP提供的纯Java实现手段足够使用。然而,AspectJ却提供了一套用以切分关注面的丰富而强有力的工具。AspectJ的弱势在于,需要采用几种新工具,学习新语言构造和使用方式。
        藉由AspectJ近期引入的“annotation form”(使用Java5annotation定义纯Java代码的方面),新工具采用的问题大大减少。另外,Spring Framework 也有一些让拥有较少 AspectJ 经验的团队更容易组合基于annotation的方面的特性。

11.7 测试驱动系统架构

        最佳的系统架构由模块化的关注面领域组成,每个关注面均用纯Java(或其他语言)对象实现。不同的领域之间用最不具有侵害性的方面或类方面工具整合起来,这种架构能测试驱动,就像代码一样。

11.8 优化决策

        模块化和关注面切分成就了分散化管理和决策。在巨大的系统中,不管是一座城市或一个软件项目,无人能做所有决策。众所周知,最好是授权给最有资格的人。但我们常常忘记了,延迟决策至最后一刻也是好手段。

        拥有模块化关注面的POJO系统提供的敏捷能力,允许我们基于最新的知识做出优化的、时机刚好的决策,决策的复杂性也降低了。

11.9 明智使用添加了可论证价值的标准

        有了标准,就更易复用想法和组件、雇用拥有相关经验的人才、封装好点子,以及将组件连接起来。不过,创立标准的过程有时却漫长到行业等不及的程度,有些标准没能与它要服务的采用者的真实需求相结合。

11.10 系统需要领域特定语言

        领域特定语言(Domain-SpecificLanguage,DSL)是一种单独的小型脚本语言或以标准语言写就的API,领域专家可以用它编写读起来像是组织严谨的散文一般的代码。

        DSL在有效使用时能提升代码惯用法和设计模式之上的抽象层次。它允许开发者在恰当的抽象层级上直指代码的初衷。

        领域特定语言允许所有抽象层级和应用程序中的所有领域,从高级策略到底层细节,使用POJO来表达。

11.11 小结

        系统也应该是整洁的。侵害性架构会湮灭领域逻辑,冲击敏捷能力。当领域逻辑受到困扰,质量也就堪忧,因为缺陷更易隐藏,用户故事更难实现。当敏捷能力受到损害时,生产力也会降低,TDD的好处遗失殆尽。
        在所有的抽象层级上,意图都应该清晰可辨。只有在编写POJO并使用类方面的机制来无损地组合其他关注面时,这种事情才会发生。
        无论是设计系统或单独的模块,别忘了使用大概可工作的最简单方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1844980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

昨天发的 npm 包,却因为 registry 同步问题无法安装使用

用过 HBuilderX 云打包的都知道,云上面的 Android 环境很有限,其实并不能覆盖 uniapp 生态所有的版本,甚至说只能覆盖最新的一两个版本。 如果你需要用到 HBuilderX 安卓云打包,就必须及时跟进 HBuilderX 的版本更新,…

【人机交互 复习】第7章 可视化设计

一、窗口界面类型 1.多文档界面 (1)优点 a.节省系统资源 b.最小的可视集 c.协同工作区 d.多文档同时可视化 (2)缺点 a.菜单随活动文档窗口状态变化,导致不一致性 b.文档窗口必须在主窗口内部,减弱多文档显…

[C++][数据结构][B-树][上]详细讲解

目录 0.常见的搜索结构1.B树概念2.B-树的插入分析1.流程分析2.插入过程总结 0.常见的搜索结构 种类数据格式时间复杂度顺序查找无要求 O ( N ) O(N) O(N)二分查找有序 O ( l o g 2 N ) O(log_2 N) O(log2​N)二叉搜索树无要求 O ( N ) O(N) O(N)二叉平衡树无要求 O ( l o g 2 …

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验5 交换机的自学习算法

一、实验目的 1.验证交换机的自学习算法; 2.了解交换机对帧的过滤特性; 3.学习交换机如何登记接收到的数据包; 4.学习交换机如何转发数据包(明确转发,盲目转发,丢弃)。 二、实验要求 1.使用Cisc…

自动化办公04 使用pyecharts制图

目录 一、柱状图 二、折线图 三、饼图 四、地图 1. 中国地图 2. 世界地图 3. 省会地图 五、词云 Pyecharts是一个用于数据可视化的Python库。它基于Echarts库,可以通过Python代码生成各种类型的图表,如折线图、柱状图、饼图、散点图等。 Pyecha…

养车小程序系统源码,汽修源码,仿途虎养车系统源码,车辆保养小程序系统

用户端+商家端+师傅端 功能介绍: 支持下单上门服务、到店核销,支持单独选择项目、 也支持选择服务人员、和选择门店多种下单方式, 支持上门服务和到店核销两种服务方式,支持自营和多商家联营两种运营模式&#xff…

静态路由(Static-Route)-Cisco

路由(Route) 世界上数亿的计算机大海 通过路由将世界连接 路由连接LAN、WAN、MAN,也连接世界 路由的工作 路由器将大块信息分解为小数据包 以实现可靠和高效的传输 过程称为“反汇编”和“封装数据有效负载” 路由表是一种逻辑数据结构…

Linux 服务管理(待更)

服务(service)本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如(mysqld , sshd防火墙等),因此又称为守护进程。 比如通过xshell进行连接的时候,需要输入的端口号就是通过守护…

PyTorch梯度直通反传

有时我们想在层的输出端放置一个阈值函数。这可能出于多种原因。其中之一是我们想将激活总结为二进制值。这种激活的二值化在自编码器中很有用。 然而,阈值化在反向传播过程中会带来问题:阈值函数的导数为零。这种梯度的缺乏导致我们的网络无法学习任何…

CSDN图片居中、左对齐、右对齐、大小设置

图片居中、左对齐、右对齐 ![在这里插入图片描述](https://img-blog.csdnimg.cn/99dc1072e8f1471990b700e1c85d301a.jpeg#pic_center) 大小设置 空格400x150 空格30%x # 长400 宽200 ![在这里插入图片描述](https://img-blog.csdnimg.cn/99dc1072e8f1471990b700e1c85d301a.…

hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式?

hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式? 1. 回顾下 spark 的架构图和部署模式 来自官方的经典的 spark 架构图如下: 上述架构图,从进程的角度来讲,有四个角色/组件&…

opencascade AIS_InteractiveContext源码学习3 highlighting management 对象高亮管理

AIS_InteractiveContext 前言 交互上下文(Interactive Context)允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是,对于已经被交互上下文识别的交互对象,必须使用上下文方法进行…

TugraphDB:探索图数据库新境界

TugraphDB:释放图数据的全部潜能- 精选真开源,释放新价值。 概览 TugraphDB是支付宝背后的分布式图数据库。该项目是由蚂蚁集团和清华大学共同研发的高性能分布式图数据库,支持事务处理、TB 级大容量、低延迟查找和快速图分析等功能。专为处…

安卓系统安装linux搭建随手服务器termux平替软件介绍

引言 旧手机丢可惜,可以用ZeroTermux(一款代替termux)的超级终端,来模拟Linux(甚至你可以模拟Win,只要性能够用) ps:此软件只是termux的增强版,相当于增加右边菜单&…

第N5周:调用Gensim库训练Word2Vec模型

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 目录 本周任务: 1.安装Gensim库 2.对原始语料分词 3.停用词 4.训练Woed2Vec模型 …

单阶段目标检测--NMS

目录 一、概念: 二、算法过程 三、代码实现 一、概念: 在目标检测的初始结果中,同一个物体,可能对应有多个边界框 (bounding box,bb),这些边界框通常相互重叠。如何从中选择一个最合适 的(也就…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 披萨大作战(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 &#x1f…

1 UC

1 UC 1、环境变量2、环境变量表3、错误处理4、库文件4.1 静态库4.2 动态库4.3 动态库的动态加载 5、虚拟地址 1、环境变量 什么是环境变量? 每个进程都有一张自己的环境变量表,表中的每个条目都是形如“键值”形式的环境变量。进程可以通过环境变量访问…

opencascade AIS_InteractiveContext源码学习4 object local transformation management

AIS_InteractiveContext 前言 交互上下文(Interactive Context)允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是,对于已经被交互上下文识别的交互对象,必须使用上下文方法进行…

数据结构4---串

一、字符串暴力匹配 要注意的就是i与j的回溯&#xff0c;通过不断移动主串的指针&#xff0c;时间复杂度高 #include <stdio.h> #include <stdlib.h>typedef struct String {char* data;int len; }String;String* initString() {String* s (String*)malloc(sizeo…