我对数据隐藏的OOP原则有疑问。
据我了解, 数据隐藏=将结构的内部字段限制为可见的特定区域。 动机:如果更改结构内容,则只需要更改可见性范围内的实现。
为了执行数据隐藏原则,oop设计人员大多数决定这样做:
方法1:
封装=使可见区域成为结构本身(类),并将对其进行操作的函数(方法)放入内部。
这对我来说似乎是一个很大的要求。并造成许多不必要的不对称。 为什么OOP设计者为什么不决定以这种方式定义封装:
方法2:
让程序员控制可见范围。可见性区域可能包括多个结构,而不仅仅是一个。 在此可见性区域中定义可以在多个结构之间运行的功能。 通过这种方式,结构和功能可以更独立地生活,具有更多的对称性,可能需要更少的吸气剂/阻气剂。
让我举个例子:如果您有一个玻璃物体和一个瓶子物体,它们内部含有一些水。假设您要实现一种从瓶子填充玻璃的功能。
在方法1中,您被迫做一些不对称的事情,您必须实现glass.fill(bottle)或实现bottle.fill(glass),所以听起来您有解决不必要的难题。不仅如此,假设您实现了glass.fill(bottle),现在您处于glass的作用域内,无法访问bottle的内部,因此您必须在bottle中编写一个方法,以便能够对其进行更新。 在我看来,这是许多不必要的工作,而这种强制的bottle.update方法听起来对数据隐藏更有害。
使用方法2,您可以仅定义一个独立的填充物(玻璃,瓶子),因为玻璃,瓶子和填充物可能是同一可见性区域的一部分,所以它可能只知道玻璃和瓶子的内部结构。听起来容易吗? 请注意,您仍然可以使用这种方法定义协议(接口), 在外部,您只需要知道玻璃和瓶子是未指定的东西,而fill就是对两个东西进行操作的操作:玻璃和瓶子。
我的论点是否有缺陷?是否有尝试强调这种排序方法的编程语言?
答案 0 :(得分:0)
在这种编程语言设计(IMHO)的“哲学”层面上,确实没有是非非。实际上,大多数编程语言确实提供了某种程度的“包”可见性,从而允许定义的类一起以更开放的方式相互访问。
从数据隐藏的角度来看,fill(Bottle, Glass)
是否比Bottle::fill(Glass)
更具优势的问题对我来说还是个未知数,但是我认为复杂性可以用两种方式隐藏。不过我了解到的是,最好有一个依赖关系的有向图,而不是循环或双向依赖关系。
答案 1 :(得分:0)
您说“方法2”可能需要“减少吸气剂/吸气剂”。这很奇怪,因为“方法1”应该已经不需要。如果行为是数据所在的位置,则您 不需要“获取”或“设置”数据。
第二,“方法2”是“更轻松”还是“方法1”是否“强迫”您以与您的直觉相反的方式做事,这根本不重要。真正重要的是代码是否可以长期维护。无论是更难写还是给作者带来不便都无关紧要,因为让读者理解它并且使更改大部分保持局部是非常重要的。
这就像马克·吐温的名言:“我没有时间写一封短信,所以我写了一封长信。”编写简单易懂的代码很困难。约束,即强迫作者使用某些习惯用法或风格是 good (好吧,假设约束是有意义的)。
答案 2 :(得分:0)
以您的玻璃杯和瓶子为例,您希望玻璃杯响应的信息是“接收到一定量的水”;瓶子响应的信息是“供应此水量”。
杯子不需要知道水从哪里来,瓶子也不需要知道水往哪里去。所有玻璃物体需要知道的是要装满其容量或所供应的水量。并且瓶子知道要供水,直到瓶子变空或收到停止消息为止。
因此,杯子响应“填充”消息的方法签名为void glass::fill(double volume)
,瓶子响应“供应”消息的方法签名为double bottle::pour()
。 (可以想象,“浇注”和“填充”将以增量进行。)
如您所见,使用这种方法,无需共享任何内部知识。例如,glass::fill()
方法将一直运行到达到内部不变性(例如其容量)为止,此时它可以抛出异常“ glass full”;类似地,bottle::pour()
方法将一直起作用,直到瓶子为空,或者捕获到“玻璃杯已满”例外,这时倒入将停止。
-
我发现许多开发人员错误地认为对象需要始终直接进行通信。但是,那是不正确的。通常,他们会在处理的消息中收到“外部Universe”的快照。在上面的示例中,发送到glass
对象的快照是在特定时刻注入的水量(这就是为什么我认为在数字世界中将逐渐进行浇注和填充的原因)。>
答案 3 :(得分:0)
通常,瓶子既不能自动填充杯子,玻璃本身也不能填充瓶子。有一个外部协调器负责从瓶子中填充玻璃。
这反映在您的第二种方法中,在该方法中,您建议采用fill()
和Glass g
的方法Bottle b
。
从OOAD的角度来看,现在您需要做的就是-创建一个外部协调器类(也许是Person
),该类会将瓶中的内容倒入玻璃杯中。 fill(Glass g, Bottle b)
方法将适当地属于Person
类。