dimanche 18 mars 2018

Design Pattern for varied input to create collection of objects

Let's say I have the following simple class

<?php
class Variable
{
    private $variableName;
    private $variableValue;

    public function __construct($name, $value)
    {
        $this->variableName  = $name;
        $this->variableValue = $value;
    }
}

I am keeping the Variable objects in a collection of the following Collection class.

class Collection
{ 
    private $items = array();

    public function addItem($obj) {
        // Code for adding an item
    }

    // Other methods delete, sort, filter, etc

}

Also, let's say I'm using a very inconsistent API to import a bunch of variable names and values. The API returns JSON but it could really be anything.

I say the API is inconsistent because depending upon your URI, the Variable object could return $raw data in this format:

{  
    "variables" : [  
        {  
            "name" : "variable_one",
            "value" : "foo"
        },
        {
            "name" : "variable_two",
            "value" : "bar"
        }
    ]
}

Or the $raw data could be in this format:

{  
   "dataObject" : {  
      "variable_one" : "foo",
      "variable_two" : "bar"
   }
}

In addition, this API is still maturing and I can foresee them making unpredictable changes to the $raw format of the variable data in the future.

Here is my current solution for consuming the $raw data to get a collection of Variable objects:

<?php
    // Turn JSON into stdObject
    $variableData = json_decode($raw);

    // Collection object to hold the variables
    $variables = new Collection()


    if ( property_exists($variableData, 'variables') ) {
        foreach ( $variableData as $variable ) {

            // Use for the first type of JSON
            $variables->addItem(
                new Variable($variable->name, $variable->value)
            );

        }
    } else {
        foreach ($variableData as $key => $value) {

            // Use for the second type of JSON
            $variables->addItem(new Variable($key, $value);

        }
    }

The problem with this solution is that if the variable constructor becomes more complex, or the number of different formats $raw can be grows, this solution becomes a big fat mess.

If the Variable grows in complexity and requires a VariableFactory, I would need to create a separate factory for each type of $raw input. If the number of types of $raw input grows, the above code becomes a big fat mess of if and elseif statements.

Is there's a good design pattern I can use for varied $raw input to create a Collection of Variable objects?

Aucun commentaire:

Enregistrer un commentaire