面向对象设计(OOD)结合了数据及其方法。据我所知,这实现了两件伟大的事情:它提供封装(所以我不关心有什么数据,只关心如何获取我想要的值)和语义(它将数据与名称联系在一起,并且它的方法始终按照最初的预期使用数据)。

那么OOD的优势在哪里呢?相比之下,函数式编程将丰富性归因于动词而不是名词,因此封装和语义都是由方法而不是数据结构提供的。

我使用的系统处于功能范围的一端,并且一直渴望面向对象的语义和封装。但我可以看到,OO 的封装可能成为对象灵活扩展的障碍。所以目前,我可以将语义视为更大的优势。

或者封装是所有有价值的代码的关键吗?

编辑:我特指的是 OO 在这里提供的封装类型。 changeColor(door,blue) 变成 door.changeColor(blue).

有帮助吗?

解决方案

您似乎使用的一个相当狭窄的定义,“封装”我会假设你定义的封装是是正确的,“与方法相结合的数据?”

如果我错了,那么请忽略这篇文章的其余部分。

封装不是松散术语;事实上,它是由国际标准化组织定义。开放分布式处理的ISO参考模型 - 定义了以下五个概念:

实体:任何所关心的具体或抽象的事

对象:实体的模型。对象的特征是它的行为和,双重,通过它的状态。

行为(一个对象的):用一组约束的动作时,可能会发生在他们的集合

接口:一个由该对象一起的一组约束的交互的子集的时可能出现它们上的对象的行为的抽象

封装:包含在一个对象中的信息是可访问的,只有通过在由对象所支持的接口的交互的属性

我们还可以做一个不言自明的建议:一些信息,通过这些接口访问,有些信息必须被隐藏和对象内无法访问。属性这样的信息呈现出被称为信息隐藏,其中通过帕尔纳斯主张模块应该被设计为隐藏既困难决定和可能改变,见大计算论文之一决定定义:

http://www.cs.umd.edu/类/ spring2003 / cmsc838p /设计/ criteria.pdf

要注意的是,它不仅是信息隐藏的数据是非常重要的:它是与困难或有可能改变对象相关行为的某个子集

在你的帖子,你似乎是说,在面向对象和函数式编程封装之间的区别,从数据管理茎,但至少根据ISO和帕纳斯,数据管理并不是关键封装。所以,我不明白为什么封装在函数式编程需要从任何不同的OO。

您提到,此外,在您的文章是函数式编程提供封装,“......由这些方法而不是数据结构。”这一点,我认为,是规模的差异,而不是绝对的。如果我用这个词,“对象”,而不是“数据结构”(再次,请让我知道如果我误解),那么你似乎找到OO的封装的对象和方法函数式编程的封装意义。

然而通过上述ISO定义,对象是什么,我要建模。由此类可以在封装内被封装,只要一些这些类的向包的接口(即,使用公共类的包的)和一些信息隐藏(私有类在包)。

同理,方法被封装在一个类中 - 的一些方法是公共和一些私人。你甚至可以把这个缺口低,说的代码McCabian连续序列被封装方法中。每个形成包封的区域内的包封的节点的图形;和所有这些曲线形成一个图栈。因此功能的编程可以在函数/文件级别以及封装,但是这是从OO的方法/类图形没有什么不同,并且从OO的类/包图形基本上没有差别或者

而且,注意,字尔格上述用途:改变。信息隐藏涉及潜在的事件,如在未来艰难的设计决策的变化。你问哪里OO的实力的谎言;还有,封装肯定是OO的实力,但接下来的问题是,“哪里封装的实力在哪里?”,答案是响亮清晰的一个:茶NGE管理。特别地,封装降低变化的最大潜能负担。

的,概念“潜在耦合”,是有用这里。

“耦合”,本身是在另一个的计算的大文件定义为“通过从一个模块到另一个模块的连接建立的关联的强度的度量,”:

http://www.research.ibm.com/journal/ SJ / 382 / stevens.pdf

和作为纸张说,在字永不自做得更好,“最小化模块之间的连接也最小化沿其改变和错误传播到系统的其它部分,从而消除灾难性,路径‘涟漪’效应,其中,改变在在另一个部分的原因的错误,因此需要额外的变化别处,从而产生新的错误,等。”

如这里定义的,然而,有两个限制,其可以很容易地解除。首先,耦合不测量模块内的连接,并且这些模块内的连接可以产生同样多的,“涟漪”的效果的模块间连接(纸张确实定义,“凝聚”,以涉及模块内元件,但这不是在元件之间的连接来定义(即,标签或地址的参考文献)与偶联定义)。其次,任何计算机程序的耦合给定的,在模块连接或;有耦合的定义范围内的小范围,以管理其尔格讲电位的变化。

这两个问题都解决了,在一定程度上,与电位耦合的概念:最大可能数量的程序的所有元素之间的可成形的连接。在Java中,例如,一类是在封装件内包专用(缺省存取)已经不能在其上形成(即,没有外部类可以依赖于它,尽管反射)的连接,但一个封装内的公共类可以有依赖它。这个公共类将有助于潜在的耦合即使没有其他类依赖于它的那一刻 - 类可能依赖于它在将来,当设计变更

要看到封装的实力,可以考虑负担的原则。负担的原则有两种形式。

在强形式指出变换实体的集合的负担是转化的实体的数量的函数。弱形式指出变换实体的集合的最大潜能负担变换实体的最大可能数量的函数。

创建或修改任何软件系统的负担的创建或修改的(在这里我们使用“类,”假定的OO系统,并且所关心的在类/包级封装类的数量的函数;我们同样可以有函数式编程的功能/文件级别来讲我们自己)。 (请注意,“包袱”,是现代软件开发通常是成本,或时间,或两者兼而有之。) 依赖于特定的,经修饰的类的类具有被影响比不依赖于修改的类的类的较高概率。

在最大潜力负担修饰的类可以强加是依赖于它的所有类的冲击。

减少对一个修改的类的依赖关系因此减少它的更新将影响其他类的概率,进而减少最大电位负担那类可以强加。 (这比的重新陈述,“结构化设计,”纸更小。)

因此

减少系统中的所有类之间的依赖关系的最大可能数目减少了一个特定类的冲击会导致更新其他类的概率,并因此减少所有更新的最大潜在负担。

封装,通过减少DEPE的最大可能数目ndencies各阶层之间,因此减轻负担的原则的弱势形态。这是所有覆盖,“封装理论”,其试图数学证明这样的断言,使用电位耦合作为构造一个程序的逻辑装置。

请注意,但是,当你问,“难道封装的关键,一切都是值得的代码”答案肯定是:没有。没有任何单一的键,将所有有价值的代码。封装是,在某些情况下,仅仅以帮助改善的代码的质量,使得它可以成为,一个工具“是值得的。”

您也写的是,“......封装可能是一个障碍为对象的灵活扩展。”是的,它肯定能:这的确是设计的一个障碍反对扩大对象的设计决策困难或有可能改变。这是没有,不过,被认为是一件坏事。另一种方法是让所有的类公共和有一个程序表达其最大的潜力耦合;但随后负担的原则的弱形式指出,更新将变得越来越昂贵;这些都是成本针对其扩展障碍是待测量

最后,你做封装和语义,并且之间的有趣的对比,在您看来,面向对象的语义是其更大的力量。我不是语义学是(我甚至不知道这样的好拉姆齐先生提到在他的评论之前存在一个字),但我想你的意思是,在意义上的“语义”,“的含义,或的含义的词,解释“,并且非常基本上是具有一个类,纬纱()方法应该被称为犬。

有这个语义强大的实力确实如此。

什么是好奇,我是你坑语义对封装和寻找一个赢家;我怀疑你会发现一个。

在我的意见中,有两个力量激励封装:语义和逻辑

语义封装仅仅意味着基于所述节点(要使用的总称)包封的含义封装。所以,如果我告诉你,我有两个包,一个叫“动物”,一个叫“矿泉水”,然后给你三个类狗,猫和山羊,并要求打包到这些类应该被封装,然后,给没有其他的信息,你会权利要求,该系统的语义将表明这三个类来的,“动物”,包内封装,而不是,是完全正确的“矿物”。

在其他动机的封装,但是,是逻辑,和潜在的耦合的特别研究中,如上所述。封装理论实际上提供方程应当用来封装以最小化潜在的耦合了若干类的包的数量。

对于我来说,封装作为一个整体是这样的语义和逻辑方法之间的权衡:我不允许我的程序的潜在耦合上升高于最低,如果这使得程序语义上更容易理解;但潜在的耦合的巨大浪费和水平将是我的程序需要重新构建,无论警告是多么语义明显。

(如果良好的拉姆齐先生还在读书,你或你的朋友语义学能给我一个更好的词了,“语义”的阶段,我在这里使用?这将是很好的使用更恰当的词。 )

此致 编

其他提示

封装和所得抽象显然OO的主要优势。该“东西”谓语是什么“动作”可以对它们进行调用,所以名词取比动词更高的语义重要性。

最终,很难想象设计以一致的和可保持的形式的复杂系统,而不包封的某一水平。

作为一个Lisp编程,它的对象系统可以说是提供了这些都不,我说:无上述的

JWZ:“伪Smalltalk的对象模型失去和通用的功能(通过适当地限制了无外部重写规则)取胜”

我觉得需要的属性,你和其他人在这里列出(封装,模块等)都没有固有的OO像你想象的。他们经常一起提供的Java风格的OO,但不是纯粹它的后果。

隔离复杂性 在我看来,任何设计的主要目标是:将功能封装在接口后面 使用更简单 比功能本身。

OO 为此提供了各种机制 - 两个 oyu 提到:

封装 允许设计独立于实际实现的自定义表面。(换句话说,“更简单意味着不同”)。

语义学 允许对代表问题域元素的实体进行建模,因此它们更容易理解。


任何达到一定规模的项目都会成为管理复杂性的练习。我敢打赌,多年来,编程已经突破了我们学会管理的复杂性的极限。

我已经多年没有涉足函数式编程了,但根据我的理解,最好用数学家对“强大”、“优雅”、“美丽”这些词的含义来描述它。在这种情况下,“美丽”和“优雅”试图描述对复杂系统的真实或相关结构的出色洞察,从令人惊讶的简单角度看待它。它接受给定的复杂性,并尝试驾驭它。

根据我的理解,您提到的灵活性是根据您的需求更改 POV 的能力 - 但这与封装相反:从一个立场来看毫无意义的细节可能在另一个立场上是唯一相关的。

OO,OTOH,是还原论方法:我们通过进入更高的水平来改变 POV。在“旧的 OO”中,存在单一的 POV 层次结构,在此模型中,接口是对不同 POV 进行建模的一种方式。

如果我可以这么说的话,面向对象的优点是更适合“普通人”。

某种形式的 模块化 是任何可扩展设计的关键。人类的局限性使得人们无法一次“摸索”太多的信息,因此我们必须将问题细分为可管理的、有凝聚力的块,两者都为解决问题提供基础。 理解 一个大项目,以及一个方法 细分工作任务 一个由多人参与的大型项目。

如何选择对大型项目最有效的“划分”/“分区”来实现上述目标?经验表明,OO 是这里的大赢家,我想很多人都会同意,OO 擅长这方面的两个关键属性是:

  • 封装的: :每个类都封装了一个“秘密”——一组特定于实现的假设,这些假设可能会随着时间的推移而对其实现进行更改——并公开一个与这些假设无关的接口;对此类封装的抽象进行分层使得构建稳健的设计成为可能,其中组件/实现可以在面对预期的变化时轻松交换。
  • 以名词为中心: :在大多数领域中,人类似乎首先通过思考领域的名词/数据来分解领域模型,然后识别与每个名词相关的支持性动词。

关于函数式编程 (FP) 与 OO,我有 写博客 关于这一点,但简单地说,我认为 FP 更多的是关于实现技术,而 OO 更多的是关于程序结构和设计,因此两者是互补的,OO 在规模的“大”端更占主导地位,而 FP 更占主导地位在“小”端。也就是说,在大型项目中,高层结构最好由 OO 类设计来描述,但许多模块级细节(实现以及模块接口形状的细节)最好由 FP 来塑造影响。

面向对象设计的强度正比于多少后期绑定发生在设计中。这是面向对象的概念凯,而不是尼加德概念。 艾伦凯写道

  

OOP对我来说意味着只有消息,本地   保留和保护和隐藏   状态的过程,和极端的   万物后期绑定。有可能   在Smalltalk和LISP完成。那里   是可能的其他系统,其中   这是可能的,但我不知道   它们。

许多文献忽略有利于面向对象的C ++想法的后期绑定。

让我们退后一步,看看这从一个更高的水平。在能力的任何语言特征谎言的优点简洁地相对于所述问题域表达在更自然的方式问题/溶液

OOP的机械结构都与结构和函数指针纯C容易地实现。你甚至可以得到一点OOP的感觉做这种方式。然而,OOP成语都几乎没有在这样一个环境中即将出台。当有对OOP实际语言的支持,则范式的表现出来的方式,以及语言实现的想法,对什么是“说”,以及如何一个非常现实的影响。例如,使用封闭/ lambda表达式在LISP,蟒,红宝石等看到代码差异。

那么,到底是不是组件和基本概念,而是他们是如何放在一起,使用,使OO在C ++中它是什么。

封装在与多态性结合使用。类在大多数OOP语言来实现一个或多个接口的能力已经对我的软件发展的影响最大。此功能可以让我准确地定义两个物体之间的相互作用。

不仅定义了相互作用,但将其记录下来,这样年后我能恢复到的代码段,看看清楚发生的事情。

此特征是为什么我更喜欢使用OOP语言以上功能的语言的主要原因。写在函数式语言虽然很强大,我发现软件是在维护周期在十年进行测量,以保持一种痛苦。 (在AutoCAD发现AutoLisp的软件)

IMHO,OO仅仅意味着与其他对象相互作用的对象。 封装只是意味着抽象的概念。所以,你创造的东西Socket和.Connect()。它是如何连接,你真的不关心(这基本上是我封装的定义)。

和,纯功能的编程可以使用对象进行通信..但这些对象必须是不可变的。所以,再次恕我直言,FP可以很容易地使用面向对象的概念;命令式语言如C仍然可以使用面向对象的概念..的,例如,对于每一个“类”一个文件,不应该使用的私有部分。

您的问题读起来像是 您想从......中获益? 通过对一块砖的分析来了解房子。

具备提供语义上下文和封装的能力 只是 OO 中类的基本功能。(就像砖头可以 承受一定的力量,占据一定的空间)。

继续类比:为了最大限度地利用积木,只需将它们放在一起即可。"(《世界人权宣言》) 这同样适用于类和对象。

那里 有很多设计模式 可用于 OO 编程它们大多依赖于 "封装 "能力和 您提到的 "语义"。

其中一些模式甚至是对第三段的回答 您的问题:

  • 如果您想扩展现有类的行为,您可以创建派生类。
  • 如果您想扩展或更改现有对象的行为,您可以考虑 装饰器模式.

OO的真实能力在于多态性,而不是封装。封装,在一定程度上,是可以实现的,并在函数式语言被使用,但是如果在功能语言实现多态性将是很别扭。

(由读 “设计图案”四人帮理解OO的功率。)

@Phil,你提到的,如果我理解正确的差异,是程序调用数据/方法的方式之间:在面向对象,有第一种是对象/实例,然后将数据/被调用对象的方法通过对象;在功能性,方法是直接调用。

然而,在寻找一个功能程序的执行情况,我们看到,数据和方法被包裹(在文件中而不是在一个类)。例如,C程序都有一个声明其他文件访问的函数的头文件,如果只有通过这些声明的函数访问的数据是私人数据。只要一个程序员足够细心,最OO封装可以在功能的程序来实现。 (即使是继承可通过使用某些指针技巧。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top