dennis-fedco Posted June 6, 2014 Share Posted June 6, 2014 (edited) I want to avoid hardcoding things like this: if ($product == "APPLE") $res = $this->doAppleComputation(); else if ($product == "PEAR") $res = $this->doPearComputation(); else if ($product == "KIWI") $res = $this->doKiwiComputation(); ... Note that I can also set it up using a switch statement. Typical advice that I have seen is "do not use switch/if/then/else, use polymorphism". Okay. So I used it and I get this: if ($product == "APPLE") $res = (new Apple())->compute(); else if ($product == "PEAR") $res = (new Pear())->compute(); else if ($product == "KIWI") $res = (new Kiwi())->compute(); ... I am not quite seeing the benefit . . . What am I missing? My goal is to not have if/then/else/switch statements, as polymorphism was supposed to get rid of that, no? Edited June 6, 2014 by dennis-fedco Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted June 6, 2014 Share Posted June 6, 2014 Polymorphism does not magically make all switch statements superfluous. If you want to instantiate different classes depending on a parameter, well, then you need to refer to those different classes. The only way to avoid a switch statement would be to make the class name dynamic: $some_class = 'A'; $a = new $some_class(); But that's not exactly pretty, either. If you take this route, you should definitely check if the parameter indeed refers to a subclass of the product class. Otherwise, you may end up with any class. Quote Link to comment Share on other sites More sharing options...
Maq Posted June 6, 2014 Share Posted June 6, 2014 Assuming all of your fruit classes extend or implement product, it looks like you should be using the factory pattern. Create a ProductFactory class that takes in the $product and returns the correct object. Quote Link to comment Share on other sites More sharing options...
maxxd Posted June 6, 2014 Share Posted June 6, 2014 (edited) I agree with Maq. What you've described above isn't really polymorphism (at least not so much as I understand the concept). What you'd do is create Apple, Pear, and Kiwi class files, the approach like this: $fruit = 'Apple'; $produce = new $fruit(); $res = $produce->calculate(); $fruit = 'Kiwi'; $produce = new $fruit(); $res = $produce->calculate(); $fruit = 'Pear'; $produce = new $fruit(); $res = $produce->calculate(); This way Apple,. Kiwi, and Pear can all have wildly different methods of calculating whatever it is they're calculating and the calling implementation doesn't have to know a thing about any of it. Edited June 6, 2014 by maxxd Quote Link to comment Share on other sites More sharing options...
Solution KevinM1 Posted June 6, 2014 Solution Share Posted June 6, 2014 What you've described above isn't really polymorphism This. Polymorphism is about being able to have different classes that perform the same task at runtime. Take the following example: abstract class Person { private $name; private $salary; public function __construct($name, $salary) { $this->name = $name; $this->salary = $salary; } abstract public function calculateRaise(); } class Employee extends Person { public function calculateRaise() { $this->salary += 1000; } } class Boss extends Person { public function calculateRaise() { $this->salary += 100000; } } class PersonFactory { private $db; public function __construct($db) { $this->db = $db; } public function getPerson($id) { // query the db to get the person info // determine what kind of person to return based on a flag or something $person = new $row['role'](); // fill the person with the rest of the data return $person; } } $factory = new PersonFactory($db); // assuming we instantiated our db somewhere else $people = array(22, 54656, 99, 675, 1009); // person ids foreach ($people as $personID) { $person = $factory->getPerson($personID); $person->calculateRaise(); // save the person to the db }Yeah, the example is canned, and probably has some syntax issues, but you get the idea. The whole point of polymorphism is to hide implementation behind a common API. The loop that gives raises to those people doesn't care if they're an Employee or a Boss. Why should it? So long as a Person can get a raise, does it matter if they're an Employee, Boss, or something else, like a Contractor? No. At some point, you'll need to make a determination about what kind of object to construct. That's generally where factories come in. Their entire purpose is to return a concrete object for the program to use. But, with polymorphism, you'll only be seeing and dealing with the functionality laid out by the abstract base class or interface. Quote Link to comment Share on other sites More sharing options...
maxxd Posted June 6, 2014 Share Posted June 6, 2014 KevinM1 - that's how I always thought about it, but I haven't had nearly enough coffee today. Thanks for the detailed explanation! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.