dennis-fedco Posted May 30, 2014 Share Posted May 30, 2014 (edited) conceptually I have a class that holds data and operations on a product line of products. I wrote the class originally for a Product Line with model numbers B, C, D, E. All of these worked similarly so my class had methods for those model numbers. Later: a new product number A was added for this product line. Turns out model A despite being from the same product line, has different features and somewhat different data, and somewhat different computation patters. I am hacking up my class and now see things like public someMethod() { if ($this->modelNumber == 'A') { //do this special thing } else { //proceed as before for models B, C, D, E } //otherwise, do things that apply to all models, including A, B, C, D, E } Somehow I feel that eventually I will end up with a switch statement for multiple models and conventional wisdom says it is not the way to go. That I am to use polymorphism instead. Well, great, but how? Do I perhaps just extend my product class like class ProductA extends Product { //my specific A model stuff here } If I do this though I will essentially move my If/then/else to the main code. i.e. if ($this->modelNumber == 'A') $product = new ProductA(); //A product else $product = new Product(); //general B, C, D, E and THAT will become the switch statement eventually. So polymorphism does not solve anything for me here. How do I then write / restructure my class, if at all ? Edited May 30, 2014 by dennis-fedco Quote Link to comment Share on other sites More sharing options...
ginerjm Posted May 30, 2014 Share Posted May 30, 2014 (edited) Not by any means an OOP guy, but I have the basic understanding to say this. When designing a class you look for the common denominators of the thing(s) that you are creating it for. If everything you know about your objects can produce a set of properties and methods that are the same for all, then those are things in your "starting" class. When you start to say to yourself - ok, I need to handle b,c,d differently that's when you start to identify a subset of properties and methods for those things and create a sub class that a) inherits the base functionality from the first class and b) adds some new functionality for the new oddballs. You don't begin to modify the methods of the main parent class to accommodate, but rather build a new object that is more flexible. That is polymorphism wherein you morph your object by adding new features to the child class which "extends" the overall functionality of the first class. (Extends - as in "Class mynewclass Extends OldClass"). The key is to recognize ALL the properties and actions that the set of things has in common so that you don't duplicate method/props in a second class. I'm sure you will get many responses to this post now, with many telling me I'm way off base ( I don't think so) and others giving you a more detailed, technical oriented description, but IMHO I think I have given you some food for thought on how to proceed. Edited May 30, 2014 by ginerjm Quote Link to comment Share on other sites More sharing options...
ignace Posted May 30, 2014 Share Posted May 30, 2014 I've seen your questions pass on these forums and they are always very vague and very abstract. So at best you get a very vague and very abstract answer for which the chances of it actually solving your design problems are less than likely. But anyway here goes: How about: public function someMethodFromSomeGhostClass { $this->model->doSomeMethodFromSomeClassInsideGhostClassAndCrossFingers(); } Quote Link to comment Share on other sites More sharing options...
dennis-fedco Posted June 2, 2014 Author Share Posted June 2, 2014 I will rephrase. I have: Mustang 2013 Mustang 2014 Both have wheel sizes of 17" x 8". So I create a Mustang class and it loads wheel specs as part of constructor. In fact I hardcoded it. class Mustang { function __construct() { $wheels = "17 x 8"; } } Now I am adding 2012 Mustang Boss 302Wheel specs are 19" x 9" My class can now look as such: class Mustang { function __construct($model) { switch($model) { case 'Mustang 2013': $wheels = "17 x 8";break; case 'Mustang 2014': $wheels = "17 x 8";break; case '2012 Mustang Boss 302': $wheels = "19 x 9";break; default: } } } I don't think it is good design and I want to change it. Quote Link to comment Share on other sites More sharing options...
maxxd Posted June 2, 2014 Share Posted June 2, 2014 (edited) class Automobile implements iAutoDetails{ private $_model; function __construct($model){ $this->_model = new $model(); } } interface iAutoDetails{ public function getWheelBase(); } class Mustang2013 extends Automobile{ private $_wheels = '17 x 8'; public function getWheelBase(){ return $this->_wheels; } } class Mustang2012Boss302 extends Automobile{ private $_wheels = '19 x 9'; public function getWheelBase(){ return $this->_wheels; } } $auto = new Automobile('Mustang2012Boss302'); print("<p>{$auto->getWheelBase()}</p>"); //prints 17 x 8 $auto2 = new Autmobile('Mustang2013'); print("<p>{$auto2->getWheelBase()}</p>"); //prints 19 x 9 I think the issue is your current object setup. Personally, I'd do the above - that way it really doesn't matter at all what automobile you're instantiating, you know you can call getWheelBase() and you'll get the proper wheel base measurements. Obviously, you'd put any and all common functionality in the parent class (Automobile) while saving the model-specific functionality and information for the child classes. The interface insures that you've got a consistent api when dealing with new objects. Edited June 2, 2014 by maxxd Quote Link to comment Share on other sites More sharing options...
Solution ignace Posted June 2, 2014 Solution Share Posted June 2, 2014 maxxd has the right idea, but i would keep it simple like this: abstract class Auto { abstract public function getWheelBase(); } class Mustang2013 extends Auto { public function getWheelBase() { return new WheelBase(17, ; } }Other option is to pass specific info to the class: class Auto { private $wheelBase; public function __construct(WheelBase $wheelBase, ..) { .. } } 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.