利用多态性同时返回多个结果和使用多种行为的方法
P粉187677012
P粉187677012 2023-09-06 00:04:47
[PHP讨论组]

我正在使用 Laravel 9 并且我有一个请求可以包含:

  • 名为 SEASON 的参数,值可以是 array 或 null 所以 SEASON 参数可以是 array 也可以是 null
  • 名为 EXPIRY 的参数可以是 array 也可以是 null

我有两个类,一个用于 SEASON 功能,另一个用于 EXPIRY ,它们都从 Repository 扩展。两者都有一个名为 execute 的方法,该方法返回一个数组

abstract class Repository 
{
     abstract public function execute(): array;
}


class Expiry extends Repository
{
   public function execute()
   {
       return ['The Request contain Expiry Parameter, and seasonal behaviours is done'];
   }
}


class Season extends Repository
{
   public function execute()
   {
       return ['The Request contain Season Parameter, and expiry behaviours is done'];
   }
}

如果我的请求包含SEASON,我想调用Season类的execute方法,或者如果我的请求包含Expiry,我想调用expiry的execute方法。或者调用它们并将执行的执行返回合并到一个数组中,以便我可以得到结果。

['The Request contain Expiry Parameter, and seasonal behaviours is done', 'The Request contain Expiry Parameter, and expiry behaviours is done']

这就是我在控制器中尝试过的:

public function bootstrap($data)
{
    $parseTopics = Helper::parseTopicsRequest();

    $basicProgram = new BasicProgramRepository();
    $seasonalProgram = new SeasonalProgramRepository($parseTopics['SEASONAL']);


    $object = count($parseTopics['SEASONAL']) ? $seasonalProgram : $basicProgram;
    // Polymorphism
    return $object->execute();
}

问题1: 我不确定我是否应该使用这种方式或类似的方式来解决我的需求:

$employe = new Program(new BasicProgramRepository());

预期结果: 预期结果取决于我是否有季节参数和到期时间。我想要实现的是使用不同的行为(execute方法)

P粉187677012
P粉187677012

全部回复(1)
P粉086993788

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

这是示例。

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不需要负责行为逻辑。简而言之,它将很容易测试或修复。

希望一切顺利。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号