簡體   English   中英

在PHP中使用多態時如何避免反射

[英]How can I avoid reflections when using polymorphism in PHP

我遇到的情況是我有一個“任務”類,可以“進步”

但是,每個任務都有不同的必需參數才能知道如何進行,因此“進度”應該接收不同的參數。

我所做的是確保每個“任務”都實現一個“ ITask”接口,該接口強制實現“進度”方法。 “ prgoress”方法的參數是“ ITaskProgress”接口,這將允許我為每個任務分配正確的任務進度。

問題是當我使用TaskProgress進行進度時,我需要在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;
            }

        }
    }
}

我知道這是一個自以為是的答案,但是就您對我的觀點感興趣而言,我認為您可以相信自己的感受,並應該更加堅定自己的感受:

我不認為這是正確的方法,您將如何正確地將各個部分組合在一起?

同樣,問題標題清楚表明您不喜歡使用反射。 因此,擺脫思考可能是將事情正確處理的好方法。

因此,現在您需要分析一個對象,以便可以使用它。 通常,這對於對象來說非常麻煩,您的情況只是其中的另一個例子。

但是為什么這么麻煩? 為了使對象受益,它們應該更加抽象。 但是,在您的情況下(請不要將它視為侮辱,就像另一個示例一樣),您只需要編寫非常專門的代碼即可使用該對象( Tell Do n't Ask )。

這有點像是由內而外。 任務進度不是實現細節,而是任務本身需要處理不同類型的進度。

那么如何解決呢? 首先,不要做自己不想做的事情(根據您的問題,只做您必須做的事,就是說,如果我理解您對所有事情都正確,以應對“多態性”的障礙[的命名方式)),因此刪除if s:

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尋找事物 )。

這使我們更接近於面向對象編程中經常遇到的控制反轉 現在很清楚,告訴任務要完成特定的任務進度,即代表狀態注入的對象作為方法參數。

如果這是您選擇用來解決總體問題的首要設計,則它還應該指導您找到面向對象設計的育兒模式。 例如,看起來您需要(至少是一個很小的)抽象工廠,因此所取得的進展來自一個類家族(進度任務),因此中央工廠可以提供該家族。 並且可以注入工廠(控制反轉),以便在整個應用程序中這一類類可以是“一個”。

然后哪個任務需要哪個進度,然后工廠可以解決,其余的代碼應該可以正常工作(tm)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM