какая здесь самая лучшая практика ...
Это зависит от вашего варианта использования , как пользователь будет использовать систему ?. Будет ли лаборатория "взорвана" Person
? или в случае использования системы нужно взорвать Person
Labs
?
или, может быть, это даже не имеет значения: S
В конце результат тот же, но здесь важна семантика кода. Если звучит глупо, если люди будут взрывать лаборатории, не делайте этого.
Таким образом, золотое правило, как упоминает BobTurbo, состоит в том, чтобы найти «информационного эксперта» (см .: GRASP ) в системе и передать управление этому объекту.
Обычно вы определяете пользовательскую историю или описательную часть о том, как будет использоваться система, если, например, описательная часть:
Когда человек что-то делает, каждый в лаборатории должен быть уведомлен.
Тогда, для меня это означает, что Person
работает в 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
, который просто взрывает лабораторию человека, вызывая метод 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()
}
}
}
}
Это основное приложение, создаст три человека, с какой-то лабораторией, только два из них связаны (Скотт и Гордон)
Случайно один из них получит сообщение blowUpLab
и выполнит метод. Лаборатория, в свою очередь, уведомит всех подписчиков этой лаборатории.
Итак, когда Джеймс Хэтфилд взорвет свою лабораторию, никто не будет уведомлен :)
Дело в том, Опишите ваш вариант использования и найдите там информационного эксперта; передать управление этому объекту и позволить этому объекту полагаться на управление другим объектом, но только в соответствии с вашим вариантом использования
Надеюсь, это имеет смысл.