0

There is a base class Product having all the generic properties and methods which a product should have.

abstract class Product
{   
    public abstract function process();
}

Now, These are the few types of products which may or may not have similar logic.

class Shirt extends Product
{
    public function process()
    {
        return 0;
    }
}

class Trouser extends Product
{
    public function process()
    {
        return 1;
    }
}

class PocketSquare extends Product
{
    public function process()
    {
        return 2;
    }
}

I've used switch statement to distinguish and initialise objects.

$products = $db->query("SELECT * FROM products LIMIT 10");
foreach ($products as $key => $product) {
    switch ($product->type) {
        case 'shirt':
            $products[$key] = new Shirt($product);
            break;
        case 'trouser':
            $products[$key] = new Trouser($product);
            break;
        case 'pocketsquare':
            $products[$key] = new PocketSquare($product);
            break;
    }   
}

Is there any way to avoid switch statement? or any better approach?

  • Is there any reason you want to avoid the switch? – Vincent Savard Jul 16 '19 at 12:41
  • Yes, because this switch statement will be sitting in a class which breaks open/close principle, as later more product types can be added. – kamal pal Jul 16 '19 at 12:50
  • @kamalpal The Open/Closed principle is from the point of view of the clients of your class. In this case, you've already abstracted Product away, and its clients will only depend on the interface, and not any concrete implementations. If you add new concrete implementations, you will not have to modify the clients, and therefore, you respect the Open/Closed principle. Your switch is essentially a Factory which instantiate the correct implementation. This is absolutely fine. – Vincent Savard Jul 16 '19 at 13:39
  • @VincentSavard ok, didn't realised that.Thanks for your views! – kamal pal Jul 16 '19 at 16:25
0

The common alternative to this is take a declarative approach to the solution: replace that switch statement with a hashmap of lambdas.

I've not used PHP in years, so I've likely got the below syntax wrong, but you'd do something like:

$productsMap = array (
    'shirt' => function ($p) { return new Shirt($p); },
    'trouser' => function ($p) { return new Trouser($p); },
    'pocketsquare' => function ($p) { return new PocketSquare($p); }

);

...

$products = $db->query("SELECT * FROM products LIMIT 10");

foreach ($products as $key => $product) {
    $products[$key] = $productsMap[$product->type]();
}
| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.