I understand the way you extend a class like ChildClass extends ParentClass, I understand use of class abstraction and interfaces, and I do understand traits
In the articles I have read most of people stated that traits is used in practice to achieve multiple inheritance that is not done by extends functionality as it supports only single extension.
As I understand traits it is more of a collection of functions that can be used by different classes or other traits.
In this question I ask you to tell me how is it correctly done to literally do extension of more than one class not adding some function-collection.
I can be extremely clear about this:
PHP does not allow this.
I indeed believe that traits provides a way to achieve multiple inheritance, under some restricted conditions. If your codebase is extremely OOP pure and well designed, traits may allow you to achieve multiple inheritence.
But it's not a catch all. If this is a stumbling block for you, don't blame this on PHP's design, you probably need to think about a different way to do what you want. (for example: delegate instead of sub-class).
Related
I am using Repository design pattern and I have a function generateBarcode() this function just do some logic and insert data in database.
I am calling this function in more one function and more that one repository to generate a new Barcode.
Question is:
What is the best way to make this function reusable?
Helpers
But I don't think this is a good idea since it am dealing with database.
Events
Firing event and storing the result.
$barcode = event(new NewBarcodeRequired())
That what I am doing right now and data is returned as an array
Also I don't think that is a good idea because I have read that events shouldn't return data.
Repository
Create a new repository for this function but I think it is a very bad idea because I won't create a class for every reusable function that I have.
Traits could be a good option for this case. Which will give you flexibility to use in any of your class without requirement of class extension.
Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.
A Trait is similar to a class, but only intended to group
functionality in a fine-grained and consistent way. It is not possible
to instantiate a Trait on its own. It is an addition to traditional
inheritance and enables horizontal composition of behavior; that is,
the application of class members without requiring inheritance.
http://php.net/manual/en/language.oop5.traits.php
I can not say that this is a question, but more of an opinion request and I am sure many others could benefit from clarifying this issue.
Here is my practical case:
I have an abstract class called DataExchangeService and a lot of sub-classes that extend this one (this is the base CONTROLLER class in my MVC Framework). The administration modules that handle data definiton (Users,Types,Sections etc) they all have the add,edit,delete,list methods with 100% similarity in most cases. I know that because I replicate them by using only search and replace. Now the thing is not all my DateExchangeService sub-classes handle data definiton so there are enough cases where I don't need the CRUD methods.
Multiple inheritance would define these CRUD methods and their behaviour in another class and would extend both these classes where it is needed, but I really do think it is tricky stuff and I do not use it (+PHP doesn't have such functionality). So what would be the best practice?
Here are the approaches that crossed my mind:
CASE A
Define a CRUDHandler class that has all these methods parametrized.
Create a property of CRUDHandler type where it is needed and also implement the CRUD interface that will force me to use these methods.
In the bodies of the implemented methods I add something like this:
public function edit($params) {
$this->params = $params;
$this->CRUDHandler->handle("edit", $this);
}
(In PHP this can be done with the __call() magic method.)
CASE B
Define class CRUDHandler as extending the base DataExchangeService.
When defining a specific type of DataExchangeService (for example
UsersExchangeService) instead of extending DataExchangeService you extend CRUDHandler,
this way you get all you want when it is needed.
So, are there any other opinions on this MultiInheritance approach?
Thanks
There is currently a popular style of thinking that says "favour composition over inheritance". There is too much information on Google to really list it all here, but let's just say that with the rare exception of the occasional abstract base class, I haven't used inheritance in 2-3 years.
The main idea is that any given class, rather than extending base classes that allow it to deliver required functionality, will have dependencies on other classes. In actual fact, to keep things SOLID, it'll have dependencies on interfaces that provide a contract that says they'll perform a function.
You then get to a point where your Controller class has services/components passed-in, which it delegates to in order to get specific jobs done.
Note you can go too far the other way as well. If you have a class that depends on lots of external services especially if not every public method on the class ends up using all of them, you might in fact have two classes after all. I.e. your controller is "violating" the single responsibility principle by doing more than one job. This is especially easy to do by accident with controllers in web frameworks because they kind of encourage it.
At this point, I reckon it's advisable to read up on:
Favour composition over inheritance.
Dependency Injection and Inversion of Control.
Inversion of Control containers (e.g. StructureMap and my personal favourite: Castle Windsor).
I happened to need to extend my class from two others:
My PDOUser class that provides basic PDO helper functions like getRow, query, mysql_error and so on.
My Debuggable class, that provides debugging methods and error methods to print out nice debug and error messages.
I was taught that inheriting multiple classes is a confusing way to make programs and that's why PHP doesn't support it.
Why I wouldn't dare to doubt the advices of more experienced programmers, I can't see a way to solve my problem nicer.
I can't make any of the classes static. The PDOUser class provides protected property pdo that can be also accessed from child classes.
The debugger class accesses the current classes names and method names to provide useful debug info.
I could make one of the helper classes inherit the other, but I think that would be confusing as well.
You can use composition over inheritance. This decouples yours objects.
Your new class doesn't need to inherit two classes, it can hold them as instances and use their functionality.
Inheritance vs. Composition:
Wikipedia
Javaworld
I can not say that this is a question, but more of an opinion request and I am sure many others could benefit from clarifying this issue.
Here is my practical case:
I have an abstract class called DataExchangeService and a lot of sub-classes that extend this one (this is the base CONTROLLER class in my MVC Framework). The administration modules that handle data definiton (Users,Types,Sections etc) they all have the add,edit,delete,list methods with 100% similarity in most cases. I know that because I replicate them by using only search and replace. Now the thing is not all my DateExchangeService sub-classes handle data definiton so there are enough cases where I don't need the CRUD methods.
Multiple inheritance would define these CRUD methods and their behaviour in another class and would extend both these classes where it is needed, but I really do think it is tricky stuff and I do not use it (+PHP doesn't have such functionality). So what would be the best practice?
Here are the approaches that crossed my mind:
CASE A
Define a CRUDHandler class that has all these methods parametrized.
Create a property of CRUDHandler type where it is needed and also implement the CRUD interface that will force me to use these methods.
In the bodies of the implemented methods I add something like this:
public function edit($params) {
$this->params = $params;
$this->CRUDHandler->handle("edit", $this);
}
(In PHP this can be done with the __call() magic method.)
CASE B
Define class CRUDHandler as extending the base DataExchangeService.
When defining a specific type of DataExchangeService (for example
UsersExchangeService) instead of extending DataExchangeService you extend CRUDHandler,
this way you get all you want when it is needed.
So, are there any other opinions on this MultiInheritance approach?
Thanks
There is currently a popular style of thinking that says "favour composition over inheritance". There is too much information on Google to really list it all here, but let's just say that with the rare exception of the occasional abstract base class, I haven't used inheritance in 2-3 years.
The main idea is that any given class, rather than extending base classes that allow it to deliver required functionality, will have dependencies on other classes. In actual fact, to keep things SOLID, it'll have dependencies on interfaces that provide a contract that says they'll perform a function.
You then get to a point where your Controller class has services/components passed-in, which it delegates to in order to get specific jobs done.
Note you can go too far the other way as well. If you have a class that depends on lots of external services especially if not every public method on the class ends up using all of them, you might in fact have two classes after all. I.e. your controller is "violating" the single responsibility principle by doing more than one job. This is especially easy to do by accident with controllers in web frameworks because they kind of encourage it.
At this point, I reckon it's advisable to read up on:
Favour composition over inheritance.
Dependency Injection and Inversion of Control.
Inversion of Control containers (e.g. StructureMap and my personal favourite: Castle Windsor).
I've faced a situation when I want to extend two parent classes, but php does not allow this.
Why I can't extend more than one class, but can implement more than one interface. What's wrong with extending many classes?
It seemed to me like a pretty obvious thing, until I got parse errors.
Is it a bad practice? If so, what are the alternatives?
Is it possible in other languages?
Why multiple inheritance is forbidden in some/most programming languages is argued with the diamond problem http://en.wikipedia.org/wiki/Diamond_problem.
Put simple if you have a car that can swim and drive because it inherits from vehicle and boat what happens on execution of the move function!?
Try using interfaces and follow the Strategy pattern or State pattern.
You're probably looking for: Multiple Inheritance in PHP.
It seems to be possible in Python.
Take a look at Can I extend a class using more than 1 class in PHP?
Is it a bad practice? If so, what are alternatives?
Unless the language is specifically designed for it, yes. Consider, you have two classes, A and B. Both classes provide a public method foo() which have identical signatures (not hard in PHP). Now, you make a class C which extends both A and B.
Now, you call C.foo(). Without explicit instructions, how does the interpreter know which version of foo() to call?
It's not supported by PHP. It can however be simulated using runkit, APD or by just overriding __call and __get to simulate inheritance from multiple classes. Symfony (and I seldomly recommand that) also provides "sfMixin" or "sfMixer" for multiple inheritance.
Separate classes implementing the same method is not a good argument against multiple inheritance, as currently multiple interfaces can be implemented. You just can't implement two interfaces with the same method. Quote from http://www.php.net/manual/en/language.oop5.interfaces.php: "A class cannot implement two interfaces that share function names, since it would cause ambiguity."
I know this question is 2 years old but I've only just had the same problem. My work-around is this: if you have one regular class and two abstracts and want to extend both, e.g abstract class AbstractOne and abstract class AbstractTwo, you can say:
abstract class AbstractOne extends AbstractTwo {
}
Then add to the main class like this:
class MyMainClass extends AbstractOne {
}
This way, it inherits both AbstractOne and AbstractTwo.