У меня большой класс (1500 строк, но скоро будет в несколько раз больше), который я хотел бы разделить, чтобы он лучше соответствовал SRP (и так, чтобы каждый файл был меньше и более управляемым.)
Класс содержит 50-100 свойств и имеет несколько различных типов действий, которые выполняются с ним — одно из которых будет update
который, в свою очередь, выполняет несколько шагов, таких как обновление базы данных и отправка электронных писем.
Поэтому я думаю, что я хочу 4 класса.
Как мне структурировать занятия?
Вот упрощенная версия того, что я имею сейчас:
class Foo {
public function __construct ($params) {}
public function update () {
$this->updateDatabase();
$this->sendEmails();
}
private function updateDatabase () {}
private function sendEmails () {}
}
$foo = new Foo($params);
$foo->update();
updateDatabase()
а также sendEmails ()
каждый вызывает много других методов — сотни строк кода каждый, и у них есть несколько родственных методов, выполняющих другие задачи.
Основное переписывание для использования статических методов
class Foo {
public function __construct ($params) {}
}
class FooUpdate {
public static function update ($fooParam) {
FooUpdateDatabase::main($fooParam);
FooSendEmails::main($fooParam);
}
}
class FooUpdateDatabase {
public static function main ($fooParam) {}
}
class FooSendEmails {
public static function main ($fooParam) {}
}
$foo = new Foo($params);
FooUpdate::update($foo);
Основное переписывание для использования созданных объектов
class Foo {
public function __construct () {}
}
class FooUpdate {
private $foo;
public function __construct ($fooParam) {
$this->foo = $fooParam;
}
public function main () {
$fooTemp = FooUpdateDatabase($this->fooParam);
$fooTemp->main();
$fooTemp = FooSendEmails($this->fooParam);
$fooTemp->main();
}
}
class FooUpdateDatabase {
private $foo;
public function __construct ($fooParam) {
$this->foo = $fooParam;
}
public function main () {}
}
class FooSendEmails {
private $foo;
public function __construct ($fooParam) {
$this->foo = $fooParam;
}
public function main () {}
}
$foo = new Foo($bar, ...);
$fooTemp = new FooUpdate($foo);
$fooTemp->update();
Или я должен как-то использовать наследование или черты?
Я предполагаю, что отправка электронной почты — это одно, а представление ваших данных — это другое, а операции чтения и записи в базу данных — третье.
Так class Foo
, class FooPersistence
, class FooMailer
,
И кто бы ни звонки FooPersistence::update($foo)
следует также позвонить FooMailer::sendUpdateNotification($foo)
,
Как примечание стороны:
Если бы у вас было что-то вроде «События», я бы запустил «событие обновления» внутри класса постоянства и добавил к нему прослушиватель, который отправляет электронные письма.
Как говорит @SparK,
Класс, который оборачивает все это (FooManager)
$foo = new Foo($params);
$fooManager = new FooManager(FooRepository, Mailer);
$fooManager->update($foo);
$fooManager->notify($foo); //this could be inside the update or an event.
Таким образом, вы также можете разложить ваши классы (то есть: отделить класс, который обрабатывает соединения с базой данных, внедрить его в FooRepository и т. Д.). Но я не думаю, что иметь классы, представляющие действие, это путь?
Классы — это объекты, которые могут выполнять действия (помимо прочего), а не действия (это просто комментарий из-за имен, которые вы использовали в своем примере: p).