“这里有什么最佳实践...”
这取决于您的
用例,用户将如何使用系统?是实验室被“人”“吹”起来的情况吗?还是系统的用例是让一些“人”炸毁“实验室”?
“或者也许这并不重要:S”
最终结果是相同的,但重要的是代码的语义。如果让人们吹起实验室听起来很傻,那就不要这样做。
所以,正如BobTurbo所提到的,黄金法则是找出系统中的“信息专家”(参见:
GRASP)并将控制权交给该对象。
通常,您会定义一个用户历史或故事,说明系统将如何使用。例如,如果故事是:
当一个人做某事时,实验室里的每个人都要被通知。对我来说,这意味着一个
人
在一个
实验室
工作,当他被创建时,他可能会接收到他所在实验室的信息,并注册自己以便接收该实验室发生的事件的通知。
由于实验室拥有要通知的人员列表,因此实验室执行通知是合理的(在这种情况下,人员将控制权交给了实验室)。
那么,可能
Person
可以定义为:
labs.Person {
- name: String
- lab : Lab
+ Person( withLab: Lab , andName: String ) {
self.lab = withLab
self.name = andName
self.lab.subscribe( self )
}
+ blowUpLab() {
lab.boom!(blownBy:self)
}
+ labEvent( lab:Lab, by: Person ) {
if( self.labg .== lab .&& self .!= by ) {
}
}
}
因此,该人在实验室中执行某些操作,例如公共方法blowUpLab
,该方法通过调用实验室的boom!
方法来炸毁实验室。
反过来,Lab
执行方法操作并在结束时通知其所有订阅者:
labs.Lab {
- labName:String
- subscribers: Person[0..*]
+ subscribe( to: Person ) {
subscribers.add( to )
}
+ boom!( blowedBy: Person ) {
....
subscriber.forEach( person: Person ) {
person.labEvent( self, blowedBy )
}
}
}
这是观察者模式。
最后,您的主应用程序将创建人员和实验室并执行用例:
labs.MainApp {
_ main() {
blackMesaLab = Lab("BlackMesa")
gordon = Person( withLab: blackMesaLab, andName: "Gordon Freeman")
scott = Person( withLab: blackMesaLab, andName: "Scott Tiger")
james = Person( withLab: Lab("SO Labs"), andName:" James Hetfield");
persons = Array( gordon, scott, james )
....
while( true ) {
if ( randomNumber() .== 42 ) {
person.at( randomPosition ).blowUpLab()
}
}
}
}
这个主应用程序将创建三个人,每个人都有一些实验室,只有两个人是相关的(Scott和Gordon)。
随机选择其中一个人将收到blowUpLab
消息并执行该方法。实验室将通知该实验室的所有订阅者。
因此,当James Hetfield炸毁自己的实验室时,没有人会被通知:)
重点是描述您的用例,并确定信息专家;将控制权交给该对象,并让该对象依据您的用例来控制其他对象,但仅限于您的用例
希望这有意义。