Heim  >  Fragen und Antworten  >  Hauptteil

Verwenden Sie Polymorphismus, um mehrere Ergebnisse zurückzugeben und mehrere Verhaltensweisen gleichzeitig zu verwenden

<p>Ich verwende Laravel 9 und habe eine Anfrage, die Folgendes enthält: </p> <ul> <li>Parameter mit dem Namen SEASON, Wert kann <code>array</code> sein Der Parameter <code>SEASON</code> kann also <code>array</code> sein. <li>Der Parameter mit dem Namen EXPIRY kann entweder <code>array</code> oder <code>null</code></li> sein. </ul> <p>Ich habe zwei Klassen, eine für die <code>SEASON</code>-Funktionalität und eine für die <code>EXPIRY</code>, beide aus der <code>Repository</code> Beide verfügen über eine Methode namens <code>execute</code>, die ein Array</p> zurückgibt. <pre class="brush:php;toolbar:false;">abstraktes Klassen-Repository { abstrakte öffentliche Funktionexecute(): array; } Die Klasse Expiry erweitert das Repository { öffentliche Funktionexecute() { return ['Die Anfrage enthält Ablaufparameter und saisonale Verhaltensweisen sind abgeschlossen']; } } Die Klasse Season erweitert das Repository { öffentliche Funktionexecute() { return ['Die Anfrage enthält Saisonparameter und das Ablaufverhalten ist abgeschlossen']; } }</pre> <p>Wenn meine Anfrage SEASON enthält, möchte ich die Execute-Methode der Season-Klasse aufrufen, oder wenn meine Anfrage Expiry enthält, möchte ich die Execute-Methode von Expiry aufrufen. Oder rufen Sie sie auf und führen Sie die Ausführungsrückgaben in einem Array zusammen, damit ich die Ergebnisse erhalten kann. </p> <pre class="brush:php;toolbar:false;">['Die Anfrage enthält einen Ablaufparameter und das saisonale Verhalten ist abgeschlossen', 'Die Anfrage enthält einen Ablaufparameter und das Ablaufverhalten ist erledigt']</pre> ; <p>Das habe ich im Controller versucht: </p> <pre class="brush:php;toolbar:false;">public function bootstrap($data) { $parseTopics = Helper::parseTopicsRequest(); $basicProgram = new BasicProgramRepository(); $seasonalProgram = new SeasonalProgramRepository($parseTopics['SEASONAL']); $object = count($parseTopics['SEASONAL']) ? $seasonalProgram : $basicProgram; // Polymorphismus return $object->execute(); }</pre> <p>Frage 1: Ich bin mir nicht sicher, ob ich dies oder etwas Ähnliches verwenden soll, um meine Anforderungen zu erfüllen: </p> <pre class="brush:php;toolbar:false;">$employe = new Program(new BasicProgramRepository());</pre> <p>Erwartete Ergebnisse: Das erwartete Ergebnis hängt davon ab, ob ich Saisonparameter und Ablaufzeit habe. Was ich erreichen möchte, ist die Verwendung eines anderen Verhaltens (Ausführungsmethode)</p>
P粉187677012P粉187677012431 Tage vor576

Antworte allen(1)Ich werde antworten

  • P粉086993788

    P粉0869937882023-09-06 18:46:06

    如果你想实现多态方法,最好创建存储库或仅用于管理该逻辑的东西。

    这是示例。

    class SampleRepository
    {
        /**
         * repository instance value
         *
         * @var string[] | null
         */
        private $sampleArray; // maybe here is SEASON or EXPIRY or null
    
        /**
         * constructor
         *
         * @param string[] | null $sampleArray
         */
        public function __construct($sampleArray)
        {
            $this->sampleArray = $sampleArray;
        }
    
        /**
         * execute like class interface role
         *
         * @return array
         */
        public function execute()
        {
            return (!$this->sampleArray) ? [] : $this->getResult();
        }
    
        /**
         * get result
         *
         * @return array
         */
        private function getResult()
        {
            // maybe pattern will be better to manage another class or trait.
            $pattern = [
                "SEASON" => new Season(),
                "EXPIRY" => new Expiry()
            ];
            return collect($this->sampleArray)->map(function($itemKey){
                $requestClass = data_get($pattern,$itemKey);
                if (!$requestClass){ // here is space you don't expect class or canIt find correct class
                    return ["something wrong"];
                }
                return $requestClass->execute();
            })->flatten();
        }
    }

    你可以这样调用。

    $sampleRepository  = new SampleRepository($sampleValue); // expect string[] or null like ["SEASON"],["SEASON","EXPIRY"],null
        $result = $sampleRepository->execute(); // [string] or [string,string] or []

    此方法仅适用于您的参数指定值。 如果Season类和Expiry类的返回结果几乎相同,那么最好在trait上进行管理。 (即示例代码中的 $pattern)

    尝试一些。

    我读了评论,所以关注..

    例如,它更愿意只获取 getResult() 的结果。 因此,某些模式和如此多的逻辑不应该写在 getResult() 上;

    如果您使用特征,这是示例。 首先,您需要创建管理行为类。

    行为.php

    <?php 
    namespace App\Repositories;
    
    class Behavior
    {
        use Behavior\BehaviorTrait;
        // if you need to add another pattern, you can add trait here.
    }

    然后,您需要在同级位置创建Behavior目录。 你移动该目录,你就创建了这样的特征文件。

    <?php
    
    namespace App\Repositories\Behavior;
    
    trait BehaviorTrait
    {
        public static function findAccessibleClass(string $itemKey)
        {
          return data_get([
            "SEASON" => new Season(),
            "EXPIRY" => new Expiry()
          ],$itemKey);
        }
    }

    findAccessibleClass() 方法负责查找正确的类。

    然后,你可以像这样调用这个方法。

    private function getResult()
        {
            return collect($this->sampleArray)->map(function($itemKey){
                $requestClass = Behavior::findAccessibleClass($itemKey); // fix here.
                if (!$requestClass){ // here is space you don't expect class or canIt find correct class
                    return ["something wrong"];
                }
                return $requestClass->execute();
            })->flatten();
        }

    如果 getResult() 中的代码太多,最好将负责的代码分开。

    要创建Behavior Trait,getResult不需要负责行为逻辑。简而言之,它将很容易测试或修复。

    希望一切顺利。

    Antwort
    0
  • StornierenAntwort