Use polymorphism to return multiple results and use multiple behaviors at the same time
P粉187677012
P粉187677012 2023-09-06 00:04:47
0
1
490

I'm using Laravel 9 and I have a request that contains:

  • Parameter named SEASON, value can be array or null So the SEASON parameter can be array or null
  • The parameter named EXPIRY can be either array or null

I have two classes, one for the SEASON functionality and another for EXPIRY, both from the Repository Extension. Both have a method called execute which returns an array

abstract class Repository { abstract public function execute(): array; } class Expiry extends Repository { public function execute() { return ['The Request contains Expiry Parameter, and seasonal behaviors is done']; } } class Season extends Repository { public function execute() { return ['The Request contain Season Parameter, and expiry behaviors is done']; } }

If my request contains SEASON, I want to call the execute method of the Season class, or if my request contains Expiry, I want to call the execute method of expiry. Or call them and merge the execution returns into an array so I can get the results.

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

This is what I tried in the controller:

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(); }

Question 1: I'm not sure if I should use this or something similar to solve my needs:

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

Expected results: The expected result depends on whether I have season parameters and expiry time. What I want to achieve is to use different behavior (execute method)

P粉187677012
P粉187677012

reply all (1)
P粉086993788

If you want to implement a polymorphic approach, it's better to create a repository or something just to manage that logic.

This is an example.

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(); } }

You can call it like this.

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

This method only works with your parameter specified values. If the return results of the Season class and the Expiry class are almost the same, it is best to manage them on traits. (i.e. $pattern in the example code)

Try some.

I read the comments, so follow..

For example, it prefers to only get the result of getResult(). Therefore, certain patterns and so much logic should not be written on getResult();

If you use traits, here is an example. First, you need to create the management behavior class.

behavior.php


          

Then, you need to create a Behavior directory at the same level. When you move this directory, you create such a signature file.

 new Season(), "EXPIRY" => new Expiry() ],$itemKey); } }

findAccessibleClass() method is responsible for finding the correct class.

Then, you can call this method like this.

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(); }

If there is too much code in getResult(), it is best to separate the responsible code.

To create a Behavior Trait, getResult does not need to be responsible for the behavioral logic. In short, it will be easy to test or fix.

hope everything is fine.

    Latest Downloads
    More>
    Web Effects
    Website Source Code
    Website Materials
    Front End Template
    About us Disclaimer Sitemap
    php.cn:Public welfare online PHP training,Help PHP learners grow quickly!