Questions tagged «object-oriented»

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

5
接口(OOP)的语义约定是否比功能签名(FP)更具信息意义?
有人说,如果您将SOLID原理付诸实践,那么您最终会从事函数式编程。我同意本文的观点,但是我认为从接口/对象到函数/闭包的转换会丢失一些语义,并且我想知道函数式编程如何减轻这种损失。 从文章: 此外,如果您严格地应用接口隔离原理(ISP),您将了解您应该比角色头接口更喜欢角色接口。 如果您继续将设计推向越来越小的界面,那么最终您将获得最终的角色界面:使用单一方法的界面。这在我身上经常发生。这是一个例子: public interface IMessageQuery { string Read(int id); } 如果我依赖IMessageQuery,则隐式合同的一部分是调用Read(id)将搜索并返回具有给定ID的消息。 将此与对其等效功能签名的依赖进行比较 int -> string。没有任何其他提示,此功能可能很简单ToString()。如果您使用A实施IMessageQuery.Read(int id),ToString()我可能会指责您故意颠覆性! 那么,函数式程序员可以做什么来保留命名接口的语义?例如,创建具有单个成员的记录类型是常规做法吗? type MessageQuery = { Read: int -> string }

2
为什么继承,封装和多态性不是OOP的支柱?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引文回答。 5年前关闭。 有一天,我去了一个Stack Overflow聊天室,看到一句话,它表明继承,封装和多态性是OOP的支柱(从某种意义上说,它们是基础,是唯一的构造)。 另外,还有一个类似的问题,在大学考试和工作面试中经常有人问我,正确的答案始终是问题标题中的声明(“是的,继承,封装和多态性是OOP的基础。 )。 但是在Stack Overflow聊天中,我被严重嘲笑,参与者强烈不同意这种说法。那么,这句话有什么问题呢? 在后苏联和美国的大学里,程序员似乎接受过不同的培训吗? 美国/英国程序员是否不将继承,封装和多态性视为OOP的支柱?

8
用于函数式编程的心理模型或真实世界隐喻
是否有人对函数式编程有一个很好的思维模型或隐喻,可以引用现实世界中的某些东西? 直观的面向对象编程对我来说很有意义。有些东西具有属性,有时它们也可以对它们的属性(方法)进行填充或执行计算。(例如:汽车,造型,猫)。 我对函数式编程毫无恶意,并且我对辩论两者的优点不感兴趣。与面向对象编程一样,我只需要一个隐喻或思维模型即可使用。 在功能范式中进行编程有哪些好的心理模型或现实世界隐喻?关于由功能处理功能组成的功能的某些说明,使一个功能没有固定的位置来站立和思考。

3
对OOP中“抽象”的定义感到困惑
我试图理解OOP中“抽象”的定义。 我遇到了一些主要定义。它们都有效吗?其中之一错了吗?我很困惑。(我用自己的话重新写了定义)。 定义1: 抽象是从现实世界中获取一些对象并将其转换为编程术语的概念。如创建Human类,并给予它int health,int age,String name等性质,和eat()等方法。 定义2: 更一般的定义。抽象是一个概念,它发生在软件系统中涉及“使事情变得更加通用/简单/抽象”的任何地方。一些例子: 继承层次结构,其中较高的类更简单或更通用,并定义更通用和抽象的实现。而层次结构中的下层类则更为具体,并定义了更详细的实现。 使用封装从其他类中隐藏类的实现细节,从而使该类对外部软件世界更加“抽象”(更简单)。 定义3 另一个通用定义:抽象是将重点从事物的细节和具体实现转移到事物的类型(即类),可用的操作(即方法)等概念,从而使编程更简单,更通用,更抽象。(这可以在软件系统中的任何位置和任何上下文中发生)。例如,它在封装时发生,因为封装意味着隐藏实现的细节,仅显示事物的类型及其更笼统和抽象的定义。Anotehr示例将使用ListJava中的对象。该对象实际上使用a ArrayList或a 的实现细节LinkedList,但是此信息使用更通用的名称来抽象List。 这些定义是否正确?(我指的是最常规和公认的定义)。

9
使用构造方法还是setter方法?
我正在编写具有Action类的UI代码,例如: public class MyAction extends Action { public MyAction() { setText("My Action Text"); setToolTip("My Action Tool tip"); setImage("Some Image"); } } 创建此Action类时,几乎可以假定Action该类是不可自定义的(从某种意义上说,它的文本,工具提示或图像在代码中的任何位置都不会更改)。现在,我们需要在代码中的某些位置更改动作文本。因此,我建议我的同事从构造函数中删除硬编码的操作文本,并接受它作为参数,以使每个人都被迫传递操作文本。类似于下面的代码- public class MyAction extends Action { public MyAction(String actionText) { setText(actionText); setTooltip("My Action tool tip"); setImage("My Image"); } } 但他认为,由于setText()方法属于基类,因此可以在创建操作实例的任何位置灵活地使用该方法传递操作文本。这样,无需更改现有的MyAction类。所以他的代码看起来像这样。 MyAction action = new MyAction(); //this creates action …

6
我们可以说对象具有属性,状态和行为吗?
我正在阅读Oracle对OOP概念的介绍,并且遇到了以下描述: 实际对象具有两个特征:它们都具有状态和行为。狗具有状态(名称,颜色,品种,饥饿)和行为(吠叫,抓捕,摇尾巴)。软件对象在概念上与现实世界中的对象相似:它们也由状态和相关行为组成。 我的问题是,当描述状态时,它的混合属性也存在。例如,狗的名字和颜色是它的属性,而饿或渴则是它的状态。 因此,我认为将对象的特征分为三个部分更为准确:属性,状态和行为。 当然,将其翻译成编程语言时,我可以看到三重分区变成了两重分区,因为属性和状态都将存储在字段/变量中,而行为将存储在方法/函数中。 但是从概念上讲,将三件事分开是更有意义的。 这是另一个示例:考虑一盏灯。在我看来,说灯泡的大小以及它是否已打开都是状态。灯的大小是属性,而不是状态,而打开或关闭是状态。 还是我错过了什么?

7
您如何跟踪大型项目?
当处理一个包含许多不同文件的项目时,我似乎总是不了解零件之间如何交互。我从来没有真正遇到过孤立地了解较小的组件的问题,但是随着项目的复杂性增加,我发现自己无法从心智上理解正在发生的事情。随着方法和源文件数量的增加,我尤其在OOP项目中注意到这一点。 我的背景:我是一个自学成才的网络程序员。我主要使用python处理快速而肮脏的脚本,但是我也做了一些基本的django项目。我喜欢flask之类的Web框架,因为在单文件布局的简单性中,我可以轻松(大部分)跟踪正在发生的事情。 现在,我处于需要与其他人开发的大型Zend Framework PHP项目进行交互的情况,而试图理解扩展到许多文件的代码让我不知所措。 您发现哪些技术和过程对理解他人开发的大型代码库有用?您是否找到任何特定的图表来帮助您掌握大图?

14
我如何解释继承的用处?[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 6年前关闭。 当试图解释OOP中的继承概念时,常见的例子通常是哺乳动物。恕我直言,这确实是一个不好的例子,因为它将导致新手以错误的方式使用此概念。而且,他们在日常设计工作中将面临的不是常见的设计。 那么,使用继承解决的一个好,简单而具体的问题是什么?

4
我怎么知道我的数据本质上是关系型或面向对象的?
只需阅读这些行- 如果您的数据本质上是对象,则使用对象存储(“ NoSQL”)。它们将比关系数据库快得多。 如果您的数据本质上是关系型的,那么关系数据库的开销是值得的。 从- http://seldo.com/weblog/2011/06/15/orm_is_an_antipattern 那么,我怎么知道我的数据是关系型的还是面向对象的呢?

6
从过程代码转换为面向对象的代码
我一直在阅读“有效地使用遗留代码和清除代码”,其目的是学习有关如何开始清除大型ASP.NET Webforms应用程序的现有代码库的策略。 该系统自2005年起问世,此后进行了许多增强。最初,代码的结构如下(并且仍然在很大程度上以这种方式进行结构化): ASP.NET(aspx / ascx) 代码隐藏(C#) 业务逻辑层(c#) 数据访问层(c#) 数据库(Oracle) 主要问题是该代码伪装成面向对象的程序。它实际上违反了两本书中描述的所有准则。 这是业务逻辑层中典型类的示例: public class AddressBO { public TransferObject GetAddress(string addressID) { if (StringUtils.IsNull(addressID)) { throw new ValidationException("Address ID must be entered"); } AddressDAO addressDAO = new AddressDAO(); return addressDAO.GetAddress(addressID); } public TransferObject Insert(TransferObject addressDetails) { if (StringUtils.IsNull(addressDetails.GetString("EVENT_ID")) || StringUtils.IsNull(addressDetails.GetString("LOCALITY")) || …

4
使用数据库时保持面向对象和可测试性
使用数据库但保持单元可测试性的一些OOP策略是什么?假设我有一个User类,并且我的生产环境适用于MySQL。我看到了两种可能的方法,如下所示使用PHP: 通过在与接口$ DATA_SOURCE load()和save(),抽象数据的后端源。测试时,请传递其他数据存储。 $ user =新用户($ mysql_data_source); $ user-> load('bob'); $ user-> setNickname('Robby'); $ user-> save(); 使用访问数据库并将结果行传递给用户的构造函数的工厂。测试时,手动生成$ row参数,或在UserFactory :: $ data_source中模拟对象。(如何保存对记录的更改?) class UserFactory { static $data_source; public static function fetch( $username ) { $row = self::$data_source->get( [params] ); $user = new User( $row ); return $user; } } 我旁边有设计模式和简洁代码,但我一直在努力寻找适用的概念。

2
DDD:一个根聚合保留对另一个根聚合的引用是否正确?
遵循域驱动设计(DDD)时,对于根聚合保留对恰好是单独聚合中根实体的内部实体的引用是否正确? 我认为这是不正确的,主要是因为这本关于蓝皮书的规则: 除了根ENTITY,AGGREGATE边界之外的任何内容都不能保存对内部任何内容的引用。根ENTITY可以将对内部ENTITIES的引用传递给其他对象,但是这些对象只能临时使用它们,并且它们可能不会保留引用。根可以将VALUE OBJECT的副本交给另一个对象,它发生什么都没有关系,因为它只是一个VALUE,不再与AGGREGATE有任何关联。 如果一个根聚合包含对另一个根聚合的引用,则违反了前者的边界,并且聚合的整个概念都已损坏,因此我认为,如果一个根聚合看起来像需要保留对另一个根聚合的引用,那么我需要创建一个不同的实体,该实体可能会与另一个根实体共享一些相同的成员,但不会具有全局标识,因为本书中的另一条规则指出: 根实体具有全球性。边界内的实体具有本地身份,仅在AGGREGATE内部具有唯一性。 我相信这将是正确的方法,但是由于它具有重复性和冗余性(当从纯DOP脱离DDD的上下文时),我要求提供一些反馈。

6
允许吸气剂的确切问题是什么?
我不是在寻找有关语义的意见,而只是在明智地使用吸气剂是一个实际障碍的情况下。也许这使我陷入了对它们的永无止境的螺旋式旋转,也许替代方法是更清洁并自动处理吸气剂,等等。 我听过所有论据,听过它们很不好,因为它们迫使您将对象视为数据源,它们违反了对象的“纯状态”,即“不要给出太多,但要做好准备”接受很多”。 但是,绝对没有明智的理由说明a为何getData是一件坏事,实际上,一些人认为这与语义有关,吸气剂本身就很好,但只是不要给它们起名字getX,对我来说,这至少很有趣。 如果我明智地使用吸气剂,并且没有明显的数据(如果将其推出,则对象的完整性不会破坏),那么没有意见的一件事是什么? 当然,允许使用getter来加密用于加密某些内容的字符串是很愚蠢的,但是我说的是系统需要运行的数据。也许您的数据是Provider从对象中拉出的,但是,仍然,对象仍然需要允许该对象Provider执行a $provider[$object]->getData,因此无法解决。 我为什么要问:对我来说,合理使用吸气剂并在被视为“安全”数据上使用吸气剂时,我有99%的吸气剂用于识别对象,例如,我通过代码询问Object, what is your name? Object, what is your identifier?,任何使用对象的人都应该了解有关对象的这些知识,因为关于编程的几乎所有内容都是身份,还有谁比对象本身更了解对象是什么?因此,除非您是纯粹主义者,否则我看不到任何实际问题。 我已经看过所有关于“为什么吸气剂/塞特器”很糟糕的StackOverflow问题,尽管我同意在99%的情况下塞特斯确实很不好,但是不必因为吸韵而对吸气剂一视同仁。 设置器会损害对象的身份,并且很难调试谁在更改数据,但是获取器却无能为力。

4
API和函数式编程
从我(有限地)接触函数式编程语言(例如Clojure)开始,似乎数据封装的作用不那么重要。通常,各种本机类型(例如地图或集合)是代表对象的首选数据。此外,该数据通常是不可变的。 例如,这是Clojure的成名人物里奇·希基(Rich Hickey)在接受此事采访时最著名的名言之一: Fogus:遵循了这个想法,Clojure并未对其类型进行数据隐藏封装,这一事实使某些人感到惊讶。您为什么决定放弃数据隐藏? Hickey:让我们清楚一点,Clojure强烈强调对抽象的编程。但是在某个时候,某人将需要访问数据。而且,如果您有“私有”的概念,则需要相应的特权和信任的概念。这就增加了很多复杂性和很小的价值,在系统中产生了僵化,并常常迫使事物生活在不应有的地方。这是将简单信息放入类时发生的其他损失的补充。在某种程度上,数据是不可变的,提供访问的危害很小,除了有人可能会依赖可能发生变化的事物之外。好吧,好吧,人们在现实生活中一直如此,当事情发生变化时,他们就会适应。如果他们是理性的,他们知道,当他们基于可能会改变的事物做出决定时,将来可能需要适应。因此,这是一项风险管理决策,我认为程序员应该可以自由做出。如果人们不希望对抽象编程,也不愿意与实现细节相结合,那么他们永远都不会成为优秀的程序员。 来自面向对象的世界,这似乎使我多年来学到的一些基本原则变得复杂。其中包括信息隐藏,德米特定律和统一访问原则等。封装的共同点是使我们能够为其他人定义API,让他们知道应该和不应该接触的内容。从本质上讲,创建一个合同,允许某些代码的维护者自由地进行更改和重构,而不必担心它将如何在用户代码中引入错误(开放/封闭原则)。它还为其他程序员提供了一个干净,精心设计的界面,以使他们知道可以使用哪些工具来获取或建立该数据。 当允许直接访问数据时,该API合同被破坏,所有这些封装好处似乎都消失了。同样,严格不变的数据似乎在遍历特定于域的结构(对象,结构,记录)时,在表示状态和可以对该状态执行的操作的意义上要有用得多。 当代码库的大小变得巨大而需要定义API且许多开发人员参与处理系统的特定部分时,功能代码库如何解决似乎出现的这些问题?是否存在这种情况的示例,以说明在这些类型的代码库中如何处理此情况?

4
OOP应用程序中的参数管理
我正在用C ++编写一个中等大小的OOP应用程序,作为实践OOP原理的一种方法。 我的项目中有几个类,其中一些需要访问运行时配置参数。这些参数是在应用程序启动期间从多个来源读取的。有些是从用户home-dir中的配置文件读取的,有些是命令行参数(argv)。 所以我创建了一个类ConfigBlock。此类读取所有参数源并将其存储在适当的数据结构中。示例是路径和文件名,用户可以在配置文件或--verbose CLI标志中更改它们。然后,可以调用ConfigBlock.GetVerboseLevel()以读取此特定参数。 我的问题:在一个类中收集所有此类运行时配置数据是一种好习惯吗? 然后,我的班级需要访问所有这些参数。我可以想到几种方法来实现这一目标,但是我不确定该采取哪种方法。类的构造函数可以是对我的ConfigBlock的给定引用,例如 public: MyGreatClass(ConfigBlock &config); 或者,它们仅包含标头“ CodingBlock.h”,其中包含我的CodingBlock的定义: extern CodingBlock MyCodingBlock; 然后,仅类.cpp文件需要包含和使用ConfigBlock内容。 .h文件不会将此接口引入类的用户。但是,ConfigBlock的接口仍然存在,但是从.h文件中隐藏了该接口。 这样隐藏起来好吗? 我希望接口尽可能小,但最后,我想每个需要配置参数的类都必须与我的ConfigBlock连接。但是,这种连接应该是什么样的?

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.