Дубликаты условных заявлений на заводе

Как от них избавиться? Мне интересно, есть ли шаблон или что-то, что решает эту проблему. По сути, мне нужно создать конкретный дочерний класс, основанный на свойстве типа другого класса, т. Е. Если type = 1, то новый A, иначе, если type = 2, затем новый B и т. Д. В итоге я создал такой тип фабрики в класс со свойством типа:

/**
* Get a ticket decorator based on the ticket type
* @return ReferralService\TicketDecorator
* @throws Exception
*/
public function getTicketDecorator(): ReferralService\TicketDecorator
{
if (!$this->code) {
throw new Exception("Couldn't create a ticket wrapper based on the type without a code");
}

/**
* The debug service
* @var Debug\Service $debugService
*/
$debugService = app(Debug\Service::class);
$debugService->setDebug(config('referral.debug'));

switch ($this->code) {
case self::TYPE_FEEDBACK:
return new ReferralService\TicketDecorator\FeedbackTicketDecorator($debugService);
break;
case self::TYPE_BIRTHDAY:
return new ReferralService\TicketDecorator\BirthdayTicketDecorator($debugService);
break;
case self::TYPE_NEW_PARTNER:
return new ReferralService\TicketDecorator\PartnerTicketDecorator($debugService);
break;
default:
throw new Exception(sprintf("Couldn't instantiate a ticket decorator based on the %s type", $this->code));

}
}

/**
* Instantiate a private page based on the ticket type
* @param ReferralService\Service $service
* @param Referrer $referrer
* @param Ticket $ticket
* @return ReferralService\Page\PrivatePage
* @throws Exception
*/
public function getPrivatePage(ReferralService\Service $service, Referrer $referrer, Ticket $ticket): ReferralService\Page\PrivatePage
{
if (!$this->code) {
throw new Exception("Couldn't create a private page based on the type without a code");
}

switch ($this->code) {
case self::TYPE_FEEDBACK:
return new ReferralService\Page\PrivatePage\EmailReference($this->service, $referrer, $ticket);
break;
case self::TYPE_BIRTHDAY:
return new ReferralService\Page\PrivatePage\Birthday($this->service, $referrer, $ticket);
break;
case self::TYPE_NEW_PARTNER:
return new ReferralService\Page\PrivatePage\Partner($this->service, $referrer, $ticket);
break;
default:
throw new Exception(sprintf("Could't find a page for the type", $this->code));
}
}

Каждый метод на заводе проверяет поле типа, для меня это выглядит неуклюже. Я думал иметь отдельный дочерний класс для каждого типа и использовать фабричные методы без условных операторов, но я не могу сделать это с моделями Laravel.

0

Решение

Это очень распространенный шаблон рефакторинга заменить условные выражения полиморфизмом.

Вы можете просто внедрить фабрику для создания специализированных TicketTypes и реализовать фабричные методы на типах заявок для создания конкретных TicketDecorator а также PrivatePage,

Тем не менее, просто имейте в виду, что это вводит связь между TicketType и конкретные классы, которые он создает. Если предпочтительнее избежать такой связи, придерживайтесь первоначального дизайна.

1

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

Ну, вот мое решение. Я отделил TicketType (класс из исходного поста с условными выражениями) из всего, чтобы он не знал о страницах / декораторах.

В то же время я создал конкретные классы билетов: BirthdayTicket, PartnerTicket,

Я поместил фабричный метод в Ticket класс, который создает конкретный экземпляр класса заявки на основе типа заявки — BirthdayTicket, PartnerTicket и т.д. Конкретные классы билетов производят вещи, которые мне нужны (страницы, декораторы), используя полиморфизм, как предложено @plalx выше.

1

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