我无法理解类与其方法的关系。对象做的方法是什么,或 的东西?或者这完全是一个不同的概念?
具体来说,在图书馆的软件系统中,borrow()
方法是属于代表图书馆顾客的类,还是表示顾客借用的项目的类?我的直觉是它应该像patron.borrow(copy)
,如英语句子结构,subject.verb(object)
;但是我的导师说那是错的,我不明白为什么他会borrow()
属于Copy
级(并且他并没有真正解释过的事情)。我不是在寻找理由,但是有人可以解释一下这种正确的关系吗?
编辑:此问题已被关闭为“非主题”。我不明白。软件设计问题不适合本网站吗?
答案 0 :(得分:12)
主观:)但老实说,我会选择Information Expert Pattern并说出类似
的内容library.lend(item, patron)
图书馆包含有关项目的信息(可能在其目录中) 图书馆将该项目借给顾客(它知道因为它注册了它们)
不确定教师如何看待这一点,但这是“抽象”(模仿现实世界实体的软件对象)的级别,这对您的场景有意义。
答案 1 :(得分:10)
你不应该把OOP的想法与Java或C ++这样的特定化身混为一谈。
此限制“方法是对象的属性”不是OOP构思的一部分,而只是某些实现的一部分,并且正如您发现它不能很好地扩展。
“整数”对象有多少种方法?什么更合乎逻辑...... myfile.write(myint)
或myint.write(myfile)
?对此没有什么好的一般答案。作为单个对象的一部分的方法的想法是一种特殊情况,并且有时将问题适合于该解决方案所需的弯曲可以变得显着或者甚至接近于一个显示器。只有当一个方法除了正在处理的对象之外没有参数时,答案才真正完全可以接受:只有涉及单一类型时,单个调度才是完美的答案。
在其他语言中,您将对象和方法分开,因此例如您有文件对象,整数对象和方法write(myfile, myint)
,它描述了在需要操作时要执行的操作...以及此method既不是文件的一部分也不是整数的一部分。
答案 2 :(得分:8)
首先是一些通用词。
软件构建不应该由英语规则或“美”或其他任何东西来管理,它是工程学科。想一想您的设计是否解决了问题,是否可维护,是否可测试,是否可以并行开发等等。如果你想要更正式的东西,请看看D. L. Parnas的“关于将系统分解为模块的标准”。
至于您的图书馆示例。想象一下,你有一个库外的副本,那么它有borrow
方法吗?借款是如何登记的?您是否可以使用负责数据存储的Copy或Patron类?将borrow
放入Library类似乎更合适。责任将明确划分,您不需要了解借用实施Copy和Patron的内容,也不需要太多关于它们的细节来实现Library。
答案 3 :(得分:3)
正如@Ryan Fernandes所说,贷款/借款操作无论是赞助人还是书本。它必须与一些知道图书馆所有书籍和顾客状态的班级。例如,是否有针对某本书的待定预订?有多少份?这位顾客是否支付了所有费用?他有资格获得这本书吗?所以通常这应该在Library或LibraryService类中。
答案 4 :(得分:3)
从类公开的公共方法是可以在实体上执行的任务。 这样,该类只会封装其行为。
例如: 如果我说
Computer.TurnOn()
该方法仅适用于计算机系统。
相反,如果我说,
SomeOne.TurnonComputer()
有人现在有责任打开电脑(设置计算机的相关属性),这意味着我们无法满足封装的概念,并且无法在整个地方散布类的属性。
答案 5 :(得分:3)
OOP的目的是创建多态函数,在每个实现中,它们处理一组遵循特定不变量的定义数据。
因此,应该在该对象的类中定义改变对象的方法。在纯粹功能性的代码存在的地方,重要的是它,但它应该依赖于它的输入类型(如果需要单个输入)或输出。
在您的示例中,如果borrow
改变了copy
中的数据,那么它应该存在于那里。但是,如果您通过在特定集合中保存图书的贷款状态(在赞助人或图书馆的集合中),那么将borrow
放在持有者身上会更有意义。类。但是,后一种设计存在一个副本可能存在于多个集合中的风险,因此您也希望在副本上放置一些信息(以及相应的方法)。
答案 6 :(得分:1)
对于确切的理由不太确定,但你可以这样想,如果多名病人去看医生,只有医生知道何时打电话给下一位病人,所以接下来的方法就是一部分医生的责任,虽然它很容易认为接下来应该成为患者责任的一部分,因为他必须接下来,不管怎样,当图书出版时,它应该是书籍类型的责任而非书籍(RESOURCE)知道什么时候会有空。
答案 7 :(得分:1)
对象的方法是什么,或者对它做了什么?或者这完全是一个不同的概念?
首先让我先澄清一下类和对象。 Class
通常用于表示特定类别。喜欢
所以,它是被驱动的法拉利,以及被吃掉的香蕉。 不是他们的班级
甚至专门针对您的案例。
borrow()
方法是由person
的对象在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));
}
答案 8 :(得分:0)
我想它可以采取任何一种方式。它没有硬性规定。这个想法是逻辑上的组功能是有意义的。对我而言,Patron#borrow(BookCopy)
与BookCopy#borrow(Patron)
具有相同的意义。或者您可能有一个班级LibManager.borrow(BookCopy, Patron)
。
答案 9 :(得分:0)
你的导师是对的。嗯,实际上,他错了。我不知道。
我的观点是,对于这样的问题,往往没有一种坚定的一般性答案。它主要归结为在您的特定情况下最有效的方法。用最简单的代码去做 - 这将是最容易维护的。而且,通过“最容易编码”,我建议还要考虑课程的预期用户(除了Library
,Copy
和Person
课程之外)。
答案 10 :(得分:0)
我正在考虑今天。我得出了这个结论:
无论哪个在适当的环境中更有意义。