我有一份Registration's的名单,我需要对每个人适用一套规则。
规则可以是单个Rule,也可以是由树表示的一系列规则。一条规则是ConditionalRule,其中条件本身可以是一棵树(例如,和,或者,不是isOwnedByAdmin),它检查特定条件是否适用于给定的Registration。我在Rule和Conditional上都使用了复合模式,目前收到的注册如下:
$rule->apply($registration)或有条件:
if($condition->check($registration))
{
$rule->apply($registration)
}这是可行的,但今后需要更加灵活。
最后,我将不得不将此方法应用于不是Registration的东西,比如Post对象。在兼容的规则和条件下,Post应该能够同样地在此规则树中运行。例如,两者都可以检查条件isOwnedByAdmin,但只有Post与规则PublishPost兼容。我同意这样一个事实:我将能够构建一个非法的树(因为它需要一个Registration,所以不能在它上运行)。
我可以扩展我的存款接口:
interface Rule
{
public function applyTo(Registration $registration, Env $environment);
}
interface Condition
{
public function check(Registration $registration);
}转入:
interface Rule
{
public function applyToRegistration(Registration $registration, Env $environment);
public function applyToPost(Post $post, Env $environment);
}
interface Condition
{
public function checkRegistration(Registration $registration);
public function checkPost(Post $post);
}最后,我将拥有相当多的(10+) Condition类、许多Rule类和一些需要运行的对象类型(3-10)。每当我需要一个新类型来检查时,我就必须修改所有这些类。
我正在考虑使用访问者模式的两个实例。一个ConditionVisitor和一个RuleVisitor。RegistrationRuleVisitor将使用Registration对象创建,RegistrationConditionVisitor将访问Rule树。
但是,由于我的复合树是应用于资源的“操作”,所以我不确定访问者模式是否适用?因为我正在访问一些没有输入(注册/发布)就无法评估的内容。或者,还有另一种模式是我忽略的,它允许我在对象上使用基于同一树的方法应用?
发布于 2021-05-06 17:48:16
我仍然不确定我完全理解你打算在这里完成什么,但我会尝试并回答,假设这些规则,虽然不一定同时适用于注册和邮政,可以是普遍的,当它们是,逻辑是一样的。例如,假设(从我的头顶)你想强加一个规则,注册和帖子都要求用户有一个有效的电子邮件。在这种情况下,逻辑是相同的,理想情况下,这两种类型的实现是相同的。
注意:我不熟悉PHP语法的细节。如果我搞错了,让我知道,我会尽力纠正它。
如果这种情况成立,我认为有一个比访问者模式简单得多的解决方案。相反,我建议的是一个名为Action的新接口(或者任何对您有意义的接口,如果不起作用的话)。那么,您的规则逻辑将是:
interface Rule
{
public function applyTo(Action $action, Env $environment);
}
interface Condition
{
public function check(Action $action);
}然后,您只根据执行所需的规则和条件来定义Action。Post和Registration然后可以扩展Action接口(假设PHP允许这样做),或者在您想要应用规则的任何具体类型上实现Action。
您提到,有些规则并不适用于所有事物,例如,规则可能适用于Post,但不适用于Registration。在这个设计中,这是完全可以管理的。你有两种清晰的方法可以用来解决这个问题。一种是在计算规则时检查对象的类型,如果规则不适用,则返回“pass”响应。另一种选择是在Action上创建一个方法,例如:
接口动作{公共函数isFooApplicable();}
这是我倾向于选择的路径,特别是如果您有一组独立的类型,而这些规则不适用于这些类型。
发布于 2023-05-01 13:03:55
是。将规则视为遍历的结构,但在访问者中保持遍历。每堂课都有一名双重访客,必须服从规则。
这样,每条规则都必须支持每一个新主题,新主题的新类是必要的,但是如果规则应用程序发生变化,您只需要编写跨主题代码(然后每个访问者都需要更改)。
如果这些权衡不够好,就去查找表达式问题,并寻找替代方案。
https://softwareengineering.stackexchange.com/questions/426085
复制相似问题