Questions tagged «object-oriented»

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

4
返回只读对象的最佳实践
我对C#中的OOP有“最佳实践”问题(但它适用于所有语言)。 考虑使库类具有要通过属性访问器公开的对象,但是我们不希望公众(使用此库类的人)对其进行更改。 class A { // Note: List is just example, I am interested in objects in general. private List<string> _items = new List<string>() { "hello" } public List<string> Items { get { // Option A (not read-only), can be modified from outside: return _items; // Option B (sort-of read-only): …

3
模拟具体课程-不推荐
我刚刚读了《成长面向对象的软件》一书的摘录,其中解释了为什么不建议模拟具体类的一些原因。 以下是MusicCentre类的单元测试的一些示例代码: public class MusicCentreTest { @Test public void startsCdPlayerAtTimeRequested() { final MutableTime scheduledTime = new MutableTime(); CdPlayer player = new CdPlayer() { @Override public void scheduleToStartAt(Time startTime) { scheduledTime.set(startTime); } } MusicCentre centre = new MusicCentre(player); centre.startMediaAt(LATER); assertEquals(LATER, scheduledTime.get()); } } 和他的第一个解释: 这种方法的问题在于,它使对象之间的关系保持隐式。我希望我们现在已经弄清楚了,使用模拟对象进行测试驱动开发的目的是发现对象之间的关系。如果我是子类,则域代码中没有任何东西可以使这种关系可见,而只是对象上的方法。这使得很难看到支持这种关系的服务是否在其他地方有用,下次我与该类一起工作时,我将不得不再次进行分析。 他说的时候我无法确切知道他的意思: 这使得很难看到支持这种关系的服务是否在其他地方有用,下次我与该类一起工作时,我将不得不再次进行分析。 我了解该服务对应于MusicCentre称为的方法startMediaAt。 他在“其他地方”是什么意思? 完整的摘录在这里:http : …

12
如何向只用Fortran 77编码的人解释面向对象的编程?
我母亲在Fortran上完成了大学论文,现在(十多年后)需要学习c ++进行流体模拟。她能够理解所有过程编程,但是无论我多么努力向她解释对象,它都不会停留。(我在Java上做了很多工作,所以我知道对象是如何工作的)我想我可能会以太高层次的方式来解释它,所以对于那些从不与它们一起工作并且成长的人来说,这真的没有任何意义。在纯粹的程序化编程时代。 有什么简单的方法可以向她解释,以帮助她理解?

5
里斯科夫替代原则与内省或鸭类打字不相容吗?
我是否正确理解在对象可以自我检查的语言(如鸭式语言中常见的语言)中不能遵守《里斯科夫替代原理》? 例如,在Ruby中,如果一个类B从一个类继承A,然后为每个对象x的A,x.class是要回报A的,但如果x是一个对象B,x.class是不会返回A。 这是LSP的声明: 令q(x)是关于类型T的对象x的可证明性质。那么,对于类型S的对象y,q(y)应该是可证明的,其中S是T的子类型。 以Ruby为例, class T; end class S < T; end 如属性q(x) =所示,以这种形式违反LSPx.class.name == 'T' 加成。如果答案是“是”(与内省不兼容的LSP),那么我的另一个问题是:是否存在某种修改后的“弱”形式的LSP,它可能适用于动态语言,可能在某些附加条件下并且仅具有特殊类型的性质。 更新。作为参考,这是我在网络上发现的另一种LSP公式: 使用指针或对基类的引用的函数必须能够使用派生类的对象,而无需了解它。 还有一个: 如果S是声明的T的子类型,则将S类型的对象视为T类型的对象,如果将它们视为T类型的对象,则它们的行为也应与预期的T类型的对象相同。 最后一个注释为: 请注意,LSP全部关于对象的预期行为。只有清楚知道对象的预期行为后,才能遵循LSP。 这似乎比最初的要弱,并且可能可以观察到,但是我希望看到它正式化,尤其要解释谁决定预期的行为是什么。 那么,LSP是否不是编程语言中的一对类的属性,而是祖先类满足的一对类以及给定的一组属性?实际上,这是否意味着要构造一个尊重LSP的子类(后代类),必须知道祖先类的所有可能用法?根据LSP,祖先类应该可以用任何后代类替换,对吗? 更新。 我已经接受了答案,但是我想添加一个来自Ruby的更具体的例子来说明这个问题。在Ruby中,每个类都是模块,从某种意义上来说,Class类是类的后代Module。然而: class C; end C.is_a?(Module) # => true C.class # => Class Class.superclass # => Module module M; end M.class # => Module …

5
为什么没有面向服务的语言?
编辑: 为了避免进一步的混乱:我不是在谈论Web服务之类的东西。我说的是内部构造应用程序,而不是计算机如何通信。它涉及编程语言,编译器以及命令式编程范例的扩展方式。 原版的: 在命令式编程领域中,我们在过去的20年(或更长的时间)中看到了两种范例:面向对象(OO)和面向服务(SO)。基于组件(CB)。 两种范例都通过引入它们自己的模块概念来扩展命令式编程范例。OO将它们称为对象(和类),并使它们将数据(字段)和过程(方法)封装在一起。相反,SO将数据(记录,bean等)与代码(组件,服务)分离。 但是,只有OO具有本机支持其范例的编程语言:Smalltalk,C ++,Java和所有其他JVM兼容,C#和所有其他.NET兼容,Python等。 SO没有这样的母语。它仅在过程语言或OO语言之上才存在:COM / DCOM(二进制,C,C ++),CORBA,EJB,Spring,Guice(所有Java),... 这些SO框架显然遭受其概念缺少本地语言支持的困扰。 他们开始使用OO类来表示服务和记录。这导致在设计中,仅具有方法的类(服务)与仅具有字段的类(记录)之间存在明显的区别。然后,通过类的继承模拟服务或记录之间的继承。从技术上讲,它并没有那么严格,但是一般来说,建议程序员使类仅扮演两个角色之一。 他们使用其他外部语言来表示缺少的部分:IDL,XML配置,Java代码中的注释,甚至像Guice中的嵌入式DSL。由于服务的组成不是服务代码本身的一部分,因此特别需要但不限于此。在OO中,对象创建其他对象,因此不需要此类工具,但是对于SO而言,是因为服务不会实例化或配置其他服务。 它们在OO(早期的EJB,CORBA)之上建立了一个内部平台效果,程序员必须在其中编写“驱动” SO所需的所有代码。类仅表示服务性质的一部分,必须编写许多类才能一起形成服务。所有这些样板都是必要的,因为没有SO编译器可以为程序员做。就像有些人在没有C ++的情况下在C for OO中所做的那样。您只需将保存对象数据作为第一个参数的记录传递给作为方法的过程。在OO语言中,此参数是隐式的,并且编译器将生成我们为虚拟功能等所需的所有代码。对于SO,显然没有此功能。 特别是较新的框架广泛使用AOP或自省功能将缺少的部分添加到OO语言中。这没有带来必要的语言表达能力,但是避免了上一点中描述的锅炉平台代码。 一些框架使用代码生成来产生样板代码。XML的配置文件或OO代码中的注释是此信息的来源。 并非我上面提到的所有现象都可以归因于SO,但我希望它清楚地表明需要使用SO语言。由于这种范例如此流行:为什么不存在一个范例?或者也许有一些学术论文,但至少该行业不使用。

9
使用哪种OO设计(是否有设计模式)?
我有两个代表“酒吧/俱乐部”(您喝酒/社交的地方)的对象。 在一种情况下,我需要栏名称,地址,距离,标语 在另一种情况下,我需要栏名称,地址,网站网址,徽标 因此,我有两个对象代表相同的事物,但具有不同的字段。 我喜欢使用不可变的对象,因此所有字段都是从构造函数设置的。 一种选择是拥有两个构造函数,而其他字段为空,即: class Bar { private final String name; private final Distance distance; private final Url url; public Bar(String name, Distance distance){ this.name = name; this.distance = distance; this.url = null; } public Bar(String name, Url url){ this.name = name; this.distance = null; this.url = url; …

5
为什么我的班级比本书中的班级等级(初学者OOP)更糟糕?
我正在阅读PHP对象,模式和实践。作者正试图在大学里模拟一堂课。目标是输出课程类型(讲座或研讨会),并且该课程的费用取决于它是每小时课程还是固定价格课程。所以输出应该是 Lesson charge 20. Charge type: hourly rate. Lesson type: seminar. Lesson charge 30. Charge type: fixed rate. Lesson type: lecture. 当输入如下时: $lessons[] = new Lesson('hourly rate', 4, 'seminar'); $lessons[] = new Lesson('fixed rate', null, 'lecture'); 我这样写: class Lesson { private $chargeType; private $duration; private $lessonType; public function __construct($chargeType, $duration, …

3
通用编程,在工业中使用的频率
目前,我在学术环境中进行编程,因此我可以使用任何我想使用的东西。我在使用Boost图形库做一些事情,并且想知道是否值得花更多的精力来更深入地了解GP。 我很好奇-通用编程(GP)在行业中使用率很高吗?我的猜测是,大多数程序员更喜欢OOP或使用不强调或不支持GP的语言,因此,除了在C ++中调用STL数据结构/函数外,我的印象是GP并不是经常使用在实践中。但是,由于目前不在行业内,因此很高兴听到从业者的来信。 (在撰写本文时,我看到通用编程甚至不是有效的标签!)

7
从设计的角度来看,记录的最佳实践是什么?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 6年前关闭。 我想将日志记录添加到当前正在处理的应用程序中。我之前添加了日志记录,这不是这里的问题。 但是从面向对象语言的设计角度来看,遵循OOP和模式的最佳记录实践是什么? 注意:我目前正在C#中执行此操作,因此显然欢迎使用C#中的示例。我也想看看Java和Ruby中的示例。 编辑:我正在使用log4net。我只是不知道插入它的最佳方法是什么。

4
如何在PHP中以面向对象的方式传递数据?
我发现即使使用MVC框架(例如CodeIgniter),我也经常采用传递嵌套数组而不是对象的方法。 这不符合我对面向对象的理解。例如,如果我要将代码移植到Java,那么我就不会梦想像这样传递数组(或Vector,或其他任何东西)。 我想知道这是否是处理数据的适当方法。为什么有这样的原因在PHP中这样传递数组,或者为什么不使用对象呢?传递数据的最佳方法是什么?

4
对设计模式和OOP实践的思考如何在动态和弱类型语言中发生变化?
这些方面已经有了一个相当有用的问题(“ 非OOP设计模式? ”),但是我对于刚开始使用动态和弱类型语言的人的过渡观点感到更加好奇。 那就是:假设我已经使用C ++,C#或Java进行编程多年,并从GoF设计模式,Fowler 企业应用程序体系结构模式,SOLID原理等方面吸取了很多智慧。 m涉猎Ruby,Python,JavaScript等,并想知道我的知识如何应用。大概在很多情况下我都可以进行直接翻译,但是几乎可以肯定的是,这并不能充分利用我的新设置。仅仅靠鸭子打字就可以改变我很多基于界面的思想。 什么保持不变?有什么变化?是否有新手应该知道的诸如SOLID之类的指导原则或动态语言新手应该知道的规范模式(也许是全新的)?

7
结构化编程与OO编程
我正在做一个演示,以显示结构化编程和面向对象编程之间的差异,并且我想以一个示例说明为什么人们需要OOP,在该示例中,应用OOP概念将使编码变得更加容易,从而使听众真正感到他们需要OOP。 有任何想法吗 ??

4
嵌套类:有用的工具还是违反封装的?
因此,对于是否应使用这些功能,我仍然持保留态度。 我感到它极度违反了封装,但是我发现我可以在某种程度上实现封装,同时在代码中获得更大的灵活性。 以前的Java / Swing项目在某种程度上使用了嵌套类,但是现在我进入了C#中的其他项目,因此避免使用它们。 您如何看待嵌套类?


2
DDD中的例外
我正在学习DDD,并且正在考虑在某些情况下引发异常。我知道对象不能进入错误状态,因此这里的异常很好,但是在许多示例中,例如,如果我们尝试使用数据库中存在的电子邮件添加新用户,也会抛出异常。 public function doIt(UserData $userData) { $user = $this->userRepository->byEmail($userData->email()); if ($user) { throw new UserAlreadyExistsException(); } $this->userRepository->add( new User( $userData->email(), $userData->password() ) ); } 因此,如果存在使用此电子邮件的用户,那么我们可以在应用程序服务中捕获异常,但我们不应该使用try-catch块来控制应用程序的操作。 最好的方法是什么?

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.