这里的最佳做法是什么...
这取决于您的用例,用户将如何使用系统?会不会是实验室被“吹”了Person
?或者系统的用例是有一些Person
爆炸Labs
?
或者也许它甚至不重要:S
最后结果是一样的,但这里重要的是代码的语义。如果让 Labs 被人攻击听起来很愚蠢,那就不要这样做。
因此,正如 BobTurbo 所提到的,黄金法则是找出系统中的“信息专家”(参见:GRASP)并将控制权交给该对象。
您通常会定义用户历史记录或系统使用方式的叙述,例如,叙述是:
当一个人做某事时,必须通知实验室中的每个人。
然后,对我来说,这意味着 aPerson
在 a 中工作Lab
,当它被创建时,该人可能会收到他工作的实验室,并注册自己以了解该 perticula 实验室中发生的事情。
由于实验室有要通知的人员列表,因此执行通知的实验室是有意义的(在这种情况下,人员将控制权交给实验室)
那么可能Person
可以定义为:
labs.Person {
- name: String
- lab : Lab
+ Person( withLab: Lab , andName: String ) {
self.lab = withLab
self.name = andName
self.lab.subscribe( self ) // want to know what happens
}
+ blowUpLab() {
lab.boom!(blownBy:self)
}
// receive a lab even notification
// performed by "someone"
+ labEvent( lab:Lab, by: Person ) {
// if is my lab and it wasn't me?
if( self.labg .== lab .&& self .!= by ) {
// ok it was someone else....
}
}
}
所以,这个人在实验室做了一些事情,在这种情况下,公共方法blowUpLab
只是通过调用 Lab 的方法来炸毁这个人的实验室boom!
。
依次Lab
执行方法操作并在最后通知其所有订阅者:
labs.Lab {
- labName:String
- subscribers: Person[0..*]
+ subscribe( to: Person ) {
subscribers.add( to )
}
+ boom!( blowedBy: Person ) {
// do blow up the lab
....
// and then notify:
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 ) {
// every now and then, have someone blowing up it's lab
if ( randomNumber() .== 42 ) {
person.at( randomPosition ).blowUpLab()
}
}
}
}
这个主应用程序将创建三个人,带有一些实验室,其中只有两个是相关的(scott 和 gordon)
随机其中一个将收到blowUpLab
消息并执行该方法。该实验室将依次通知该实验室的所有订阅者。
因此,当 James Hetfield 炸毁其实验室时,不会通知任何人 :)
关键是要描述您的用例,并确定那里的信息专家;将控制权交给该对象,并让该对象将控制权依赖于其他对象,但仅根据您的用例
我希望这是有道理的。