dennis-fedco Posted December 15, 2014 Share Posted December 15, 2014 (edited) I have class MyProductClass { function computeProductA() { doSometing(); } function computeProductB() { doSometingElse(); $this->computeProductCommon(); } function computeProductC() { $this->computeProductCommon(); } function computeProductCommon() { } } And I was wondering ... does it make sense to move out product-specific functions into their own classes and then have them extend MyProductClass. While I think it makes sense to me from an aesthetic point of view, and that I get to use object oriented principles, I could not answer myself as to "Why" I would do that. So, why? Why would I do that, and should I? Right now in the code, various product specific classes instantiate MyProductClass and just use their specific and generic functions, as needed. Edited December 15, 2014 by dennis-fedco Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/ Share on other sites More sharing options...
NotionCommotion Posted December 15, 2014 Share Posted December 15, 2014 Do you have common things you need to do to all products? For instance, computeProduct, orderProduct, buildProduct, etc? By creating a separate class for each product which extends a generic product, your outer application does not need to worry about the specific method names of each product type, and your individual product classes do not need to duplicate the script in the generic product class. Whether you should do so is based on your specific requirements, and there is no absolute answer, however, I expect you should do so. Also, you might want to look into factory method pattern. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499630 Share on other sites More sharing options...
dennis-fedco Posted December 15, 2014 Author Share Posted December 15, 2014 I do have common things among products, not neccessarily all of them. There are groups and subgroups of products that need specific computations. So in a sense methods I have in the class are like a library. A specific method, depending on the product may call the same function for product A and B, for example. I have "generic" methods right now that have if ($product == "A") { } else if $product == "B") { } and I have ones that do not use product destinction, and just do a small computations that may be be called for several different products. I don't see where to put factory method or why it is needed .. Are you saying I can use it to hide the fact that I may be instantiating different products?... As in, I have {x, y, z}, give me a Product that I can use generically? There is no globally common functions between all products, but there are groups of them. i.e. {A, B, C} may use computations for X, and Y, but products {C, D, E} may use computation functions for Z and W. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499632 Share on other sites More sharing options...
dennis-fedco Posted December 15, 2014 Author Share Posted December 15, 2014 There are some common methods, yes, like computing model name for a product, with a fuction that goes if ($product == "A") $model = ".."; else if $product == "B") $model = ".."; //etc Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499634 Share on other sites More sharing options...
maxxd Posted December 15, 2014 Share Posted December 15, 2014 If that's the case, you can use multiple levels of inheritance. For instance, create the abstract Product() class, extend that in the ProductGroupA() class, then extend that for each product in group A. Do the same for group B, C, etc. You'll create the new middle class based on the similar functionality. Because everything is extending from the base Product() superclass, you can use that as a type hint in your code and everything will work. If I'm not mistaken in the labels, it's kind of a combination of both factory and strategy patterns. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499635 Share on other sites More sharing options...
dennis-fedco Posted December 15, 2014 Author Share Posted December 15, 2014 I am more so asking why use inheritance (in my case). I know I can use it and I have an idea of what I want it to be like, but the "why" part is hazy to me. I don't want to use it just because it's cool to do so, or just because it's "object oriented" if I do, or just because it's the craze right now. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499672 Share on other sites More sharing options...
NotionCommotion Posted December 15, 2014 Share Posted December 15, 2014 I am more so asking why use inheritance (in my case). Because it might allow you to write, test, and maintain your script in less time. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499675 Share on other sites More sharing options...
requinix Posted December 15, 2014 Share Posted December 15, 2014 Here's a practical reason: What if you had 20 products? You'd have (up to) 20 different "computeProductX" methods. And that's just for computeProduct. Another method to customize means another 20 methods. Now you've got 40 methods to sift through when looking at the code. Do you really want to do that? Inheritance lets you do the same thing you're doing now but keeps the code a lot simpler. Each subclass has only the differences it needs. When you want to find how product M computes its whatever, you don't have to sift through dozens or even hundreds of methods to find the one you want, and instead you go to the M class and look at its computeProduct method. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499683 Share on other sites More sharing options...
maxxd Posted December 15, 2014 Share Posted December 15, 2014 And, in all honesty, you don't have to use inheritance. A composition-style setup would be doable as well. Granted, it might take a bit more thought and work at the outset, but it would be less coupled and potentially easier to modify if the need arises. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499694 Share on other sites More sharing options...
Jacques1 Posted December 16, 2014 Share Posted December 16, 2014 (edited) You don't necessarily need inheritance, but what you desparately need is polymorphism. Stuffing all methods of all product variants into a single class and using gigantic if statements to pick the right method whenever you want to do something with a product is an awful approach. It obviously leads to code clutter par excellence, and if you want to add a new variant, you have to go through your entire project and adjust all if statements – hoping that you won't overlook any. This is not how programming works. It's not just bad OOP code. It's bad code in general and shows a lack of abstraction. Think about it: Does the user of a product really need to know every single variant with its specific computation method? Why not leave the computation to the product? The user just asks for the result, and then the current variant (whatever it is) will take the necessary steps. If you want to drive a car, you don't need to know every single car model and how it works internally. You just turn the ignition and leave the rest to the car. It's the same thing with code: As a user, you want an interface for a product. This interface provides various product funitionalities like computation, getting the model code etc. How exactly those functionalities are implemented is entirely up to the variant. The user doesn't care. Like I said above, this doesn't necessarily lead to inheritance. If the products don't share anything except the API, then you want an interface: <?php interface Product { public function compute(); public function getModelCode(); } class ProductA implements Product { public function compute() { return 1 + 1; } public function getModelCode() { return 'AAA'; } } class ProductB implements Product { public function compute() { return 2 + 2; } public function getModelCode() { return 'BBB'; } } Now the user of a product only has to call the API functions without having to distinguish between the different variants: $model_code = $product->getModelCode(); Which getModelCode() method of which class this is doesn't matter. We just want the model code, and the variant knows how to calculate it. Edited December 16, 2014 by Jacques1 1 Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499700 Share on other sites More sharing options...
dennis-fedco Posted December 17, 2014 Author Share Posted December 17, 2014 And, in all honesty, you don't have to use inheritance. A composition-style setup would be doable as well. I don't immediately see how that will work. .. Maybe because of my specific use case, it didn't make sense, or maybe I am not seeing how it could be used. My products are different enough where I think polymorphism will work a little cleaner. With composition, I think I will just have mostly disjoint composites. soo .. say model code ... maybe a couple of the products share the same model code, but the rest are different. How would I code that? What would I call it? If ProductA and ProductB use the same model code, but Product C through F are all different, what would I do? Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499857 Share on other sites More sharing options...
Jacques1 Posted December 17, 2014 Share Posted December 17, 2014 If product A and product B have a lot in common, it might make sense to create a subclass of product for them. For example: Product is the root class, below that are FooProduct (which in turn is the parent of ProductA and ProductB) and BarProduct (which is the parent of C, …, F). Another approach is to use traits. Unlike inheritance, this does not create a strict hiarchical structure. A trait is basically a method container which can be mixed into arbitrary classes. So ProductA and ProductB would have Product as their parent, but they'd get their model code method from a trait. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499867 Share on other sites More sharing options...
maxxd Posted December 17, 2014 Share Posted December 17, 2014 I haven't delved into traits too much yet, so I can't speak to that, but composition could work in much the same way. Instead of inheriting from a common Product parent class, though, the disparate child classes would implement a Product interface. Then you can use Product as a type hint, and the base class still couldn't care less what specific product it's working with or how it works, as long as the product classes are coded to the interface's contract. So all products have a getPrice() method defined in the interface, but ProductA and ProductB return a straight number while ProductC, ProductD, and ProductE all perform complicated mathematical equations to arrive at their prices. The using class doesn't care, 'cause it knows it can simply call $this->product->getPrice() and $this->product will do whatever it needs to and return the price. That being said, you could combine this idea with the inheritance pattern described by Jacques1 quite easily to corral any common functionality between product suites as necessary and override and/or expand the base product functionality in some or all of the leaf classes. Quote Link to comment https://forums.phpfreaks.com/topic/293108-why-use-inheritance/#findComment-1499880 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.