《代码简洁之道》总结六之对象和数据结构

将变量设置为私有有一个理由:我们不想其他人依赖这些变量。我们还想在心血来潮时能自由修改其类型或事项。那么就不要自动添加赋值器和取值器,将私有变量公之于众、如果它们根本就是公共变量一样。


一、数据抽象

即便变量都是私有,并通过变量去之气和赋值器使用变量,仍然暴漏了数据结构。

隐藏实现并非只是在变量之间放上一个函数曾那么简单。隐藏实现关乎抽象!类不简单地用取值器和赋值器将其变量推向外间,而是曝露抽象接口,以便用户无需了解数据的实现就能操作数据本体。

代码不应曝露数据细节,更应该以抽象形态表述数据。这并不只是用接口和/或赋值器、取值器就万事大吉。要以最好的方式呈现某个对象包含的数据,需要做严肃的思考。乱加赋值器和取值器是最坏的选择。


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

对象把数据隐藏于抽象之后,曝露操作数据的函数。数据结构曝露其数据,没有提供有意义的函数。它们是对立的。

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

过程式代码(使用数据结构的代码)便于在不改动既有数据结构的前提下添加新函数,面向对象代码便于在不改动既有函数的前提下添加新类。

反过来也说得通:

过程式代码难以添加新数据结构,因为必须修改所函数。面向对象代码难以添加新函数,因为必须修改所有类。

所以,对于面向对象较难的事,对于过程式代码却较容易,反之亦然。

在任何一个复杂系统中,都会有需要添加新数据类型而不是新函数的时候,这时,对象和面向对象就比较合适。另一方面,也会有想要添加新函数而不是数据类型的时候。在这种情况下,过程式代码和数据结构更合适。

一切都是对象只是一个传说,有时候需要在简单数据结构上做一些过程式的操作。


三、德墨忒尔率(de mo tui er lv)

著名的德墨忒尔律认为,模块不应了解它所操作对象的内部情形。

方法不应调用由任何函数返回的对象的方法。


连串调用通常被认为是肮脏的风格。

Options opts = ctxt.getOptions();

File scratchDir = opts.getScratchDir();

final String outputDir = scratchDir.getAbsolutePath();

上述这些代码是否违法德墨忒尔律,取决于ctxt、Options和ScratchDir是对象还是数据结构,如果是对象,则他们的内部结构应当隐藏而不曝露,而有关其内部细节的知识就明显违反了德墨忒尔律。如果ctx、Options和ScratchDir只是数据结构,没有任何行为,则他们自然会曝露其内部结构,德墨忒尔律也就不适用了。


混杂

一般是对象,一半是数据结构。公共访问器及赋值器都把私有变量公开化,诱导外部函数以过程式程序使用数据结构的方式使用这些变量。此类混杂增加了添加新函数的难度,也增加了新添加数据结构的难度,应避免创造这种结构。它们的出现,展示了一种乱七八糟的设计,其作者不确定---或者更糟糕,完全无视---他们是否需要函数或类型的保护。


隐藏结构


四、数据结构传送对象

最为精炼的数据结构,是一个只有公共变量、没有函数的类。这种数据结构有时被称为数据传送对象,或DTO(Data Transfer Objects)


Active Record

Active Record是一种特殊的DTO形式。它们是拥有公共(或可豆式访问的)变量的数结构,但通常也会拥有类似的save和find这样的可浏览的方法。

往这类数据结构中塞进业务规则方法,把这类数据结构当成对象来用,这是不理智的行为,因为它导致了数据结构和对象的混杂体。

解决方案就是把Active Record当做数据结构,并创建包含业务规则、隐藏内部数据(可能就是Active Record的实体)的独立对象。


五、小结

对象曝露行为,隐藏数据,便于添加新对象类型而无需修改既有行为,同时也难以在既有对象中添加新行为。数据结构曝露数据,没有明显的行为。便于向既有数据结构添加新行为,同时也难以向既有函数添加新数据结构。

在任何系统中,我们有时会希望能够灵活地添加新数据类型,所以更喜欢使用对象。另外一些时候,我们希望能灵活地添加新行为,这时候我们更喜欢使用数据类型和过程。优秀的软件开发者不带成见地了解这种情形,并依据手边工作的性质选择其中一种手段。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值