给您一个简短的观点:我正在尝试根据条件进行重定向。如果请求满足给定目标的条件,您将重定向到特定目标。
我有Destination
模型,该模型具有许多条件(条件模型)。我有很多条件,它们扩展了基本条件模型,例如DateCondition
,LocationCondition
等(通过政治形态关系制成)。每个条件类型都应具有“服务”,以告知给定条件是否匹配请求。示例DateCondition
应该具有自己的DateConditionMatcher
,该实现实现ConditionMatcherInterface
。
(仅public function match($condition, $request)
)。
我想使用SOLID中的Open Closed原理编写它。首先,我想直接向条件模型添加getMatcher()
函数,并为每种条件类型返回不同的ConditionMatcher
,但是某些ConditionMatchers需要在构造函数中传递其他一些服务,因此这迫使我也将它们注入Condition
的模型是很糟糕的。
也许在ServiceProvider中使用上下文绑定可以解决此问题,但如何解决? 我不知道如何将Model耦合到正确的一个ConditionMatcher,然后像这样自由地使用它:
foreach ($destination->conditions as $condition){
$isMatched = $this->conditionMatcher->match($condition, $request);
}
要始终在$ this-> conditionMatcher下具有正确的ConditionMatcher。 我希望有人能理解我不太清楚的信息。
答案 0 :(得分:0)
我一夜之间想到了提供服务,以保留所有匹配者。此解决方案的唯一缺点是注入每个匹配器。
class ConditionResolver implements ConditionResolverInterface
{
/** @var ConditionMatcherInterface[] */
private $conditionMatchers = [];
public function __construct(
DateConditionMatcher $dateConditionMatcher,
TimeConditionMatcher $timeConditionMatcher,
LocationConditionMatcher $locationConditionMatcher
) {
$this->conditionMatchers[DateCondition::class] = $dateConditionMatcher;
$this->conditionMatchers[TimeCondition::class] = $timeConditionMatcher;
$this->conditionMatchers[LocationCondition::class] = $locationConditionMatcher;
}
}
因此,现在我可以通过这种方式(简化)对给定条件使用正确的匹配器:
foreach ($model->conditions as $condition)
{
$this->conditionMatchers[get_class($condition)]->match($condition, $request);
}
它允许我将各种服务注入AppServiceProvider中的匹配器。
$this->app->singleton(LocationServiceInterface::class, function($app){
return new LocationService();
});
$this->app->singleton(DateConditionMatcher::class, function($app){
return new DateConditionMatcher();
});
$this->app->singleton(TimeConditionMatcher::class, function($app){
return new TimeConditionMatcher();
});
$this->app->singleton(LocationConditionMatcher::class, function($app){
return new LocationConditionMatcher($app->make(LocationServiceInterface::class));
});
总的来说,我认为我可以遗漏一些东西,并且可以通过更优雅的方式来完成,但是现在我将其视为答案。如果您有更好的解决方案,请分享:)