Questions tagged «object-oriented»

一种使系统能够建模为一组对象的方法论,这些对象可以模块化方式进行控制和操作

6
了解“编程接口”
我遇到过很多术语“编程为接口而不是实现”,我想我有点理解它的意思。但是我想确保我了解它的好处以及可能的实现。 “对接口进行编程”意味着,在可能的情况下,应该引用一个类的更抽象级别(一个接口,抽象类,有时甚至是某种超类),而不是引用一个具体的实现。 Java中的一个常见示例是使用: List myList = new ArrayList();代替ArrayList myList = new ArrayList();。 我对此有两个问题: 我想确保我了解这种方法的主要好处。我认为好处主要是灵活性。将对象声明为更高级的引用,而不是具体的实现,可以在整个开发周期和整个代码中提供更大的灵活性和可维护性。它是否正确?灵活性是主要好处吗? 还有更多的“编程接口”方法吗?还是“将变量声明为接口而不是具体的实现”是此概念的唯一实现? 我不是在谈论Java构造接口。我说的是OO原则:“编程为接口,而不是实现”。按照这个原理,世界“接口”是指一个类的任何“超类型” -接口,抽象类或简单的超类,它比更具体的子类更抽象,更不具体。

9
为什么大多数“知名”命令式/ OO语言都允许未经检查的类型代表“无”值的访问?
我一直在阅读关于拥有null而不是(例如)的(不便)便利的信息Maybe。阅读本文之后,我相信使用Maybe(或类似方法)会更好。但是,令我惊讶的是,所有“众所周知”的命令式或面向对象的编程语言仍在使用null(这允许对可以表示“无”值的类型进行未经检查的访问),并且Maybe大多数在函数式编程语言中使用。 作为示例,请看下面的C#代码: void doSomething(string username) { // Check that username is not null // Do something } 这里有些难闻的气味...为什么我们要检查参数是否为null?我们不应该假设每个变量都包含对对象的引用吗?如您所见,问题在于,根据定义,几乎所有变量都可以包含空引用。如果我们可以决定哪些变量是“可为空的”而哪些则不是呢?这将节省我们调试和寻找“ NullReferenceException”时的工作量。想象一下,默认情况下,没有类型可以包含null引用。取而代之的是,您将明确声明变量只有在确实需要时才可以包含空引用。那就是Maybe背后的想法。如果您的函数在某些情况下会失败(例如,被零除),则可以返回Maybe<int>,明确指出结果可能是整数,但也没有任何结果!这是选择Maybe而不是null的原因之一。如果您对更多示例感兴趣,那么我建议阅读这篇文章。 事实是,尽管存在使大多数类型默认为可空的缺点,但大多数OO编程语言实际上都可以做到这一点。这就是为什么我想知道: 您必须用null编程语言来实现什么样的参数Maybe呢?完全有原因还是仅仅是“历史包bag”? 在回答此问题之前,请确保您了解null和Maybe之间的区别。

7
“数据隐藏”和“封装”有什么区别?
我正在阅读“实践中的Java并发性”,有人说:“幸运的是,相同的面向对象技术可以帮助您编写组织良好,可维护的类(例如封装和数据隐藏),也可以帮助您创建线程安全的类。” 问题#1-我从未听说过数据隐藏,也不知道它是什么。 问题2-我一直认为封装使用的是私有vs公共,实际上是在隐藏数据。 您能否解释一下什么是数据隐藏以及它与封装有何不同?

12
为什么一个班级除了“抽象”或“最终/密封”之外,什么都不应该?
经过10年以上的Java / C#编程,我发现自己创建了以下任一文件: 抽象类:合同,并非原样实例化。 期末/密封班:实现不打算用作其他任何东西的基类。 我想不出任何简单的“类”(即既不是抽象的也不是最终的/密封的)是“明智的编程”的情况。 为什么一个班级应该不是“抽象”或“最终/密封”之外的任何东西? 编辑 这篇很棒的文章比我能更好地解释我的担忧。

12
每班可以容纳多少人?
我是一位长期的开发人员(我49岁),但是是面向对象开发的新手。自从Bertrand Meyer的Eiffel以来,我一直在阅读有关OO的文章,但是几乎没有做过OO编程。 关键是每本有关OO设计的书都以船,汽车或我们经常使用的任何常见对象为例开始,并且它们开始添加属性和方法,并说明如何建模对象状态以及如何使用对象它。 因此,它们通常会采用“模型越好,模型在应用程序中代表对象的能力越强,结果就越好”的想法。 到目前为止,到目前为止还不错,但是,我发现有几位作者给出了一些食谱,例如“一个类应该放在一个页面上”(我会添加“显示器尺寸是多少?”,因为我们尝试不这样做)打印代码!)。 以一个PurchaseOrder类为例,该类具有控制其行为的有限状态机和的集合PurchaseOrderItem,此处工作的一个论据是,我们应该使用一个PurchaseOrder简单的类,并带有一些方法(比数据类多一点),并且具有PurchaseOrderFSM处理的有限状态机的“专家类” PurchaseOrder。 我想说的是Jeff Atwood 在《编码恐怖》上的Code Smells帖子的“特征嫉妒”或“不适当的亲密关系”分类。我将其称为常识。如果我可以签发,核准或取消我的真正的采购订单,那么PurchaseOrder类应该有issuePO,approvePO而且cancelPO方法。 这不是我理解为面向对象的基础的“最大化内聚力”和“最小化耦合”的古老原则吗? 此外,这是否有助于提高类的可维护性?


6
学习一种功能语言是否会使一个更好的OOP程序员变得更好?[关闭]
作为Java / C#/ C ++程序员,我听到了很多关于函数式语言的讨论,但从未发现有必要学习一种。我还听说过,功能语言中引入的更高层次的思维使您成为更好的OOP /过程语言程序员。 有人可以确认吗?它以什么方式提高了您的编程技能? 为了提高不那么复杂的语言的技能,学习语言的最佳选择是什么?

6
将基本类型(如int)实现为类的注意事项是什么?
设计和implenting面向对象的编程语言时,在某些时候你必须做出有关实现基本类型的选择(例如int,float,double或等价物)类或其他什么东西。显然,C系列语言倾向于不将其定义为类(Java具有特殊的原始类型,C#将其实现为不可变的结构,等等)。 当基本类型实现为类时(在具有统一层次结构的类型系统中),我可以想到一个非常重要的优势:这些类型可以是根类型的适当Liskov子类型。因此,我们避免使用装箱/拆箱(显式或隐式),包装器类型,特殊方差规则,特殊行为等使语言复杂化。 当然,我可以部分理解语言设计者为什么要决定他们的工作方式:类实例往往会有一些空间开销(因为实例可能在其内存布局中包含vtable或其他元数据),因此原语/结构不需要拥有(如果语言不允许继承这些语言)。 空间效率(以及改善的空间局部性,尤其是在大型阵列中)是基本类型通常不是类的唯一原因吗? 我通常认为答案是肯定的,但是编译器具有转义分析算法,因此当实例(任何实例,不仅仅是基本类型)被证明是严格的时,它们可以推断出是否可以(有选择地)忽略空间开销本地。 以上是错误的,还是我还缺少其他东西?

7
函数式编程是否忽略了“关于将系统分解为模块所用的准则”(数据隐藏)所带来的好处?
我第一次读过一篇经典的文章,名为《关于将系统分解为模块的标准》。这对我来说很有意义,并且可能是OOP所基于的那些文章之一。结论: 我们试图通过这些示例来证明,根据流程图将系统分解为模块几乎总是不正确的。...然后每个模块都被设计为对其他模块隐藏这样的决定 以我未受过教育和缺乏经验的观点,函数式编程与本文完全相反。我的理解是函数式编程使数据流变得惯用了。数据从一个函数传递到另一个函数,每个函数都密切了解数据并在此过程中“更改”它。而且我想我已经看过Rich Hickey的演讲,他在演讲中谈到数据隐藏是如何被高估或不必要的,但我不确定。 首先,我想知道我的评估是否正确。FP范式和本文在哲学上是否不一致? 假设他们不同意,FP如何“弥补”缺乏数据隐藏的能力?也许他们牺牲了数据隐藏,但获得了X,Y和Z。我想知道为什么X,Y和Z比数据隐藏更有益的原因。 或者,假设他们不同意,也许FP认为数据隐藏很糟糕。如果是这样,为什么会认为数据隐藏不好? 假设他们同意,我想知道什么是FP数据隐藏实现。很明显在OOP中看到了这一点。您可以拥有一个private班级以外的人无法访问的字段。在FP中,没有明显的比喻。 我觉得还有其他问题要问,但我不知道我要问。也可以随意回答。 更新资料 我发现尼尔·福特(Neal Ford)的演讲中有一个非常相关的幻灯片。我将屏幕截图嵌入此处:


12
SOLID与避免过早抽象
我了解SOLID在模块化很重要且其目标显然有用的情况下应定期完成并使用的功能。但是,有两点使我无法在代码库中一致地应用它: 我想避免过早的抽象。以我的经验,绘制没有具体用例(现在或可预见的将来)的抽象线会导致将它们绘制在错误的位置。当我尝试修改此类代码时,抽象行会妨碍您的工作,而不是有所帮助。因此,我倾向于不画任何抽象线,直到我对它们的用处有了一个很好的认识。 我发现很难证明增加模块化本身是合理的,如果它使我的代码更冗长,更难理解等,并且不能消除任何重复。我发现有时,简单,紧密耦合的过程或God对象代码比构造良好的馄饨代码更易于理解,因为流程简单且线性。编写起来也容易得多。 另一方面,这种心态常常导致神的对象。我通常会保守地重构它们,仅在看到清晰的模式出现时才添加清晰的抽象线条。如果您显然不需要更多的模块化,没有大量重复且代码可读性强,那么上帝对象和紧密耦合的代码怎么办? 编辑:就个别SOLID原则而言,我想强调的是,Liskov Substitution是IMHO的常识形式化,应在所有地方应用,因为如果不是这样的话,抽象是没有意义的。同样,每个类都应该在某个抽象级别上担负单个责任,尽管这可能是一个很高的级别,将实现细节都塞进一个庞大的2,000行类中。基本上,您的抽象应该在您选择抽象的地方有意义。在模块化不是很有用的情况下,我所质疑的原则是开放式,接口隔离,尤其是依赖关系倒置,因为这些都是关于模块化的,而不仅仅是让抽象有意义。

14
管理多少个非OO代码库?
我总是看到抽象是OO为管理代码库提供的非常有用的功能。但是如何管理大型非OO代码库?还是那些最终变成了“ 泥浆大球 ”? 更新: 似乎每个人都在认为“抽象”只是模块化或数据隐藏。但是恕我直言,这也意味着必须使用“抽象类”或“接口”,这对于依赖注入和测试是必须的。非OO代码库如何管理这一点?而且,除了抽象之外,封装还有助于管理大型代码库,因为它定义并限制了数据与函数之间的关系。 使用C,非常有可能编写伪OO代码。我对其他非OO语言了解不多。那么,这是管理大型C代码库的方式吗?

8
是否有某些SOLID原则与清洁代码相反的OOP风格?
我最近与我的一个朋友讨论了有关视频游戏开发中OOP的问题。 我正在解释我的一款游戏的体系结构,令我的朋友惊讶的是,它包含许多小类和几个抽象层。我认为这是我专注于赋予一切单一职责并放松组件之间的耦合的结果。 他担心的是,大量的课程将转化为维护的噩梦。我的看法是,它将产生完全相反的效果。我们进行了长达数个世纪的讨论,最终同意了不同意,说也许在某些情况下SOLID原则和适当的OOP实际上并不能很好地融合在一起。 甚至Wikipedia关于SOLID原则的条目都指出,它们是有助于编写可维护代码的指南,并且它们是敏捷和自适应编程的整体策略的一部分。 所以,我的问题是: 在OOP中是否存在某些或全部SOLID原则不适合清理代码的情况? 我可以马上想象一下,《李斯科夫替代原则》可能与另一种安全继承形式发生冲突。也就是说,如果有人设计了通过继承实现的另一种有用模式,则LSP很可能与其直接冲突。 还有其他吗?也许某些类型的项目或某些目标平台可以使用较少的SOLID方法更好地工作? 编辑: 我只想说明我不是在问如何改善代码;)我在这个问题中提到一个项目的唯一原因是提供一些上下文。我的问题是关于OOP和一般的设计原则。 如果您对我的项目感到好奇,请参阅this。 编辑2: 我以为可以用以下三种方式之一回答这个问题: 是的,存在与SOLID部分冲突的OOP设计原则 是的,存在与SOLID完全冲突的OOP设计原则 不,SOLID是蜜蜂的膝盖,OOP将永远更好。但是,与所有内容一样,它不是万能药。负责任地喝酒。 选项1和2可能会产生很长且有趣的答案。另一方面,选项3是一个简短的,无趣的,但总体上令人放心的答案。 我们似乎正在选择方案3。

6
函数式编程是面向对象的超集吗?
我做的功能越多,我越觉得它会增加一个额外的抽象层,就像洋葱的层如何一样-都包含了先前的层。 我不知道这是否是真的,所以要脱离我多年使用的OOP原则,谁能解释功能如何准确地描述其中的任何一个:封装,抽象,继承,多态性 我想我们都可以说,是的,它具有通过元组进行封装,或者从技术上讲元组是否可以算作“函数式编程”,还是它们只是该语言的实用程序? 我知道Haskell可以满足“接口”要求,但是再次不确定它的方法是否具有功能性?我猜想函子具有数学基础的事实,您可以说函子是对功能的期望而定的,也许吧? 请详细说明您认为功能是否满足OOP的四项原则。 编辑:我了解功能范式和面向对象范式之间的区别就很好,并且意识到现在有很多多范式语言可以同时做到这两种。我真的只是在寻找关于完全fp(例如纯粹主义者,例如haskell)如何完成所列4项中的任何一项的定义,或者为什么它不能做到其中任何一项的定义。即“可以使用闭包来封装”(或者如果我对此信念有误,请说明原因)。

5
如何将OO程序重构为功能性程序?
我很难找到有关如何以功能样式编写程序的资源。我可以在网上找到讨论的最高级的话题是使用结构化类型来减少类层次结构。大多数只处理如何使用map / fold / reduce / etc替换命令式循环。 我真正想找到的是深入讨论非平凡程序的OOP实现,其局限性以及如何以功能样式重构它。不仅是算法或数据结构,还有一些具有不同角色和方面的东西-也许是电子游戏。顺便说一句,我确实读过Tomas Petricek撰写的《现实世界的函数编程》,但是我还想要更多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.