🐴
то есть дублирование кода против неестественного наследования
🐴
что лучше?
🐴
в чат призывается @fes0r
🐴
походу лучше не наследоваться
🐴
но что делать с дублированием - хз
Sergei
я не 100% улавливаю задачу, наверное, но положим у меня есть несто такое:
🐴
у меня превдомапперы
🐴
классы, аккаумулирующие набор методов для оперирования с одной таблицей в БД
🐴
они каждый принимают db_connection как зависимость
Sergei
покажи кода пример
🐴
но для них нет соответствующих моделей
Sergei
не очень пока понимаю
🐴
class BookingMapper { /** * @var Connection */ private $connection; public function __construct(Connection $connection) { $this->connection = $connection; } /** * @param int $user_id * @param int $travel_id */ public function registerBooking(int $user_id, int $travel_id) { $insert = $this->connection->prepare( 'INSERT INTO bookings (user_id, travel_id) VALUES (:user_id, :travel_id) ON CONFLICT DO NOTHING' ); $insert->execute([ ':user_id' => $user_id, ':travel_id' => $travel_id, ]); }
Sergei
и этот код нужно в нескольких классах иметь?
🐴
первые десять строчек одинаковые
🐴
в нескольких классах
Sergei
можно их как-то выделить в метод или функцию?
Sergei
по мне так оно довольно крепко похоже на вложенный объект или что-то вроде того , но не наследование
🐴
Ну я его убрал
🐴
Пусть будет дублирование
🐴
можно их как-то выделить в метод или функцию?
Ну это просто одинаковый конструктор и член класса. Больше ничего
Sergei
в С++ я бы еще подумал нет ли там возможности применить template
Sergei
оно аккурат придумано для переиспользования реализации, но не создавая наследование
🐴
а в дивном мире php есть трейты
🐴
можно их заюзать
Sergei
подозреваю оно что-то похожее
🐴
только мне казалось странной идея иметь конструктор в трейте
🐴
но наверно ок
Evgeniy
в трейте можно абстрактный метод сделать
Sergei
судя по тому что пишут в вашей документации (и как я это понял) - trait это прямо самое то для этого случая
Evgeniy
getConnection()
Evgeniy
и конструктор в трейте не придется описывать
🐴
getConnection()
ну так мне же так или иначе экхемпляр $connection надо передавать
🐴
все равно конструкто нужен получается
Evgeniy
ну если все мапперы с одинаковыми зависямости
Evgeniy
почему нет что то типо BaseMapper и там конструктор описанный ну или да трейты)
Evgeniy
в трейте не будет конструктора
Evgeniy
хотя да ничем)
🐴
ну будет protected function getConnection()
Evgeniy
а чем это лучше?
у тебя допустим штук 10 маппперов с одинаковым конструктором и 2 маппера с одинаковым registerBook методом
Evgeniy
тогда все 10 мапперов наследоваться от BaseMapper
Evgeniy
а у 2 мапперов use RegisterBookTrait;
🐴
BaseMapper получается пустой
Evgeniy
конструктор
🐴
он не определяет никакой интерфейс
🐴
интерфейс у него пустой
🐴
я не вижу смысла в наследовании, если интерфейс пустой
Evgeniy
ну не делай )
Evgeniy
пиши конструктор в каждом классе
🐴
я сделал трейт с конструктором
Evgeniy
ну сделай так)
Evgeniy
но я бы сделал тогда 2 трейта
Evgeniy
в одном конструктор в другом метод
Evgeniy
и из 2 трейта включил бы 1
🐴
зачем метод?
Evgeniy
чтобы там где надо только конструктор можно было юзать только его
Evgeniy
и тогда метод getConnection абстрактный не нужен
🐴
чем плохо protected поле в классе?
Evgeniy
сейчас покажу о чем я
Evgeniy
http://pastebin.com/tdD0cxSG
🐴
понял
🐴
но это мне не подойдет, набор методов типа registerBooking разный у всех мапперов
Evgeniy
а ну тогда да )
Evgeniy
твой вариант лучше.
Evgeniy
если что всегда сможешь к такому виду придти
🐴
Я продолжаю слушать Немчинского. Мое мение о нем улучшается. https://www.youtube.com/user/pro100fox2/playlists
Пантелеев
а кто это такой вообще?
Sergey
Это - клевый дядька который публикует свои лекции
Sergey
у него замечательные лекции по GRASP например, и в целом неплохие лекции по паттернам с разъяснениями откуда они появились и тд.
Иван
Люди. Есть mvc-фреймворк на php (yii2). Хочу логику моделей отделить от ActiveRecord. Допустим я создаю в app\models подкаталог (и подпространство) ActiveRecord и соответствующие классы моделей, наслеюущиеся от db\ActiveRecord располагаю там. Аналогичные классы с бизнес-логикой размещаю в app\models. То есть, допустим, есть у нас лягушки. И есть два класса: models\Frog и models\ActiveRecord\Frog. Экземпляры первого умеют прыгать, квакать и всё такое. А экземляры второго можно получать из базы и сохранять их туда-же. Внимание вопрос: стоит ли models\Frog унаследовать от models\ActveRecord\Frog или запилить что-то вроде декоратора/прокси (в смысле не наследоваться от ar\Frog а обращаться к нему из Frog)? В первом случае вроде всё проще, но насчёт отделения я не уверен. Во втором пользователь не сможет напрямую образаться к методам ActiveRecord (а значит если способ хранения изменится не придётся реализовывать весь интерфейс AR), но как-то всё усложняет.
🐴
Я бы вообще от AR отказался в пользу Data Mapper
Иван
Я бы вообще от AR отказался в пользу Data Mapper
В данном случае на AR будет быстрее сделать. При этом, разумеется, хотелось бы иметь возможность всё что касается хранения и персистентности безболезненно переделать полностью или для отдельных сущностей.
Ale
можно AR оставить, они организуют доступ к полям таблицы
Ale
Люди. Есть mvc-фреймворк на php (yii2). Хочу логику моделей отделить от ActiveRecord. Допустим я создаю в app\models подкаталог (и подпространство) ActiveRecord и соответствующие классы моделей, наслеюущиеся от db\ActiveRecord располагаю там. Аналогичные классы с бизнес-логикой размещаю в app\models. То есть, допустим, есть у нас лягушки. И есть два класса: models\Frog и models\ActiveRecord\Frog. Экземпляры первого умеют прыгать, квакать и всё такое. А экземляры второго можно получать из базы и сохранять их туда-же. Внимание вопрос: стоит ли models\Frog унаследовать от models\ActveRecord\Frog или запилить что-то вроде декоратора/прокси (в смысле не наследоваться от ar\Frog а обращаться к нему из Frog)? В первом случае вроде всё проще, но насчёт отделения я не уверен. Во втором пользователь не сможет напрямую образаться к методам ActiveRecord (а значит если способ хранения изменится не придётся реализовывать весь интерфейс AR), но как-то всё усложняет.
можешь сделать композицией class Frog { constructor(FrogDao $dao) { $this->dao = $dao; } } и дергать dao из твоего класса или вынести это вообще вне и потом мапить твой Frog на dao
Иван
можешь сделать композицией class Frog { constructor(FrogDao $dao) { $this->dao = $dao; } } и дергать dao из твоего класса или вынести это вообще вне и потом мапить твой Frog на dao
Вопрос в том как лучше: так или наследоваться? Несколько статей на эту тему прочёл, уже больше к твоему варианту склоняюсь.
Ale
наследоваться хуже
Ale
если ты передаешь в конструктор, то тестить легко
Ale
подсовывать разные реализации тоже легко
Ale
например запись в файл, в nosql