【发布时间】:2016-10-28 11:57:37
【问题描述】:
如何摆脱它们?我想知道是否有解决此问题的模式或其他东西。基本上我需要根据另一个类的 type 属性来实例化一个具体的子类,即如果 type=1 然后 new A,否则如果 type=2 然后 new B 等等。我最终在具有 type 属性的类:
/**
* 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 模型这样做。
【问题讨论】:
-
它不漂亮,但它没有任何问题。这是拥有工厂的一种非常易读、合法的方式。我不会担心太多
-
您已经可以删除所有无用的
break;(returns 之后)。 -
@Casimir 对,我已经习惯了一直使用 break 语句
-
@Andrew 是的,除非我有更优雅的东西,否则我将保持原样。谢谢!
-
我实际上没有,因为您写的内容非常实用且切中要害。正如我所说,我会接受它,这是合法的。
标签: php design-patterns factory factory-pattern