yaleksandr89
@yaleksandr89
PHP developer

Как правильно реализовать реализовать классы Родитель->Потомок?

Здравствуйте.
Не так давно стал изучать ООП, поэтому прощу строго не судить :)
Нужно решить такую задачу. Есть класс:
class Subscribe

<?php declare(strict_types=1);
class SubscribeController
{
    public function notify(Request $request)
    {
        $email = $request->json('from.email');
        if (!isset($email)) {
            return self::userError('from.email is missing.');
        }
        if (!is_string($email)) {
            return self::userError('from.email must be a string.');
        }

        $name = $request->json('from.name');
        if (isset($name) && !is_string($name)) {
            return self::userError('from.name must be either null or a string.');
        }

        try {
            $mailer = Factory::createMailer(app()->basePath(), new EmailAddress($email, $name));
            $mailer->notify('тут название события', new EmailAddress('тут почта', 'тут имя'));
        } catch (Exception $e) {
            return self::error($e->getMessage());
        }

        return self::ok();
    }

    privat static function userError($message)
    {
        return self::error($message, 400);
    }

    privat static function error($message, $code = 500)
    {
        return response()->json($message, $code);
    }

    privat static function ok()
    {
        return response()->json("ok");
    }
}


Ранее событие было одно - подписка на новости, сейчас появились варианты (еженедельный дайджест, рассылка по категориями...). Соответственно нужно создать свой класс на тот или иное событие.

Так как в программирование занимаюсь от силы 6-7 месяцев и до этого шпарил исключительно на процедурке, первое что я сделал в такой ситуации - наговнокодил :) т.е. тупо скопировал содержимое этого класса, дал ему другое название и поменял тип события, фактически изменения (не считая переименования класса) были лишь в одной строке:
$mailer->notify('тут название события', new EmailAddress('тут почта', 'тут имя'));

Понял, что так дела не делаются, попытался вспомнить те статьи и видео, которые я смотрел по ООП (Где объяснялось: есть общий класс Животные, а есть классы Собака, Кошка и т.д.). Решил сделать нечто похожее. Сделать один общий класс SubscribeController и extends создать классы New, Didgest и т.д.

Переименовал приватные методы (обрабатывающие ошибки в protect), вынес в класс-родитель все что смог вынести и классы-потомки стали выглядеть примерно так:
Пример класса потомка

class Didgest extends SubscribeController
{
public function notify(Request $request)
    {
        $email = $request->json('from.email');
        if (!isset($email)) {
            return self::userError('from.email is missing.');
        }
        if (!is_string($email)) {
            return self::userError('from.email must be a string.');
        }

        $name = $request->json('from.name');
        if (isset($name) && !is_string($name)) {
            return self::userError('from.name must be either null or a string.');
        }

        try {
            $mailer = Factory::createMailer(app()->basePath(), new EmailAddress($email, $name));
            $mailer->notify('didgest', new EmailAddress('email', 'name'));
        } catch (Exception $e) {
            return self::error($e->getMessage());
        }

        return self::ok();
    }
}


Но даже тут видно, что копипасты крайне много осталось, фактически, в зависимости от типа события, мне нужно лишь менять название здесь:
$mailer->notify('--->NEW<---', new EmailAddress('email', 'name'));
   $mailer->notify('--->DIDGEST<---, new EmailAddress('email', 'name'));


Собственно подскажите, как можно убрать в класс-родитель(SubscribeController):
$email = $request->json('from.email');
        if (!isset($email)) {
            return self::userError('from.email is missing.');
        }
        if (!is_string($email)) {
            return self::userError('from.email must be a string.');
        }

        $name = $request->json('from.name');
        if (isset($name) && !is_string($name)) {
            return self::userError('from.name must be either null or a string.');
        }


Если его убрать в общий класс, то начинают ругаться переменные: $email, $name, что вполне логично, а как их сделать видимыми из класса-родителя в классах-потомках ума не приложу :( или может вы подскажите, какой-то более элегантный способ в такой ситуации.

Буду очень признателен за помощь!
  • Вопрос задан
  • 149 просмотров
Решения вопроса 1
myks92
@myks92 Куратор тега PHP
Нашёл решение — пометь вопрос ответом!
Паттерн диспетчер событий.

https://github.com/ElisDN/yii2-demo-shop/blob/mast...

Там где нужно вызвать https://github.com/ElisDN/yii2-demo-shop/blob/mast...
Обработчик https://github.com/ElisDN/yii2-demo-shop/blob/mast...

Зависимости через DI
https://github.com/ElisDN/yii2-demo-shop/blob/mast...
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы