具体来说,在图书馆软件系统中,
borrow()
方法应该属于代表图书馆用户的类,还是代表借阅物品的类?我的直觉是应该像英语句子结构一样写成 patron.borrow(copy)
的形式,即主语动词宾语;但是我的指导教师说这是错误的,我不明白为什么他认为 borrow()
应该属于 Copy
类(而且他没有很好地解���清楚)。我不需要证明正确性,只是想请有人解释一下正确的关系是什么。编辑:这个问题被关闭为“离题”。我不明白,难道软件设计问题不适合在这个网站上讨论吗?
borrow()
方法应该属于代表图书馆用户的类,还是代表借阅物品的类?我的直觉是应该像英语句子结构一样写成 patron.borrow(copy)
的形式,即主语动词宾语;但是我的指导教师说这是错误的,我不明白为什么他认为 borrow()
应该属于 Copy
类(而且他没有很好地解���清楚)。我不需要证明正确性,只是想请有人解释一下正确的关系是什么。有点主观,但老实说,我会选择信息专家模式,然后做出这样的建议:
library.lend(item, patron)
该库包含其所拥有物品的信息(可能在其目录中)。 该图书馆将物品借给读者(它知道读者是谁,因为它会登记他们)。
不确定您的教师如何看待此问题,但这是适合您场景的“抽象”级别(软件对象模仿现实世界实体)。
不要把OOP的概念与Java或C++等特定实现混淆。
"方法是对象的属性"这个限制并不是OOP的一部分,而只是某些实现的特点。正如你所发现的,它并不适用于大规模应用。
"整数"对象应该有多少方法?哪种更合理:myfile.write(myint)
还是myint.write(myfile)
?事实上,并没有一个好的普遍答案。将“方法是单个对象的一部分”作为一种特例并不总是适用的,有时为了使问题适应这个解决方案需要做出明显的弯曲,甚至可能接近停滞状态。当一个方法除了正在处理的对象之外没有其他参数时,单派发才是完美的答案:只有涉及单个类型时,单派发才是真正可接受的答案。
在其他语言中,对象和方法是分开的,例如,您可以有文件对象、整数对象和write(myfile, myint)
方法描述需要执行的操作…而此方法既不属于文件也不属于整数。
首先,一些常见的词语。
软件构建不应该由英语语言规则或“美感”之类的东西来支配,它是一门工程学科。考虑你的设计是否解决了问题,是否易于维护,是否易于测试,是否可以并行开发等等。如果你想要更加正式的规范,请查看 D. L. Parnas 的《将系统分解为模块应使用的标准》。
至于你的图书馆例子。想象一下,如果你有一个在图书馆外的副本,那么它应该有“借出”方法吗?借阅如何注册?你是否同意 Copy 或 Patron 类负责数据存储?把 “borrow” 方法放到 Library 类中更加合适。职责将被清晰地划分,你不需要知道太多关于借阅的细节来实现 Copy 和 Patron,也不需要太多关于它们的细节来实现 Library。
类中公开的方法是可以在实体上执行的任务。这样,类只会封装其行为。
例如:
Computer.TurnOn()
该方法仅适用于计算机系统。
相反,如果我说:
SomeOne.TurnonComputer()
现在,某人将有责任打开计算机(设置计算机相关属性),这意味着我们没有满足封装的概念,而是将类的属性散布到各个地方。
Library.lend(book, patron)
和Patron.loan(book)
。lend
将会改变Library
中必要的数据并调用Patron
上的loan
,这将会改变Patron
中必要的数据。 - KaptajnKoldlibray.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));
}
mouth.eat(banana)
还是banana.eat()
? - Frungi对于确切的理由我不是很确定,但你可以这样想,如果多个患者去看医生,只有医生知道什么时候叫下一个患者,所以下一个方法应该是医生职责的一部分,尽管认为下一个应该是患者的责任很诱人,因为他必须接下来去看病,但在某些情况下,当图书馆书籍需要借出时,它应该是书籍类型而不是读者的责任,因为书籍(资源)知道何时会空闲。
我想这可以两种方式实现。没有硬性规定。重点是逻辑上合理的分组函数。对我来说,Patron#borrow(BookCopy)
和 BookCopy#borrow(Patron)
意义相同。或者你可以有一个类 LibManager.borrow(BookCopy, Patron)
。
你的讲师是对的。嗯,实际上他是错的。我不知道。
我的观点是,对于这样的问题,通常没有确定的一般性答案。它主要取决于在您特定情况下最有效的方法。选择最容易编码的方式-它将是最容易维护的方式。而且,“最容易编码”也建议考虑类的预期用户(不仅仅是您的Library
,Copy
和Person
类)。
library.loan(patron, copy)
吗?可能有很多可行的设计方案。如果您不理解,为什么不问他呢?请注意,我没有进行任何解释或添加额外的内容。 - Carl Norumcopy.borrowCopy(account)
。而且我已经说过他解释得不太好。 - Frungi