I was reading an article about the new features in PHP 5.4.0.
One of the most anticipated one being Traits.
Reading up on these Traits, to see what they're all about, they simply look as compiler assisted copy-paste to me; and a language provided way to use composition, very much as used in the well-known Strategy Pattern which leverages the 'favor composition over inheritance' design principle.
Am I understanding this correctly?
What other advantages might these traits provide, that makes them worthwhile instead of just using the composition design principle?
No, traits are not simply composition due the fact that the rules by which traits are "pasted" into a class are completely different.
When using Composition, there is no chance for conflicts or methods overwriting because the composite element is a completely isolated unit (an instance of some other class) you interface with via it's public API from within the consuming instance. Also, if you need to provide access from the consuming instance, you'd have to add proxy methods to delegate to the composite element.
Traits on the other hand become part of the API of the very instance they are used in. They are not subsystems in the instance. They are not even instances but just a reusable boilerplate code. One benefit this provides is satisfying interfaces with a trait, as I have shown in Traits in PHP – any real world examples/best practices?
You have to be careful about the meaning you give to composition. In the more general sense, traits are a mechanism for decomposition as well as composition.
Decomposition -- how we decompose a software base into suitable units
of reuse(code re-use, DRY).
Composition -- how we compose these units to obtain a class hierarchy
suitable for our application domain.
Traits are a mechanism for composition in the sense that they can be composed with a class. Many trait implementations would also allow for traits to be composed with one another.
The GoF mantra is "favor composition over inheritance".
All class-based languages by default favor inheritance. Object can only acquire behaviours from their class or from classes higher in their inheritance chain. Sure you can achieve the same outcome in different ways. For instance, you can create a Manager Class (e.g., LayoutMananager) and then add a reference to it in any class that has a layable behavior/layout trait and add function that do nothing but call methods of the Manager
public function doSomething() { return layoutManager.doSomething(); }
Traits favor composition. Simple as that. The key characteristic of traits is that they live outside of the class hierarchy. You can "acquire" re-usable behaviors or traits without them coming from any of your super-class (the horizontal vs vertical distinction introduced in other posts). That's the main advantage.
The biggest issue with traits is the emergence of conflict when traits are implemented in a way that you can directly do myObject.doSomething() instead of myObject.trait1.doSometing() (directly, or indirectly as described above with layoutManager). Once you add more than one trait to a class, conflicts can easily emerge. Your implementation needs to support mechanisms like aliasing and override to help with conflict resolution. You get some overhead back.
It is not clear that the PHP implementation conform to this, but traits are also supposed to not specify any instance variables and the methods provided by traits should never directly access instance variables. (source: Adding Traits to (Statically Typed) Languages, PDF). This blog post discusses this. It claims that in PHP, the structure named trait really is a mixin (that is traits with state). (Though this other blog post describe them as stateless)
All, in all, thinking in terms of traits is likely to help write with better code. Writing your traits classes to avoid instantiation could also contribute to better code. This frees traits from any dependency, making it possible to call them in any order. But it is not clear that adding the concept of trait in the language itself would contribute to better code.
The traits "composition" (it's merely an include on the method level of classes) happens at compile time, whereas the composition you talk about is at runtime.
When you do that composition, the trait has already been there.
As the single inheritance in PHP and as well the often seen static utility classes hinder some design goals, traits offer another facet to shape your implementation and allow to reduce code-duplication.
traits are synonym of behaviour more than inheritance or decoration.
It is not the same thing as strategy pattern because you can define a generic algorithme whereas each concrete strategy object has different algorithm.
Moreover it is more a "horizontal" inheritance of a behaviour than a "vertical" inheritance with a specification of a behaviour.
The question is reallty interesting.
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).
Problem: Implementing fluent interface with many methods yields class complexity metric growing very
fast.
How to keep low complexity for class which implements fluent interface?
Some information about specific class:
Class already has 25 methods and will get another 15-ish more.
All methods in class transform $this->wrapped object in one way or another.
Several (5-7) methods reuses already existing methods (those can be extracted to class and added via inheritance, not issue here).
Already considered options:
Traits - I want to support PHP 5.3 and up.
One class per method - Massive extend chain, not nice.
'Plugins' - helper classes somehow injected into "master class", called via magic methods and autocomplete support added via #method annotation.
Feedback (on design, performance, maintainability, etc.) for any options is highly anticipated.
Checked examples:
Lodash: 170-ish methods, 1 class, 8400 lines
Doctrine2 QueryBuilder: 40+40-ish methods, 2 classes, 1400+600 lines of code;
separated via ExpressionBuilder class
Symfony2 FormBuilder: 10-ish exposed methods, 1 class, 300 lines
Question can be considered language-agnostic - answers both from PHP implementation and design point of view are both equally welcome.
EDIT:
Aim is to have nice (easy to use and easy to maintain) tool for functional programming (map, reduce, etc.)
Complexity is a software metric to indicate lacks of understandings for developer which have to work with. Thus, the higher complexity of a software entity (package/module, class, method) is, the worst maintainable it is. Or in other words, how much time and effort is required to modify and maintain a software entity.
The main types of complexities for classes are:
Cyclomatic-Complexity: Number of decision points in a method, like 'if', 'while', 'for', 'switch'
NPath-Complexity: Number of acyclic execution paths through that method
Too large class length: Indication for class is doing too much
Too large method body: Indication for method is doing too much
Too long method parameter list: Should be grouped by a ValueObject
Too much public methods provided: Indication for broken interchangeability
Too many class fields/properties: Indication for missing nested objects
Number of children by inheritance: Indication for an unbalanced class hierarchy
Depth of inheritance: Indication for an unbalanced/wrong class hierarchy
Coupling between objects: Indication for too many dependencies
All types can be measured by tools and have an angular point, where the complexity is too high. In this case it's a good suspect for refactoring, in order to reduce complexity by using Design Patterns. Another measurement for complexity is, how testable is the class.
How much stubs/mocks i need, how much assertions i need, etc.
How to keep low complexity for class which implements fluent interface?
Fluent Interface is a design pattern for chaining method calls. Chaining at the best looks like real phrases. It aims to provide for more readable code. Thus it's reduce complexity.
Implementing Fluent Interfaces is reached by only adding one new line of code, which only impacts large of method body and large of class length. Thus, fluent interface impacts complexity very low.
Chaining at the best with real phrases can be difficult with growing complexity, but to taggle this it's reacheable by proxy classes, which delegates operations to object without fluent interface.
In general best approach for taggling complexity is to keep single responsibility principle, interface segregation principle, information hiding principle and loose coupling as key aspects.
One approach is to have a simple, reliable base class that provides the tooling methods for implementing the fluent interface class. Then the fluent interface class just calls into the base class for everything it does, reducing the complexity down to the single, fluent interface class.
Do you have a design for your fluent interface already? (I'm wondering just how many of those methods you actually will use.)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
traits in php – any real world examples/best practices?
In what kind of situations would one use Traits in PHP? I do have a pretty good overall idea of this, but I can't seem to think of a way to use them in an application I have written, but that may be because it does not need traits at the time.
One scenario I have realized that needs traits:
Events. Instead of having one class that implements the observer pattern and letting all other classes inheriting it, just make it a trait and let classes that want to fire events or subscribe to use the trait. For example, the Yii framework is doing it wrong by implementing stuff at CComponent class rather than using a Trait.
Basically functionality that can be shared among classes, but may spread along multiple class hierarchies should use traits. What other scenarios could take advantage of Traits than an event system?
The issue that Traits addresses is similar to the one that Java addresses with interfaces - how to enforce common behaviour (as represented by interfaces) among classes that are not in the same class hierarchy.
With languages such as C++ which only have inheritance, for two objects from two different classes to be used in the same context requiring the same behaviour, the two classes had to be from the same hierarchy. This sometimes meant creating quite artificial hierarchies simply to allow objects from different classes to be used in the same context.
Java tackled this problem through interfaces - an interface is essentially a contract governing the provision of behaviour so that an object of one class can be substituted for an object of a separate class because it promises the same behaviour - the interface. But they don't have to be from the same hierarchy.
PHP Traits embody this idea. A trait is a kind of interface, a set of behaviours that a class contains so that it can be used in a context that requires that behaviour. So, any Java interface example should carry over to a PHP Traits example. PHP Traits are a bit different to Java interfaces, though, since Traits can contain full function definitions, whereas Java interfaces can only contain declarations (typical PHP idiosyncrasy!)
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).