SocialService в каждом методе на каждый вызов постоянно создавать новый класс
Псевдо код:
DI можно заюзать (dependency injection). Получится примерно так: class SocialService { public function _construct( protected TGSocialService $telegramService, protected VKSocialServics $vkService ) {} public function delete(Post $post): void { some_condition ? $this->telegramService->delete($post) : $this->vkService->delete($post); } // ... } // Code for the customers $posts->each( fn (Post $post) => $this->socialService->delete($post) );
можно просто app(ClassName::class)->method()
как выглядет сам кондишн?)
ну DI не очень хочу, т.к. один из сервисов вообще может ни разу не заюзаться в ходе жизненного цикла, хочу сделать наверное отложенную инициализацию через геттеры и сеттеры. Тут больше вопрос в том что сервисов может быть и не 2 и не 3, хотелось удобную масштабируемость иметь. Куча if-ов городить не хочется
Паттерн Фабричный как будет?)
ну в данном сервисе через геттер пробрасывай нужный провайдер нужной сети. А выше где-то его разруливай через фабрику
Юзай match: protected function service(Post $post): SocialService { return match(true) { condition_1 => new TgSocialService(), condition_2 => new VKSocialService(), condition_3 => new ..., default => ... } } public function delete(Post $post): void { $this->service($post)->delete($post); }
только опять таки на каждый вызовы новый объект)
хочешь чтобы создавалсь только один обьект?
protected function service(Post $post): SocialService { return match(true) { condition_1 => $this->getTgService(), condition_2 => $this->getVkService(), condition_3 => new ..., default => ... } private function getTgService(): TgService { if(!$this->tgService) { $this->tgService = new TgService(); } return $this->tgService; } } public function delete(Post $post): void { $this->service($post)->delete($post); }
Класс разрастется, тебе на каждый сервис добавлять метод и свойство. Храни в свойстве-массиве все инициализированные
Как вариант. Разрастается конечно, но уже не так критично.
protected function service(Post $post): SocialService { return match(true) { condition_1 => $this->getService(TgSocialService::class), condition_2 => $this->getService(VKSocialService()), condition_3 => new ..., default => ... } private function getService(string $class): SocialService { if(isset($this->services[$class]) { return $this->services[$class]; } return $this->services[$class] = new $class(); } } public function delete(Post $post): void { $this->service($post)->delete($post); }
похоже у тебя перевернуто немного. я очень сомневаюсь, что нагромождение if-ов тебе нужно. и match - это тоже теже ифы, погоду не меняют. у тебя есть класс SocialServices, который вызывает сервисы, которые выглядят как подтипы этого сервиса, что не так, т.е. нестыковка логики. куда логичнее было б, что TgSocialService является подтипом SocialService. этот код как не пиши будет выглядеть всегда уродливо. тебе же надо инжектить SocialService (абстракцию) - а уже передавать необходимый подтип, Tg,Vk и прочие. Посмотри паттерн адаптер и декоратор на эту тему. у тебя по сути получилось некоторое подобие фабрики, но топорное, а ваще переизобретаешь сервис контейнер ларки. на счет ветвления логики посмотри паттерн стратегия. ну и еще как вариант, ты можешь сделать обычный массив в конфигурации, например tg => App\Services\TgService, vk => App\Services\VkServices и таким образом по ключу вытаскивать нужную реализацию и еще: у тебя в примере some_condition ? A : B, где B получилось дефолтным значением. этот момент тоже лучше обыграть, т.е. ты либо матчишь по ключу и возвращаешь сервис, либо кидаешь эксепшен, если такого сервиса нет, либо возвращаешь дефолтный сервис.
Спасибо, почитаю
Обсуждают сегодня