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?

marked as duplicate by gnat, BobDalgleish, Robert Harvey Jul 16 at 14:52

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Is there any reason you want to avoid the switch? – Vincent Savard Jul 16 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 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 at 13:39
  • @VincentSavard ok, didn't realised that.Thanks for your views! – kamal pal Jul 16 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]();
}

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