Расщепление большого класса PHP

У меня большой класс (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();

Или я должен как-то использовать наследование или черты?

4

Решение

Я предполагаю, что отправка электронной почты — это одно, а представление ваших данных — это другое, а операции чтения и записи в базу данных — третье.

Так class Foo, class FooPersistence, class FooMailer,
И кто бы ни звонки FooPersistence::update($foo) следует также позвонить FooMailer::sendUpdateNotification($foo),

Как примечание стороны:
Если бы у вас было что-то вроде «События», я бы запустил «событие обновления» внутри класса постоянства и добавил к нему прослушиватель, который отправляет электронные письма.

2

Другие решения

Как говорит @SparK,

  • Ваш объект (Foo)
  • Класс, который обрабатывает связь с базой данных (FooRepository)
  • Класс, который отправляет почту (Mailer)
  • Класс, который оборачивает все это (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).

2

По вопросам рекламы [email protected]