我遇到的情况是我有一个“任务”类,可以“进步”
但是,每个任务都有不同的必需参数才能知道如何进行,因此“进度”应该接收不同的参数。
我所做的是确保每个“任务”都实现一个“ ITask”接口,该接口强制实现“进度”方法。 “ prgoress”方法的参数是“ ITaskProgress”界面,它将使我能够为每个任务分配正确的任务进度。
问题是,当我使用它进行进度时,我需要在Task内反映taskProgress,以了解“ taskProgress”内部存在哪些成员/方法,以便我可以使用它进行进度。
我觉得这不是正确的方法,您将如何正确地将各个部分组合在一起?
假定由于必须将任务和任务进度保存在不同的位置,因此它们不能生活在同一班级。
interface ITaskProgress {};
interface ITask
{
function progress(ITaskProgress $taskProgress);
}
class DoThisTaskPrgoress implements ITaskProgress
{
public $needThisToProgress;
}
class DoThatTaskProgress implements ITaskProgress
{
public $needThatToProgress;
public $alsoNeeded;
}
class DoThisTask implements ITask
{
function progress(ITaskProgress $taskProgress)
{
if ($taskProgress instanceof DoThisTaskPrgoress)
{
$taskProgress->needThisToProgress++;
}
}
}
class DoThatTask implements ITask
{
function progress(ITaskProgress $taskProgress)
{
if ($taskProgress instanceof DoThatTaskProgress)
{
if ($taskProgress->needThatToProgress > $taskProgress->alsoNeeded)
{
$taskProgress->needThatToProgress = 0;
}
}
}
}
答案 0 :(得分:0)
我知道这是一个自以为是的答案,但是就您对我的观点感兴趣而言,我认为您可以相信自己的感受,并应该更坚定自己的感受:
我觉得这不是正确的方法,您将如何正确地将各个部分组合在一起?
问题标题也清楚表明您不喜欢使用反射。因此,摆脱思考可能是将事物正确摆放的好方法。
因此,现在您需要分析一个对象,以便可以使用它。通常,这对于对象来说是非常麻烦的,您的情况只是这种情况的另一个例子。
但是为什么这么麻烦?为了使对象受益,它们应该更加抽象。但是,在这种情况下(请不要像其他示例那样将其视为侮辱),您只需要编写非常专业的代码即可使用对象(Tell Don't Ask)。
这有点像是由内而外。与其说任务的进度是实现细节,不如说任务本身需要处理不同类型的进度。
那么如何解决呢?首先,不要做您不想做的事情(仅根据您的问题做您必须做的事,也就是说,如果我理解您的所有事情都正确,可以解决“多态性的障碍“ [您的命名方式]),因此请删除if
:
class DoThisTask implements ITask
{
function progress(DoThisTaskPrgoress $taskProgress)
{
$taskProgress->needThisToProgress++;
}
}
class DoThatTask implements ITask
{
function progress(DoThatTaskProgress $taskProgress)
{
if ($taskProgress->needThatToProgress > $taskProgress->alsoNeeded)
{
$taskProgress->needThatToProgress = 0;
}
}
}
因此,现在将反射(类型检查)移出进度实现会感觉更好。
特定合同现在仅在某些任务进度方法的调用方之间需要注意,以提供正确的具体任务进度参数。
由于PHP在可见性中没有“朋友”的概念,因此在这里键入更具体的任务进度类型(与任务进度界面相比)非常重要,以便可以清楚地知道该进程希望使用哪种特定类型。 (Don't Look for Things)。
这使我们更接近inversion of control,我们在面向对象编程中经常会遇到这种情况。现在很明显,告诉任务进展需要特定的任务进展,一个表示状态的对象作为方法参数注入。
如果这是您选择用来解决总体问题的首要设计,则它还应该指导您找到面向对象设计的育儿模式。例如。看来您需要(至少是一个很小的)抽象工厂,因此所进行的工作都来自一个类族(progress 和任务),因此中央工厂可以提供该类。并且可以注入工厂(控制反转),以便在整个应用程序中这一类类可以是“一个”。
然后哪个任务需要进度,然后工厂可以解决,其余代码应该可以正常工作(tm)。