进一步改进的 3位减法器 示例, 被减数和减数均可以为负数(并能正确显示), 最终运算结果在 -8~7 之间也能正确显示, 超出此范围的将不能正确显示:

被减数和减数均可为负数的 3 位减法器示例

在线可互动操作的 被减数和减数均可为负数的 3 位减法器示例

得益于之前 LED 补码解码显示模块的封装, 使得可以同时显示三个负数, 而界面也不至于过于拥挤及杂乱.

一个简化的 3位减法器 示例, 通过对模块的进一步封装及抽象, 引入了 求补器, 补码LED解码器(其内部封装了求补器及多位选择器) 等模块,从而使得各种细节得以隐藏, 大为减少各种连线:

更为简化的 3 位减法器示例

在线可互动操作的 更为简化的 3 位减法器示例

当然, 由于 circuitjs 本身的一些局限, 比如无法封装一个显示模块(如 LED 七段数码管), 无法使用总线(比如数据总线, 地址总线)等限制, 想要构建更多位的更复杂的电路还是比较麻烦的.

为文章内容增加了目录, 从 heading 标签中自动抽取.

对于一个比较长的文章来说, 有了目录导航也更加方便, 也便于用户掌握文章整体结构.

对于写作者而言, 先有一个清晰的写作大纲也有助于写出更有条理的文章.

这一点对于写代码而言也是类似的, 也是抽象原则的体现, 低层次的目录类似于函数(方法), 高层次的目录类似于类(class)乃至模块(module).

一个目录示意图:

目录示意图

重复性管理--抽象的重要性(下)

什么是抽象及它在重复性管理中的作用

接着 上一篇的谈论, 继续谈论抽象在重复性管理中的重要作用.

好的抽象与糟糕的抽象?

通过前面的一些例子, 你可能形成了一个印象: 所谓抽象很多时候就是把一些代码封装到一个方法中.

不过事实上并不是这么简单的. 抽象的结果确实很多时候产生了一个方法, 但不是说我把一堆代码整在一块就是一个抽象, 又或者说, 即便它是一个抽象, 但可能却不是一个好的抽象, 而是一个糟糕的抽象.

假如你看到一段代码很长, 然后你"啪"的一声把它从中间拦腰截断, 划分出两个方法来, 一个叫 firstPart(), 一个叫 secondPart(), 那么这算是怎样的一个抽象呢?

继续阅读

重复性管理--抽象的重要性(上)

什么是抽象及它在重复性管理中的作用

Haskell 语言的设计者之一 Paul Hudak 曾说过一句略带夸张的话(overstatement):

编程中最重要的三件事是: 抽象, 抽象, 抽象.

"abstraction, abstraction, abstraction" are the three most important things in programming.

如果你去问一些资深开发者, 程序员最重要的的能力之一有哪些? 那么"抽象的能力"是绝对能排得上号的.

继续阅读