33

我无法理解类与它们的方法之间的关系。方法是对象所做的事情,还是对它所做的事情?或者这完全是一个不同的概念?

具体来说,在图书馆的软件系统中,该borrow()方法应该属于代表图书馆读者的类,还是代表读者借阅的项目的类?我的直觉是它应该读起来像patron.borrow(copy),像英语句子结构,subject.verb(object); 但是我的老师说那是错误的,我不明白他为什么会borrow()属于这个Copy班级(而且他并没有真正解释得很好)。我不是在寻找理由,但是有人可以解释正确的关系吗?

编辑:这个问题被关闭为“离题”。我不明白。软件设计问题不适合这个网站吗?

4

11 回答 11

12

主观的:)但老实说,我会使用信息专家模式并说类似

library.lend(item, patron)

图书馆包含有关其拥有的项目的信息(可能在其目录中)。
图书馆将项目借给读者(它知道是因为它注册了它们)

不确定您的讲师如何看待这一点,但这是对您的场景有意义的“抽象”级别(模仿现实世界实体的软件对象)。

于 2012-04-26T05:56:07.290 回答
10

您不应将 OOP 的概念与 Java 或 C++ 之类的特定化身相混淆。

这个限制“方法是对象的属性”不是 OOP 思想的一部分,而只是某些实现的一部分,正如您发现的那样,它不能很好地扩展。

“整数”对象有多少种方法?什么是更合乎逻辑的......myfile.write(myint)myint.write(myfile)?对此确实没有很好的通用答案。将方法作为单个对象的一部分的想法是一种特殊情况,有时将问题与此解决方案相适应所需的弯曲可能会变得很明显,甚至接近于展示。只有当一个方法除了正在处理的对象之外没有参数时,答案才是完全可以接受的:只有在涉及单一类型时,单一分派才是一个完美的答案。

在其他语言中,对象和方法之间是分开的,例如,您有文件对象、整数对象和一个write(myfile, myint)描述需要操作时要做什么的方法……而这个方法既不是文件的一部分,也不是文件的一部分。的整数。

于 2012-04-26T05:59:59.890 回答
7

先说一些通用词。

软件构建不是应该受英语语言规则或“美”或其他什么约束的东西,它是工程学科。想想你的设计是否解决了问题,是否可维护,是否可测试,是否可以并行开发等等。如果您想要更正式的内容,请查看 DL Parnas 的“关于将系统分解为模块时使用的标准”。

至于您的图书馆示例。想象一下你在图书馆外面有一个副本,那么它应该有borrow方法吗?借款如何登记?您对负责数据存储的 Copy 或 Patron 类是否满意?borrow放入图书馆类看起来更合适。职责将被明确划分,您不需要了解太多关于借用来实现 Copy 和 Patron 的知识,并且您不需要太多关于它们的详细信息来实现 Library。

于 2012-04-26T07:35:10.243 回答
3

正如@Ryan Fernandes 所说,借/借操作不能与赞助人或书籍一起进行。它必须与某个知道图书馆所有书籍和顾客状态的班级在一起。例如,是否有针对一本书的未决保留?有多少份可用?这位赞助人是否支付了所有费用?他有资格读这本书吗?所以通常这应该在 Library 或 LibraryService 类中。

于 2012-04-26T06:03:02.827 回答
3

从类公开的公共方法是可以在实体上执行的任务。这样,该类将仅封装其行为。

例如:如果我说

计算机.TurnOn()

该方法仅适用于计算机系统。

相反,如果我说,

SomeOne.TurnonComputer()

某人现在将有责任打开计算机(设置计算机的相关属性),这意味着我们没有满足封装和分散类属性的概念。

于 2012-04-26T06:17:17.587 回答
3

OOP 的重点是创建多态函数,这些函数在每个实现中处理一组定义的数据,这些数据服从特定的不变量。

因此,改变对象的方法应该在该对象的类中定义。纯函数式代码存在于何处并不重要,但它可能应该存在于其输入的类型(如果它采用单个输入)或其输出上。

在您的示例中,如果borrow更改 中的数据copy,则它应该存在于那里。但是,如果您通过将图书保存在特定馆藏(在赞助人中,或在图书馆的馆藏中)来模拟图书的外借状态,那么borrow设置持有者类会更有意义。但是,后一种设计存在副本可能位于多个集合中的风险,因此您还需要在副本上放置一些信息(和相应的方法)。

于 2012-04-26T07:44:18.563 回答
1

不太确定确切的理由,但你可以这样想,如果多个病人去看医生,只有医生知道什么时候打电话给下一个病人,所以下一个方法将是医生责任的一部分,尽管很容易认为下一个应该是患者的责任,因为他必须下一个,但是当图书馆的书籍要发行时,它应该是书籍类型而不是赞助人的责任,因为书籍(资源)知道什么时候将是免费的。

于 2012-04-26T05:53:25.183 回答
1

方法是对象所做的事情,还是对它所做的事情?或者这完全是一个不同的概念?

让我先澄清一下类和对象。Class通常用于表示特定类别。像

  1. 不是法拉利或保时捷的汽车
  2. 水果 不是香蕉或苹果

所以,开的是法拉利,吃的是香蕉。不是他们的班级

它始终是具有属性和行为的对象。

甚至专门去你的案子。

borrow()方法是由 aperson的对象在book其记录由library system自身的另一个对象保存的对象上完成的动作/行为。

对我来说,以 OO 方式表示这一点的好方法就像

libray.borrow(new book('book title'), new person('starx'));

只是为了好玩,你怎么看这个

person starx = new person('starx');
book title1 = new book('title1');
library libraryname = new library('libraryname');
libraryname.addBook(title1);

if(starx.request(title1, libraryname)) {
     starx.take(library.lend(title1, starx));
}
于 2012-04-26T06:12:16.370 回答
0

我想它可以去任何一种方式。没有硬性规定。这个想法是逻辑上有意义的组功能。对我来说,Patron#borrow(BookCopy)BookCopy#borrow(Patron). 或者你可能有一个类LibManager.borrow(BookCopy, Patron)

于 2012-04-26T06:03:01.450 回答
0

你的导师是对的。好吧,事实上,他错了。我不知道。

我的观点是,对于这样的问题,通常没有一种或另一种固定的通用答案。这在很大程度上取决于在您的特定情况下最有效的方法。选择最容易编码的东西——这将是最容易维护的。而且,通过“最容易编码”,我建议还考虑类的预期用户(不仅仅是你的Library,CopyPerson类)。

于 2012-04-26T06:04:50.110 回答
0

我今天正是在考虑这个问题。我得出了这个结论:

在适当的上下文中更有意义。

于 2012-04-26T08:04:46.963 回答