【Code】《代码整洁之道》笔记-Chapter8-边界

MacTeX+TeXstudio:Macbook配置本地Latex看这一篇就够了 这个博客记录本人在MacBook上配置本地Latex的流程,其中选择的编译环境为MacTeX,编辑器为TeXstudio。采用的原因主要两点:一个是本人配置的原因主要是用来撰写毕业论文,希望能够尽可能简化设置流程,专注内容表达;第二是由于本人还有一个windows系统的笔记本,想要编辑器在专注写作体验的同时在两个系统上能够都适配,从而减少切换效率,故选择此组合。这篇文章介绍并详细记录了本人的安装流程,有相同需求的同志也可借鉴。 阅读详情

第8章 边界

我们很少能控制系统中的全部软件。有时我们购买第三方程序包或使用开放源代码,有时我们依靠公司中其他团队打造组件或子系统。不管是哪种情况,我们都得将外来代码干净利落地整合进自己的代码中。本章将介绍一些保持软件边界整洁的实践手段和技巧。

8.1 使用第三方代码

在接口提供者和使用者之间,存在与生俱来的矛盾。第三方程序包和框架提供者追求普适性,这样就能在多种环境中工作,从而吸引广泛的用户。而使用者则想要得到集中满足特定需求的接口。这种矛盾会导致系统边界上出现问题。

以java.util.Map为例,Map有着广阔的接口和丰富的功能。当然,这种力量和灵活性很有用,但也要付出代价。比如,应用程序可能构造一个Map对象并传递它。我们的初衷可能是Map对象的所有接收者都不要删除映射图中的任何东西。但它却正好有一个clear()方法。Map的任何使用者都能清除映射图。或许设计惯例是Map中只能保存特定的类型,但Map并不会可靠地约束存于其中的对象的类型。使用者可随意往Map中塞入任何类型的条目。

  • clear() void – Map

  • containsKey(Object key) boolean – Map

  • containsValue(Object value) boolean – Map

  • entrySet() Set – Map

  • equals(Object o) boolean – Map

  • get(Object key) Object – Map

  • getClass() Class<? extends Object> – Object

  • hashCode() int – Map

  • isEmpty() boolean – Map

  • keySet() Set – Map

  • notify() void – Object

  • notifyAll() void – Object

  • put(Object key, Object value) Object – Map

  • putAll(Map t) void – Map

  • remove(Object key) Object – Map

  • size() int – Map

  • toString() String – Object

  • values() Collection – Map

  • wait() void – Object

  • wait(long timeout) void – Object

  • wait(long timeout, int nanos) void – Object

如果你的应用程序需要一个包容Sensor类对象的Map映射图,大概会是这样:

Map sensors = new HashMap();

当代码的其他部分需要访问这些传感器,就会有这行代码:

Sensor s = (Sensor)sensors.get(sensorId);

这行代码一再出现。代码的调用端承担了从Map中取得对象并将其转换为正确类型的职责。行倒是行,却非整洁代码。而且,这行代码并未说明自己的用途。通过对泛型的使用,这段代码的可读性可以大大提升,如下所示:

    Map<String,Sensor> sensors = new HashMap<Sensor>();
...
    Sensor s = sensors.get(sensorId);

不过,Map<String, Sensor>提供了超出所需/所愿的功能的问题,仍未得到解决。

在系统中不受限制地传递Map<String, Sensor>的实体,意味着当Map的接口被修改时,有许多地方都要跟着改。你或许会认为这样的改动不太可能发生,不过,当Java 5加入对泛型的支持时,的确发生了改动。我们也的确见到一些系统因为要做大量改动才能自由使用Map类,而无法使用泛型。

使用Map的更整洁的方式大致如下。Sensors的用户不必关心是否用了泛型,那将是(也该是)实现细节才关心的。

public class Sensors {
  private Map sensors = new HashMap();

  public Sensor getById(String id) {
    return (Sensor) sensors.get(id);
  }

  // snip
}

边界上的接口(Map)是隐藏的。它能随来自应用程序其他部分的极小的影响而变动。对泛型的使用不再是个大问题,因为转换和类型管理是在Sensors类内部处理的。

该接口也经过仔细修整和归置以适应应用程序的需要。结果就是得到易于理解、难以被误用的代码。Sensors类推动了设计和业务的规则的形成。

我们并不建议总是以这种方式封装Map的使用。我们建议不要将Map(或在边界上的其他接口)在系统中传递。如果你使用类似Map这样的边界接口,就把它保留在类或近亲类中。避免从公共API中返回边界接口,或将边界接口作为参数传递给公共API。

8.2 浏览和学习边界

第三方代码帮助我们在更少时间内发布更丰富的功能。在利用第三方程序包时,该从何处入手呢?我们没有测试第三方代码的职责,但为要使用的第三方代码编写测试,可能最符合我们的利益。

设想我们对第三方代码库的使用方法并不清楚。我们可能会花上一两天(或者更多)时间阅读文档,决定如何使用。然后,我们会编写使用第三方代码的代码,看看是否如我们所愿地工作。我们会陷入长时间的调试,找出在我们或他们代码中的缺陷,这可不是什么稀罕事。

学习第三方代码很难,整合第三方代码也很难,同时做这两件事难上加难。如果我们采用不同的做法呢?不要在生产代码中试验新东西,而是编写测试来遍览和理解第三方代码。Jim Newkirk把这叫作学习性测试(learning test)。

在学习性测试中,我们就像在应用中那样调用第三方代码。我们基本上是在通过核对试验来检测自己对那个API的理解程度。测试聚焦于我们想从API得到的东西。

8.3 学习log4j

比如,我们想使用Apache log4j包来代替自定义的日志代码。我们下载了log4j,打开介绍文档页。无须看太久,就编写了第一个测试用例,希望它能向控制台输出“hello”字样。

@Test
public void testLogCreate() {
  Logger logger = Logger.getLogger("MyLogger");
  logger.info("hello");
}

运行上述代码,logger发生了一个错误,告诉我们需要用Appender。再多读一点文档,我们发现有个ConsoleAppender。于是我们创建了一个ConsoleAppender,再看是否能解开向控制台输出日志的秘诀。

@Test
public void testLogAddAppender() {
  Logger logger = Logger.getLogger("MyLogger");
  ConsoleAppender appender = new ConsoleAppender();
  logger.addAppender(appender);
  logger.info("hello");
}

这回,我们发现Appender没有输出流。奇怪,它该有输出流的。在谷歌上得到一点帮助后,我们写了以下代码:

@Test
public void testLogAddAppender() {
  Logger logger = Logger.getLogger("MyLogger");
  logger.removeAllAppenders();
  logger.addAppender(new ConsoleAppender(
    new PatternLayout("%p %t %m%n"), 
    ConsoleAppender.SYSTEM_OUT));
  logger.info("hello");
}

这回行了,“hello”字样的日志信息出现在控制台上!必须告知ConsoleAppender,让它往控制台写字,看起来有点儿奇怪。

很有趣,当我们移除ConsoleAppender.SystemOut参数时,那个“hello”字样仍然输出到屏幕上。但如果取走PatternLayout,就会出现关于没有输出流的错误信息。这实在太古怪了。

再仔细看看文档,我们看到默认的ConsoleAppender构造器是“未配置”的,这看起来并不明显或没什么用,反而像是log4j的一个缺陷,或者至少是前后不太一致。

再搜索、阅读、测试,最终我们得到代码清单8-1。我们极大地发掘了log4j的工作方式,也将得到的知识融入了一系列简单的单元测试中。

代码清单8-1 LogTest.java

public class LogTest {
  private Logger logger;

  @Before
  public void initialize() {
    logger = Logger.getLogger("logger");
    logger.removeAllAppenders();
    Logger.getRootLogger().removeAllAppenders();
  }
  @Test
  public void basicLogger() {
    BasicConfigurator.configure();
    logger.info("basicLogger");
  }

  @Test
  public void addAppenderWithStream() {
    logger.addAppender(new ConsoleAppender(
        new PatternLayout("%p %t %m%n"),
        ConsoleAppender.SYSTEM_OUT));
      logger.info("addAppenderWithStream");
  }

  @Test
  public void addAppenderWithoutStream() {
    logger.addAppender(new ConsoleAppender(
         new PatternLayout("%p %t %m%n")));
      logger.info("addAppenderWithoutStream");
  }
}

现在我们知道如何初始化一个简单的控制台日志器,也能把这些知识封装到自己的日志类中,好将应用程序的其他部分与log4j的边界接口隔离开来。

8.4 学习性测试的好处不只是免费

学习性测试毫无成本。无论如何我们都得学习要使用的API,而编写测试则是获得这些知识的容易而不会影响其他工作的途径。学习性测试是一种精确试验,帮助我们增进对API的理解。

学习性测试不光免费,还在投资上有正向的回报。当第三方程序包发布了新版本,我们可以运行学习性测试,看看程序包的行为有没有改变。

学习性测试确保第三方程序包按照我们想要的方式工作。一旦整合进来,就不能保证第三方代码总与我们的需求兼容。原作者不得不修改代码来满足他们自己的新需求。他们会修正缺陷、添加新功能。风险伴随新版本而来。如果第三方程序包的修改与测试不兼容,我们也能马上发现。

无论你是否需要通过学习性测试来学习,都要有一系列与生产代码中调用方式一致的输出测试来支持整洁的边界。如果不使用这些边界测试来减轻迁移的劳力,我们可能就会超出应有时限,长久地绑在旧版本上面。

8.5 使用尚不存在的代码

还有另一种边界,那种将已知和未知分隔开的边界。在代码中总有许多地方是我们的知识未及之处。有时,边界那边就是未知的(至少目前未知)。有时,我们并不往边界那边看过去。

好多年以前,我曾在一个开发无线通信系统软件的团队中工作。该系统有一个子系统Transmitter(发送机)。我们对Transmitter知之甚少,而该子系统的开发者还没有对接口进行定义。我们不想受这种事阻碍,就从距未知那部分代码很远处开始工作。

对于我们的世界如何结束、新世界如何开始,我们有许多好主意。工作时,我们偶尔会跨越那道边界。尽管云雾遮挡了我们看向边界那边的视线,但是我们还是从工作中了解到我们想要的边界接口是什么样的。我们想要告知发送机一些事:

将发送机置于指定频率,并发出自这个流得到的数据的模拟表示。

我们不知这会如何做到,因为API还没设计出来。所以,我们决定过后再编写细节代码。

为了不受阻碍,我们定义了自己使用的接口。我们给它起了个好记的名字,比如Transmitter。我们给它写了个名为transmit的方法,获取频率参数和数据流。这就是我们希望得到的接口。

编写我们想得到的接口的好处之一是它在我们控制之下。这有助于保持客户代码更可读,且集中于它该完成的工作。

我们将CommunicationsController类从发送器API(Transmitter API,该API不受我们控制,而且还没定义)中隔离出来。通过使用符合应用程序的接口,CommunicationsController代码整洁且足以表达其意图。一旦发送器API被定义出来,我们就编写TransmitterAdapter来跨接。ADAPTER封装了与API的互动,也提供了一个当API发生变动时唯一需要改动的地方。

这套设计方案为测试提供了一种极为方便的接缝。使用适当的FakeTransmitter,我们就能测试CommunicationsController类。在拿到TransmitterAPI时,我们也能创建确保正确使用API的边界测试。

8.6 整洁的边界

边界上会发生有趣的事。改动是其中之一。如果有良好的软件设计,则无须巨大投入和重写即可进行修改。在使用我们控制不了的代码时,必须加倍小心保护投资,确保未来的修改不至于代价太大。

边界上的代码需要清晰的分割和定义了期望的测试。应该避免我们的代码过多地了解第三方代码中的特定信息。依靠你能控制的东西,好过依靠你控制不了的东西,免得日后受它控制。

我们通过代码中少数几处引用第三方边界接口的位置来管理第三方边界。可以像我们对待Map那样包装它们,也可以使用ADAPTER模式将我们的接口转换为第三方提供的接口。采用这两种方式,代码都能更好地与我们沟通,如果在边界两边推动内部一致的用法,当第三方代码有改动时修改点就会更少。

TI硬件笔试面试题型解析上 摘要: 本专栏聚焦大厂硬件笔试面试题解析,当前第14期以德州仪器(TI)为例,涵盖模拟电路与数字电路核心考点。模拟电路部分涉及最大功率传递定理、运放设计(虚短/虚断)、共模抑制比(CMRR)及高频PCB信号完整性;数字电路包括CMOS与TTL对比、建立/保持时间、竞争冒险消除、D触发器分频及“线与”逻辑实现。文章强调通过例题掌握解题方法与知识点,助力读者应对硬件工程岗位的笔试与面试挑战,附常见考点总结与实用建议。全文注重理论与实践结合,提供典型题型解析与设计思路。(150字) 阅读详情

相关推荐

Cadence Virtuoso实战:用gm/Id方法搞定折叠式共源共栅放大器设计(附完整仿真流程)

本文详细介绍了在Cadence Virtuoso设计环境中,运用gm/Id方法高效设计折叠式共源共栅放大器的完整实战流程。该方法通过工艺特征曲线,将设计指标映射到晶体管尺寸与偏置,有效克服深亚微米工艺下传统方法的不足。文章以TSMC 180nm工艺为例,从指标拆解、参数查找、电路搭建、仿真验证到问题调试,提供了清晰、可复现的操作指南,并探讨了自动化脚本与版图考量,助力工程师和学生提升模拟IC设计效率与成功率。

jwt8token的博客 648

代码整洁之道-读书笔记之边界

代码整洁之道之边界

constant_rain的博客 445

保姆级教程:用BIGEMAP和Global Mapper搞定5米精度DEM高程数据下载与处理

本文提供了一份详细的5米精度DEM高程数据处理教程,涵盖从BIGEMAP下载到Global Mapper处理的完整流程。通过实战案例和避坑指南,帮助用户掌握高效下载DEM数据、优化等高线生成及坐标系转换的关键技巧,适用于GIS新手和专业人士。

weixin_34169322的博客 392

代码整洁之道【7】-- 边界

这一章书中全是理论性的东西,再加上中文翻译肯定有词不达意的地方(并未有意冒犯译者,sry),初读起来并没有理解,遂仔细思考后又读了两遍才敢总结。 作者在本章提到“边界”的概念,我个人的理解是:使用外部代码(第三方库提供的API、或者其他模块的服务)与自身项目代码结合的时候,自身项目调用外来代码以及外来代码提供的功能,这两部分代码就是边界。如果干净利落的将这些代码整合,就能保持软件边界的整洁。 一、使用第三方代码(良好的实践范例) 第三方jar包和框架提供者追求通用性,这样就能在多个环境下工作,吸引更多的用户

LifeIsGood 474

保姆级教程:用STM32单片机实现国标交流充电桩的CP信号检测(附完整代码)

本文详细介绍了基于STM32单片机实现国标交流充电桩CP信号检测的全流程,包括硬件设计、软件架构和充电控制实现。通过分压电路设计、ADC配置和状态机逻辑,确保充电过程的安全与可靠性,适用于新能源汽车充电桩开发。附完整代码和调试技巧,助力开发者快速掌握关键技术。

weixin_42641998的博客 252

从零构建C++ Gerber解析器:以PCB缺陷检测为目标的实战指南

本文是一份面向PCB缺陷检测项目的实战指南,详细介绍了如何从零开始使用C++构建高性能的Gerber文件解析器。文章深入剖析了Gerber RS-274X格式,并提供了完整的开发环境搭建、核心数据结构设计、解析步骤实现以及为缺陷检测优化的具体方案,旨在帮助开发者获得对PCB制造数据的深度控制与极致性能。

weixin_29291185的博客 184

代码整洁之道--边界

  我们内部每周都有读书会,最近在读《clean code》,基本上是20分钟左右。总体原则是大家轮流来讲。 我自己也领了其中一章,第八章。这一张特别不巧,书少了3页。整个一章少了一半的内容。于是我自己发挥了一下,希望大家能有所收获。   从接口到类、工程、系统、框架。在做设计的时候关于边界的基本思路是一致的。就是需要在普适性和集中性中做一个权衡。权衡的结果直接就影响着边界。 边界的目的是要...

weixin_34396902的博客 410

Holt-Winters方法预测水电发电量

Holt-Winters 模型, ARMIA,ACF检验 ,Dickey-Fuller 检测,白噪声检测,差分

firefox_yau的博客 1270

代码整洁之道第八章 边界

第八章讨论了如何处理系统和组件的外部边界,以及如何与外部系统和库进行集成。

WayneHu的博客 272

Windows Server 2019 服务器一天之中内存利用率越来越高直到死机,疑似内存泄漏

环境: 华为桌面云虚拟机 Windows Server 2019 版本1809 OS内部版本17763.107 问题描述: Windows Server 2019服务器 一天之中内存利用率越来越高直到死机,不断扩容内存从10G到16G一重启就正常然后慢慢又循环,连续几天都这样,疑似内存泄漏 内存泄漏是什么? 内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪

本博客,博文仅代表个人操作经验,不能完全解决你的问题,仅供参考,佛系回复。 5394

【文献笔记】CVPR 2023|Attention-Based Point Cloud Edge Sampling

优点能够有效采出点云数据的边缘点分类任务性能优越不足没有设计出一个更好的上采样方法,导致分割任务的性能略低只考虑了边缘特征,没有利用其他几何特征。

m0_55908255的博客 321

《代码整洁之道》第8章 边界 - 笔记

这些外部代码是你的**“边界”直接且紧密地依赖**这些外部代码的具体类、方法、异常等细节,那么一旦外部代码发生变化,你的大量应用代码就可能需要修改,变得非常脆弱和难以维护。我们要将外来代码干净利落的整合进自己的项目中。

CoFFee________的博客 1437

R语言生存分析之竞争风险模型

R语言生存分析之竞争风险模型 竞争风险模型(Competing Risk Model)是一种处理多种潜在结局生存数据的分析方法,早在1999年Fine和Gray就提出了部分分布的半参数比例风险模型,通常使用的终点指标是累积发生率函数(cumulative incidence function,CIF)。 研究中结局事件可能有多个,某些结局将阻止感兴趣事件的出现或影响其发生的概率,各结局事件形成“竞争”关系,互为竞争风险事件。 竞争风险模型( Competing Risk Model ) : 指

data+scenario+science+insight 5248

【Code】《代码整洁之道》笔记-Chapter16-重构SerialDate

如果你找到JCommon类库,深入该类库,其中有个名为的程序包。在该程序包中,有个名为SerialDate的类,我们即将剖析这个类。SerialDate的作者是David Gilbert。David显然是一位经验丰富、能力很强的程序员。如我们将看到的,他在代码中展示了极高的专业性和原则性。无论怎么说,SerialDate都是“好代码”,而我将把它撕成碎片。这并非恶意的行为,我也不认为自己比David强许多,有权对他的代码说三道四。其实,如果你看过我的代码,我敢说你也会发现好些该埋怨的东西。

江湖人称菠萝包 1518

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【Code】《代码整洁之道》笔记-Chapter9-单元测试

过去十年以来,编程专业领域进步很大。1997年时,没人听说过测试驱动开发。对于我们之中的大多数人来说,单元测试是那种用来确保程序“可运行”的用过即扔的短代码。我们辛勤地编写类和方法,再弄出一些特殊代码来测试它们。通常这些代码会是一种简单的驱动式程序,让我们能够手工与自己编写的程序交互。我记得在20世纪90年代曾为一套嵌入式实时系统编写过C++程序。想法很简单;到达指定毫秒数时,在一个新线程中执行Command的execute方法。问题在于如何测试它。我随便写了个简单的驱动式程序,聆听来自键盘的动作。

江湖人称菠萝包 1415

【Code】《代码整洁之道》笔记-Chapter11-系统

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

江湖人称菠萝包 1207

【Code】《代码整洁之道》笔记-Chapter14-逐步改进

本章研究一个逐步改进的案例。你将看到一个开始还不错,但规模扩大后即出问题的模块。你还将看到这个模块是如何被重构得整洁起来的。我们中的大多数人都会遇到解析命令行参数的情况。如果没有就手的工具,就得遍历传入main函数的字符串数组。有一些不同来源的好工具,但没有一个是最符合要求的。所以,我当然要自己写一个,我把它叫作Args。Args非常易于使用。你只要简单地用输入参数和格式化字符串构造Args类,再向Args实体询问参数值即可。看看代码清单14-1中给出的简单例子。代码清单14-1 Args的简单用法。

江湖人称菠萝包 1223

【Code】《代码整洁之道》笔记-Chapter10-类

到目前为止,本书一直在讨论如何编写良好的代码行和代码块。我们深入研究了函数的恰当构成,以及函数之间如何互相关联。尽管讨论了这么多关于代码语句及由代码语句形成的函数的表达力,但是,除非我们将注意力放到代码组织的更高层面,否则始终不能得到整洁的代码。

江湖人称菠萝包 1261

【Code】《代码整洁之道》笔记-Chapter7-错误处理

对异常分类有很多方式。可以依其来源分类:是来自组件还是其他地方?也可以依其类型分类:是设备错误、网络错误还是编程错误?不过,当我们在应用程序中定义异常类时,最重要的考虑应该是它们如何被捕获。我们来看一个不太好的异常分类的例子。下面的语句是对某个第三方代码库的调用。try {语句包含了一大堆重复代码,这并不出奇。在大多数异常处理中,不管真实原因如何,我们总是做相对标准的处理。我们得记录错误,确保能继续工作。

江湖人称菠萝包 1312

【Code】《代码整洁之道》笔记-Chapter17-味道与启发

Martin Fowler在其大作《重构:改善既有代码的设计》(Refactoring: Improving the Design of Existing Code)中指出了许多不同的“代码的坏味道”。下面的清单包括很多Martin指出的“坏味道”,还添加了更多我自己提出的“坏味道”,也包括我借以历练本业的其他珍宝与启发。我借由遍览和重构几个不同的程序总结出这个清单。每次修改,我都问自己为什么要这样改,把修改的原因写下来,结果就得到相当长的清单,该清单列出了在读代码时让我闻起来不舒服的味道。

江湖人称菠萝包 1366

【Code】《代码整洁之道》笔记-Chapter4-注释

什么也比不上放置良好的注释来得有用。什么也不会比乱七八糟的注释更有本事搞乱一个模块。什么也不会比陈旧、提供错误信息的注释更有破坏性。注释并不像辛德勒的名单。它们并不“纯然地好”。实际上,注释最多也就是一种必需的恶。若编程语言足够有表达力,或者我们长于用这些语言来表达意图,就不那么需要注释——也许根本不需要。注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。注意,我用了“ 失败”一词,我是说真的,注释总是一种失败。我们总无法找到不用注释就能表达自我的方法,所以总要有注释,这并不值得庆贺。

江湖人称菠萝包 1055

【Code】《代码整洁之道》笔记-Chapter6-对象和数据结构

我们将变量设置为私有(private)有一个理由:不想让其他人依赖这些变量。我们还想在心血来潮时能自由修改其类型或实现。那么,为什么还是有那么多程序员不假思索就给对象添加赋值器(setter)和取值器(getter),将私有变量公之于众,如同它们是公共变量一般呢?

江湖人称菠萝包 1617

【Code】《代码整洁之道》笔记-Chapter12-迭进

假使有4条简单的规则,跟着做就能帮助你创建优良的设计,会如何?假使遵循这些规则,你就能洞见代码的结构和设计,更能轻易地应用SRP和DIP之类的原则,便会如何?假使这4条规则有利于良好的设计“浮现”出来,又会如何?我们中的许多人认为,Kent Beck关于简单设计的4条规则,对于创建具有良好设计的软件有着莫大的帮助。据Kent所述,只要遵循以下规则,设计就能变得“简单”:运行所有测试;不可重复;表达了程序员的意图;尽可能减少类和方法的数量。以上规则按其重要程度排列。

江湖人称菠萝包 920

【Code】《代码整洁之道》笔记-Chapter5-格式

当有人查看底层代码实现时,我们希望他们为代码的整洁、一致及所感知到的对细节的关注而震惊。我们希望他们高高扬起眉毛,一路看下去。我们希望他们感受到专业人士们的劳作。但若他们看到的只是一堆像是由酒醉的水手写出的鬼画符,那他们多半会得出结论,认为项目其他任何部分也同样对细节漠不关心。你应该保持良好的代码格式。你应该选用一套管理代码格式的简单规则,然后贯彻这些规则。如果你在团队中工作,则团队应该一致同意采用一套简单的格式规则,所有成员都要遵从这套规则。使用能帮你应用这套格式规则的自动化工具会很有帮助。

江湖人称菠萝包 1041

【Code】《代码整洁之道》笔记-Chapter1-整洁代码

略。

江湖人称菠萝包 487

【Code】《代码整洁之道》笔记-Chapter2-有意义的命名

起好名字最难的地方在于需要良好的描述技巧和共有文化背景。与其说这是一种技术、商业或管理问题,还不如说是一种教学问题。其结果是,这个领域内的许多人都没能学会做得很好。我们有时会担心其他开发者反对重命名。讨论一下就会知道,如果名称改得更好,那大家真的会感激你。多数时候我们并不记忆类名和方法名,而使用现代工具应对这些细节,好让自己集中精力把代码写得像词句篇章,至少像是表和数据结构(词句并非总是呈现数据的最佳手段)。改名可能会让某些人吃惊,就像你做到其他代码改善工作一样。别让这种事阻碍你前进的步伐。

江湖人称菠萝包 1128

【Code】《代码整洁之道》笔记-Chapter13-并发编程

对象是过程的抽象。线程是调度的抽象。编写整洁的并发程序很难——非常难,而编写在单线程中执行的代码却简单得多。编写表面上看似不错、深入进去却支离破碎的多线程代码也简单,但是系统一旦遭受压力,这种代码就扛不住了。本章将讨论并发编程的需求及其困难之处,并给出一些应对这些难点、编写整洁的并发代码的建议。最后,我们将讨论与测试并发代码有关的问题。整洁的并发编程是个复杂话题,值得用一整本书来讨论。本书只做概览,并在附录A中提供更详细的指引。如果你只是对并发好奇,阅读本章就足够了。

江湖人称菠萝包 1377

【Code】《代码整洁之道》笔记-Chapter3-函数

在编程的早期岁月,系统由程序和子程序组成。后来,到Fortran和PL/1的年代,系统由程序、子程序和函数组成。如今,只有函数存活下来。函数是所有程序中的第一组代码。本章将讨论如何写好函数。请看代码清单3-1。在FitNesse中,很难找到长函数,不过我还是搜寻到一个。它不光长,而且很复杂,有大量字符串、怪异且不显见的数据类型和API。花3分钟时间,你能读懂多少?代码清单3-1 HtmlUtil.java(FitNesse 20070619)读懂这个函数了吗?大概没有。

江湖人称菠萝包 1018
上一篇: 【Code】《代码整洁之道》笔记-Chapter7-错误处理
下一篇: 【Code】《代码整洁之道》笔记-Chapter9-单元测试
江湖人称菠萝包
博客等级 码龄10年 762粉丝 314原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值