Questions tagged «object-oriented»

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

8
面向对象的类设计
我想知道好的面向对象的类设计。特别是,我很难在以下两个选项之间做出选择: 静态与实例方法 没有参数或返回值的方法 vs 有参数和返回值的方法 重叠与独特的方法功能 私人与公共方法 范例1: 此实现使用实例方法,没有返回值或参数,没有重叠的功能,并且所有方法都是公共的 XmlReader reader = new XmlReader(url); reader.openUrl(); reader.readXml(); Document result = reader.getDocument(); 范例2: 此实现使用静态方法,返回值和参数,功能重叠和私有方法 Document result = XmlReader.readXml(url); 在示例一中,所有方法都是公共实例,这使得它们易于进行单元测试。尽管所有方法都不同,但readXml()依赖于openUrl(),因为必须首先调用openUrl()。所有数据都在实例字段中声明,因此,除了构造函数和访问器之外,任何方法都没有返回值或参数。 在示例二中,只有一种方法是公共的,其余的是私有静态的,这使得它们很难进行单元测试。方法是重叠的,因为readXml()调用openUrl()。没有字段,所有数据均作为方法中的参数传递,并且结果立即返回。 我应该遵循什么原则来进行正确的面向对象编程?

9
继承出错
我有一些代码,其中一个好的继承模型已经走下坡路,我试图理解为什么以及如何修复它。基本上,假设您有一个Zoo层次结构,其中: class Animal class Parrot : Animal class Elephant : Animal class Cow : Animal 等等 您有自己的eat(),run()等方法,一切都很好。有一天,有人来说-我们的CageBuilder类工作得很好,并使用了animal.weight()和animal.height(),但新的非洲野牛实在太强了,可以打碎墙壁,所以我要补充一下Animal类的另一个属性是isAfricanBizon(),并在选择材质时使用该属性,并且仅对AfricanBizon类覆盖它。下一个人来做类似的事情,下一件事您知道您具有所有特定于基类中层次结构子集的属性。 改善/重构此类代码的好方法是什么?这里的一种替代方法是只使用dynamic_casts来检查类型,但是这会使调用者混乱,并在整个位置添加一堆if-then-else。您可以在此处具有更多特定的接口,但是如果您仅有的话,那么基类引用也无济于事。还有其他建议吗?例子? 谢谢!

5
多种方法优于切换的优势
我今天收到一位高级开发人员的代码审查,询问“顺便问一下,您反对通过switch语句分派功能吗?” 我已经在很多地方读到了关于如何通过切换到调用方法来泵送参数是不好的OOP,而不是可扩展的,等等。但是,我无法真正为他提供明确的答案。我想一劳永逸地解决这个问题。 这是我们的竞争代码建议(以php为例,但可以更普遍地应用): class Switch { public function go($arg) { switch ($arg) { case "one": echo "one\n"; break; case "two": echo "two\n"; break; case "three": echo "three\n"; break; default: throw new Exception("Unknown call: $arg"); break; } } } class Oop { public function go_one() { echo "one\n"; } public function …

9
避免从C移植到面向对象的陷阱,对您有用的是什么?
我已经使用过程语言进行编程已有一段时间了,我对问题的第一反应是开始将其分解为要执行的任务,而不是考虑存在的不同实体(对象)及其关系。 我在OOP上过一门大学课程,并且了解封装,数据抽象,多态性,模块化和继承的基础知识。 我阅读了/programming/2688910/learning-to-think-in-the-object-directional-way和/programming/1157847/learning-object-directional-thinking,并将查看这些答案中指出的一些书籍。 我认为我的一些中型到大型项目将受益于OOP的有效使用,但是作为一个新手,我想避免耗时的常见错误。 根据您的经验,这些陷阱是什么?解决这些陷阱的合理方法是什么?如果您能解释为什么它们是陷阱,以及您的建议如何有效解决该问题,将不胜感激。 我正在考虑类似“是否有大量观察者和修饰符方法并使用私有变量,或者是否有用于合并/简化它们的技术?”这样的思路。 如果有充分的理由混合使用方法,我不担心将C ++用作纯OO语言。(尽管有节制,但让人想起使用GOTO的原因。) 谢谢!

12
C ++不适合OOP吗?[关闭]
按照目前的情况,这个问题并不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 我在这里某个问题的答案之一(不记得是哪个)中读到C ++不适合面向对象的编程。有人提到您可以利用它的功能或类似功能,但不能纯粹从面向对象的角度来理解(我实际上并不真正了解此人的意思)。 这有什么道理吗?如果是这样,为什么?

4
为什么对OOP的基本概念没有一致的定义?
我对编程非常陌生,并且从不同来源阅读\听到不同的约定有些困惑: 面向对象的编程有4个或5个概念吗? 作为新手,我了解以下5个概念: 抽象化 遗产 封装形式 多态性 模块化 那么,为什么找不到更“严格”的定义,这些概念似乎有几种排列方式呢?

4
并行层次结构-部分相同,部分不同
那里有很多类似的问题 1,2,3,4,但是在这个问题上似乎并非如此,解决方案也不是最优的。 假设多态性,泛型和混合可用,这是一个普遍的OOP问题。实际使用的语言是OOP Javascript(Typescript),但是在Java或C ++中,这是同样的问题。 我有并行的类层次结构,有时具有相同的行为(接口和实现),但有时每个都有其自己的“受保护”行为。像这样说明: 这仅是为了说明目的 ; 这不是实际的类图。阅读: Canvas(左)和SVG(右)层次结构共享公共层次结构(中心)中的任何内容。分享是指接口和实现。 仅左列或右列中的任何内容均表示特定于该层次结构的行为(方法和成员)。例如: 左和右层次结构都使用完全相同的验证机制,Viewee.validate()在通用层次结构上显示为单个方法()。 仅画布层次结构具有方法paint()。此方法在所有子项上调用paint方法。 SVG层次结构需要覆盖的addChild()方法Composite,但是canvas层次结构并非如此。 不能从两个侧面层次结构中混合构造。工厂确保做到这一点。 解决方案I-逗弄继承 Fowler的“逗趣分开继承”在这里似乎不起作用,因为两个相似之处之间存在一些差异。 解决方案II-Mixins 这是我目前唯一能想到的。这两个层次结构是分别开发的,但是在每个级别上,这些类都混合在公共类中,而这并不属于类层次结构。省略structural叉子,将如下所示: 请注意,每列将位于其自己的名称空间中,因此类名不会冲突。 问题 谁能看到这种方法的缺点?谁能想到更好的解决方案? 附录 这是一些示例代码,该如何使用。命名空间svg可以替换为canvas: var iView = document.getElementById( 'view' ), iKandinsky = new svg.Kandinsky(), iEpigone = new svg.Epigone(), iTonyBlair = new svg.TonyBlair( iView, iKandinsky ), iLayer = new svg.Layer(), iZoomer …

7
OOP如何演变为包含属性的概念
我来自C ++背景,在目前的工作中全力以赴使用C#,并且我刚刚读了很多问答,内容涉及公共领域和属性之间的区别以及此变化和体现的所有来回变化。基本问题(例如此SO帖子和所有相关的链接问题)。所有这些问题都是根据实际存在的差异解决的,这些差异应理所当然地认为存在财产制度,但是我认为最好从所有语言的设计者首先决定支持财产的角度来解决这个问题。地方正在思考(在此处查看 Wikipedia文章中的列表))。OOP是如何从C ++ / Java扩展到Wikipedia文章有趣地标识为方法和成员数据之间的中间地带的: “也就是说,属性位于类的成员代码(方法)和成员数据(实例变量)之间,并且属性提供比公共字段更高的封装级别。” MSDN进一步增加了背景: “尽管从技术上讲,属性在本质上与方法非常相似,但是它们的使用场景却大不相同。应将它们视为智能字段。它们具有字段的调用语法和方法的灵活性。” 我想知道这种中间封装水平对于一般的编程证明是有用的。我假设在表达OOP范式的编程语言的第一个化身中没有这个概念。

3
依赖倒置原则与“编程到接口而不是实现”
我试图了解依赖倒置原则与“程序到接口,而不是实现”原则的区别。 我了解“对接口编程,而不是实现”的含义。我也了解它如何允许更灵活和可维护的设计。 但是我不理解依赖关系反转原理与“程序到接口,而不是实现”原理有何不同。 我在网上的几个地方都读到了DIP,但这并没有消除我的困惑。我仍然看不到这两个原则之间的区别。谢谢你的帮助。

1
在大型对象层次结构中使用访问者模式
语境 我一直在使用对象层次结构(一个表达式树)使用“伪”访问者模式(伪,因为它不使用双调度): public interface MyInterface { void Accept(SomeClass operationClass); } public class MyImpl : MyInterface { public void Accept(SomeClass operationClass) { operationClass.DoSomething(); operationClass.DoSomethingElse(); // ... and so on ... } } 由于MyInterface的实现数量很多(约50个或更多),而且我不需要添加额外的操作,因此该设计非常舒适。 每个实现都是唯一的(它是一个不同的表达式或运算符),而某些实现是组合的(即,将包含其他运算符/叶节点的运算符节点)。 遍历当前是通过在树的根节点上调用Accept操作来执行的,后者依次在其每个子节点上调用Accept,依次类推...依次类推... 但是现在是时候需要添加一个新操作了,例如漂亮的打印: public class MyImpl : MyInterface { // Property does not come from MyInterface public string …

3
主方法是否应该仅由对象创建和方法调用组成?
我的一个朋友告诉我,最佳实践是main应命名Main包含main方法的类,而只包含方法。此外main方法应该只解析输入,创建其他对象和调用其他方法。本Main类和main方法,不应该做任何事情。基本上他在说包含main方法的类应该是这样的: public class Main { public static void main(String[] args) { //parse inputs //create other objects //call methods } } 这是最佳做法吗?

3
OO C公共和私有功能的典型命名约定是什么?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 简短问题 有一种典型的方式来命名OO C项目的“公共”和“私人”成员吗? 背景 我完全理解公共和私营成员没有真正在C语言中存在。但是,像大多数C程序员一样,我仍然将成员视为公共或私有成员,以维护OO设计。除了典型的面向对象的方法,我发现我的自我下面,让我更容易分辨哪些方法的模式(见下面的例子),意味着对外界VS私有成员可能有更少的检查/更有效等...是否存在针对此类问题的标准或最佳实践,或者下面的示例是解决此问题的好方法? 标题示例 #ifndef _MODULE_X_H_ #define _MODULE_X_H_ bool MOD_X_get_variable_x(void); void MOD_X_set_variable_x(bool); #endif /* _MODULE_X_H_ */ 范例来源 // Module Identifier: MOD_X #include "module_x.h" // Private prototypes static void mod_x_do_something_cool(void); static void mod_x_do_something_else_cool(void); // Private Variables static bool var_x; // Public Functions - Note the upper …

3
您如何在OOP中进行班级设计?
当我尝试设计OO解决方案时,通常使用CRC建模,其中列出了类名(名词),它们的作用(动词)以及它们与其他类的协作方式。 关于此名词-动词方法,此博客有以下要说的话 ...This approach, which I will call “noun and verb,” is so limited I’ll dare to call it brain damaged.... 我的问题是,使用OO方法是否存在更好的建模技术?

5
您是否利用了封闭式原则的好处?
开闭原理(OCP)指出对象应打开以进行扩展,但应关闭以进行修改。我相信我理解它,并将其与SRP结合使用来创建仅做一件事的类。而且,我尝试创建许多小的方法,使所有行为控件都可以提取到可以在某些子类中扩展或重写的方法中。因此,我最终得到了具有许多扩展点的类,包括:依赖项注入和组合,事件,委托等。 考虑以下简单的可扩展类: class PaycheckCalculator { // ... protected decimal GetOvertimeFactor() { return 2.0M; } } 现在说,例如,OvertimeFactor更改为1.5。由于上述类是为扩展而设计的,因此我可以轻松地子类化并返回一个不同的OvertimeFactor。 但是 ...尽管该类是为扩展而设计的,并且坚持使用OCP,但我将修改单个方法,而不是子类化和覆盖该方法,然后在IoC容器中重新连接对象。 结果,我违反了OCP尝试完成的部分工作。感觉就像是在偷懒,因为上面的内容要容易一些。我是否误解了OCP?我真的应该做些不同的事情吗?您是否以其他方式利用OCP的优势? 更新:根据答案,由于许多不同的原因,这个人为的例子似乎是一个糟糕的例子。该示例的主要目的是证明该类是通过提供以下方法来扩展的:该方法在被重写时将更改公共方法的行为,而无需更改内部或私有代码。不过,我绝对误会了OCP。

4
非OOP范例是否支持封装等概念?
面向对象编程中的重要概念之一是封装。但是,最近,软件世界似乎倾向于使用其他范例,例如函数式编程。 这让我思考,封装和其他OOP原则如何?他们错了吗? OOP应用错误吗?例如,艾伦·凯(Alan Kay)在OOPSLA'97主题演讲中说:“我发明了术语面向对象,我可以告诉你我没有C ++。” 乔·阿姆斯特朗(Joe Armstrong)-“对象将功能和数据结构以不可分割的单位绑定在一起。我认为这是一个根本性的错误,因为功能和数据结构属于完全不同的世界。”

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.