0%

在C#中,throwthrow ex都用于抛出异常,但它们在异常堆栈跟踪处理上有重要区别。

  • throw ex resets the stack trace (so your errors would appear to originate from HandleException) 重置堆栈跟踪

  • throw does not - the original offender would be preserved. 保留堆栈跟踪

阅读全文 »

本篇记录读完第1和2章内容的一些收获。

  • .NET Core 不是 .NET Framework 的升级版,而是一个从头开始开发的全新平台,因此在 .NET Framework 下开发的程序不能直接在 .NET Core 下运行

  • .NET Core 的很多代码都是直接从 .NET Framework 中迁移或改造过来的,这就意味着绝大多数类的用法没变

  • AppDomain 不再被 .NET Core 支持,在 .NET Framework 中,AppDomain 可以用来在进程内对代码执行进行隔离,但其本身有很多缺陷和局限,.NET Core 不再支持

  • .NET Standard 是一个规范,只是规定了需要被实现的规范,但不负责具体实现

  • .NET Standard 定义了 .NET Core、.NET Framework、Xamarin 的交集,只要是 .NET Standard 类库,都可以被 .NET Core、.NET Framework 和 Xamarin 等项目引用

  • C# 9.0 中新增 Record 类型,编译器会自动生成 Equals、GetHashcode 等方法,是一个语法糖,用于简化一种pattern的类编写

  • 在需要编写不可变类并且需要进行对象值比较时,使用 Record 可以大大简化代码编写

阅读全文 »

Robert 认为编程是一种技艺甚于科学的东西,要编写整洁代码,必须先写肮脏代码,然后再清理。

跟写作文先写草稿,再写第二稿,直至最终写出终稿,这是一个逐步改进的过程。

写出能工作的程序远远不够 ,要以整洁代码为目标,只有达到整洁代码后,才可转移到下一个任务上。

阅读全文 »

对象是过程的抽象,线程是调度的抽象

  1. 并发是一种架构设计:并发不是简单的 “用 Thread 跑个任务”。它是一种宏观的设计决策,应该在架构设计早期就考虑,而不是事后添加。它可以将“做什么”和“何时做”解耦。

  2. 并发与性能不是等价的

    • 并发结构性问题。旨在让程序在同一时间做多件事(更清晰的设计)。

    • 并行性能问题。旨在让程序在更短的时间内做一件事(提高速度)。

    • 并发可以带来并行,从而提升性能,但这不是唯一目的。并发只有在多个线程或处理器之间能分享大量等待时间的时候管用

  3. 并发编写的核心难点对共享数据的正确访问。不同执行线程对同一数据资源的竞争和协作是万恶之源。

  4. 并发防御原则

    • 单一权责原则 (SRP):并发相关的代码应该有自己独立的开发、修改和调优的生命周期。不要将并发代码与其他业务代码混在一起。

    • 限制数据作用域:共享数据是危险的。严格限制哪些数据可以被共享,并通过精细的同步机制来保护它们。

    • 使用数据副本:尽可能避免共享,使用数据的副本进行处理。

    • 线程应尽可能独立:让每个线程在自己的世界中运行,不与其他线程共享数据。例如,使用 ThreadLocal 变量。

阅读全文 »

通过迭进设计达到整洁目的

简单设计 4 规则:

  1. 运行所有测试 Run all the tests

  2. 不可重复 Contains no duplication

  3. 表达了程序员的意图 Expresses the intent of the programmer

  4. 尽可能减少类和方法的数量 Minimizes the number of classes and methods

阅读全文 »

在阅读本章时,不是太明白,遂借助 deepseek 理解本章:

核心思想:构造与使用分离

这是本章最根本、最重要的理念。作者认为,系统混乱的主要根源在于:

构造(Construction) 和 使用(Use) 这两件事被混在了一起。

  • 构造:创建对象、定义依赖关系、组装应用程序结构的过程。(如何将零件组装成引擎

  • 使用:系统运行时,对象之间协作执行业务逻辑的过程。(如何踩油门让汽车跑起来

将这两者混杂,会导致代码职责不清、难以测试和维护。一个整洁的系统架构应该将这两者清晰地分离开。

阅读全文 »

类的组织 Class Organization

公共函数调用的私有函数,紧跟公共函数后,这符合自上向下原则,让程序读起来像一篇报纸文章

封装 Encapsulation

有时为了测试,会把 private 的变量或函数变成 protected 或 Internal 的

首先想办法隐藏,保有隐私,发送封装总是下策

阅读全文 »

TDD 三定律 The Three Laws of TDD

  • 在编写不能通过的单元测试前,不可编写生产代码

  • 只可编写刚好无法通过的单元测试,不能编译也算不通过

  • 只可编写刚好足以通过当前失败测试的生产代码

保持测试整洁 Keep Tests Clean

脏测试等同于没测试

测试不干净 -> 改动代码能力受到限制 -> 失去改进代码结构的能力 -> 代码腐化

阅读全文 »

使用第三方代码 Using Third-Party Code

在接口提供者和使用者之间存在与生俱来的矛盾

  1. 第三方程序包或框架提供者追求普适性,能在多种环境中工作,从而吸引广泛的用户

  2. 使用者想要得到集中满足特定需求的接口

因此,应该对第三方代码进行适当的封装

阅读全文 »

错误处理很重要,但是如果它搞乱了代码逻辑,就是错误的做法

使用异常而非返回码 Use Exceptions Rather Than Return Codes

  • 将逻辑和错误处理隔离

先写 try-catch-finally 语句 Write Your Try-Catch-Finally Statement First

异常的妙处在于:它们在程序中定义了范围,执行 try-catch-finally 语句中 try 部分的代码时,你是在表明可随时取消执行,并在 catch 语句中接续

在某种意义上,try 代码块就像是 事务

  • 最好先写出 try-catch-finally 代码块,能帮你定义该代码的用户 应该期待什么

尝试编写强行抛出异常的测试,再往处理器中添加行为,使之满足测试要求

阅读全文 »