Method Factory with Non Abstract Product - php

I was implementing the Factory Method pattern, but checking several examples out there I couldn't determinate if extending a concrete class for the product instead of creating an abstract class or interface is correct... This is just intended for an example (PHP).
So, I have my abstract factory and their concrete factories:
interface BookFactoryInterface
{
public function createBook();
}
class ElectronicBookFactory implements BookFactoryInterface
{
public function createBook()
{
return new ElectronicBook();
}
}
class PaperBookFactory implements BookFactoryInterface
{
public function createBook()
{
return new PaperBook();
}
}
Now what I have seen in all the examples is that usually products extend from an abstract class or an interface, but when I was testing I realized that in my case there was not need for that, what I was needing is a concrete class with the common behavior and then my subclasses with the rest.
class Book
{
/*
All properties like title, authors, publicationDate
here, with the corresponding methods.
*/
}
class ElectronicBook extends Book
{
//...
}
class PaperBook extends Book
{
//...
}
The class instantiation is still been derived to subclasses, so I really believed this is a Factory Method implementation, but I could find another example code in this way.
So the question: is this still a Factory Method implementation? if not Why?

The need to for abstraction(using interface or abstract class) comes when you need to change the code for creating the concrete objects. This is particularly helpful when situations arises such as while writing unit tests or you need add few more products (or/and) creators.
It is interesting to know that there is difference between factory and factory method. Factories are ways to encapsulate the creation part into a class having a method which takes care of the creation part. On the other hand, Factory Methods are given to "Creators" for creating "Product(s)", which can be decided by the creator. The method to create Product, say createProduct(), is usually inside the Creator, ( induced by using inheritance) and the intention of other methods are usually to work on the product, created by Factory Method.
Now, in both creators and products, we use a parallel sort of hierarchy, so that creator do not depend (or know how the products are created) on Concrete Products and Products also are unaware of creators. This helps in achieving loosely coupled code (here, CHANGE does not impact each other).
Hope this helps.
You can read more at:
https://sourcemaking.com/design_patterns/factory_method
https://en.wikipedia.org/wiki/Dependency_inversion_principle

This is very subjective, but I would argue you don't need any inheritence for it to be a factory method. This would actually suffice to meet the definition:
class Book {
}
class BookFactory {
function createBook() {
return new Book();
}
}

Related

what's the advantage of using factory method pattern over simple factory?

I am reading about factory method pattern and simple factory. turns out As I can understand, simple factory is enough and I don't see the use case of factory method pattern. Please read this link, https://www.binpress.com/factory-design-pattern/ , and I'll ask my questions.
1) in simple factory , it says it's bad because it violates the open/closed principle. I understand that but in factory method pattern what it did still violates the open/closed principle.
if ('car'==$toyName) {
$toy = new NyCar();
} else if ('helicopter'==$toyName) {
$toy = new NyHelicopter();
}
If there'll be a new tory for New York, we need to add it here.
2) after reading the link, before it actually reached the better solution, it used this following code. :
class NySimpleFactory {
public function createToy($toyName) {
$toy = null;
if ('car'==$toyName) {
$toy = new NyCar();
} else if ('helicopter'==$toyName) {
$toy = new NyHelicopter();
}
return $toy;
}
}
class NyToysFactory {
public $simpleFactory;
public function __construct(SimpleFactory $simpleFactory) {
$this->simpleFactory = $simpleFactory;
}
public function produceToy($toyName) {
$toy = null;
$toy = $this->simpleFactory->createToy($toyName);
$toy->prepare();
$toy->package();
$toy->label();
return $toy;
}
}
Then it says,
The developers finish the new code quickly and hand it over to the US
factories. After two weeks, the phone starts ringing in the
developers’ office because the New York factory was having production
issues. It turns out that the NyToysFactory class has been modified by
developers at the remote branch because the staff doesn’t want to do
packaging and labeling work. They’ve modified produceToy() by removing
its label() and package() functions.
It seems like Simple Factory won’t work in this scenario. We don’t
want branches in US to be able to modify produceToy() functions.
ProduceToy() should consist of a set of standard procedures and the
branches should only be responsible for creating location specific
toys. What if they can create an abstract class? And the abstract
class they create will have a concrete produceToy()method which will
implement a set of standard operating procedurea that all branches
have to follow. Inside produceToy(), it calls its own abstract method
createToy() to obtain a toy class. This way createToy() is able to
encapsulate object creation and, since it’s abstract, it delegates the
creation to its subclasses.
Question is: a)What does it mean by saying handing over it to US factories? b) or We don’t want branches in US to be able to modify produceToy() functions. they can still modify produceToy function, what difference does it make at all if they can't or can change it? I just don't understand why simple factory was bad for the following example at all.
No need to read about abstract factory at that link
THIS CODE / PROBLEM does not illuminate the Abstract Factory or Factory Method. Deciding which class to instantiate by switching on a parameter is indeed an anti-pattern encouraging open-closed principle violation.
Abstract Factory
The Abstract Factory is all about enforcing a family of related classes:
abstract class ToyFactory
+ createBear(): ToyBear
+ createElephant(): ToyElephant
class USToyFactory extends ToyFactory
+ createBear(): ToyBear -> creates USToyBear
+ createElephant(): ToyElephant -> USToyElephant
abstract class ToyBear
+ playSound()
class USToyBear extends ToyBear
+ playSound()//play US National Anthem
Passing a USToyFactory where a ToyFactory is expected enforces the creation of US toys (USToyBear and USToyElephant) – this is the power of Abstract Factory.
Notice the products, bears, elephants, etc., are known AoT (ahead of time).
Factory Method
The Factory Method is all about deferring instantiation to subclasses.
abstract class Dashboard
+ createWidget(): Widget
abstract class Widget
+ config()
class StatsDashboard extends Dashboard
+ createWidget: Widget -> return new StatsWidget()
class StatsWidget extends Widget
Calling createWidget() returns a Widget, but which concrete Widget to return must be deferred to subclasses (StatsDashboard returns a StatsWidget).
Notice the creation methods are declared up the inheritance tree, but they are fulfilled down the inheritance tree.
❧ A reader with a keen eye will see that Abstract Factory methods resemble Factory Methods, coincidence? – no. This is where Factory Method’s name is derived (they fulfill concrete class instantiation).
The confusion regarding “US factories” is valid; this is poor word choice. The author hints this code may be passed around to factory workers which is totally irrelevant and confusing pertaining to the factory patterns.
To resolve the switch above, you'll need to realize the obvious: each condition handler is related in some way. In this case, they are all toys.
public function createToy($toyName) {
$toy = null;
if ('car'==$toyName) {
$toy = new NyCar();//I'm a Toy
} else if ('helicopter'==$toyName) {
$toy = new NyHelicopter();//I'm a Toy
}
return $toy;
}
Using polymorphism, we can satisfy the open-closed principle by creating a set of sibling classes:
abstract class Toy
+ operate()
Car extends Toy
Helicopter extends Toy
some_toy.operate();
Adding to the switch cases is nothing more than creating another sibling class.
I hope this helps!

Factory Design Pattern Explanation

In most factory's pattern explanation topics, we are told that factories are needed to refuse using new for for instantiating objects. Instead it we need to instantiate factories with new, that do new for concrete objects for us.
But why? In that case we just have excess middle class.
For example here
In my code I use this way. Is it factory? Is it right way?
<?php
abstract class CarAbstract
{
abstract public function makeSignal();
public static function factory($type)
{
switch($type) {
'automobile':
return new AutoCar();
break;
'truck':
return new TruckCar();
break;
}
}
}
class AutoCar extends CarAbstract {
public function makeSignal()
{
return 'beep-beep';
}
}
class TruckCar extends CarAbstract {
public function makeSignal()
{
return 'faa-faa';
}
}
$auto = CarAbstract::factory('automobile');
$truck = CarAbstract::factory('truck');
$auto->makeSignal(); // beep-beep
$truck->makeSignal(); // faa-faa
P.S.
Excuse me for my english
The Wikipedia page you link to explains why:
The Factory Method design pattern solves problems like:
How can an object be created so that subclasses can redefine which class to instantiate?
How can a class defer instantiation to subclasses?
Personally the most useful situation I have found in PHP for factories is when implementing libraries. This is a matter of opinion, but I find factories to usually be excessive inside the core of my PHP applications. But when writing a library to be used by multiple applications it allows a lot more flexibility in providing specific implementations.
The example you provide will work but is not the best way to implement the pattern. It's usually better to make a concrete factory class which you instantiate. Or even better an interface which you then implement. Then it's more useful and easier to unit test.
The factory pattern is useful when the actual type of the object is determined dynamically.
$carType = $_POST['type'];
$cat = CarAbstract::factory($carType);
This allows you to implement the switch statement once in the base class, rather than having to code it in all the applications that use these classes. And if you add more subclasses, you just update that one switch statement, rather than having to find all the callers.

Organizing classes and properties in PHP - the right way?

Please help me. I need a better understanding PHP OOP principles.
If I have a class property which is immutable for all of the class instances it should be defined as static?
If so, is there a way to be sure that static properties are defined in all classes of that type? As I read in PHP manual, static properties cannot be controller neither by the interface nor by abstract classes? Or am I wrong?
Simple example.
<?php
// Parent class
abstract class Employee
{
abstract public function getAlias();
}
// Child classes
class Manager extends Employee
{
public function getAlias()
{
return 'manager';
}
}
class Security extends Employee
{
public function getAlias()
{
return 'security';
}
}
Tell me, where an alias property should be placed?
I have to be sure that any Employee descendants that will be created in future will have that property defined. Is it OK to keep that kind of properties in dynamic methods? Or they should be placed in constants, static methods or static properties?
Actually the current version is quite ok (if considered with no context) because it makes for a cleaner code, since it closer matches principle of least astonishment. Technically, you could rewrite it as this (but that would actually make it worse code):
abstract class Employee {
public function getAlias() {
return $this->alias;
}
}
class Manager extends Employee {
protected $alias = 'mngr';
}
$user = new Manager;
echo $user->getAlias();
Live code: https://3v4l.org/sjVOT
The more important aspect is the purpose of this code. You mentioned, that you would want to use something like this for dealing with single-table inheritance, but here is the important part:
Your domain entities should not be aware of how your persistence layer works.
And pulling structural information from the domain layer for use in some query-builder is a terrible idea. I would recommend for you to instead looks at data mapper pattern (you probably should actually read the PoEAA book).
Your domain entities should not know any details about how (or even "if") they is being saved or restored.

unit tests and object-inheritance

I have a question concerning "unit tests" and object-inheritance. For example:
I have a class A which extends class B. Let's assume the only difference of the two classes is the add method . In class B this add method is slightly extended. Now I want to write a unit test for the add function of class B but because of the parent::add call I have a dependency to the parent class A. In this case I can't mock the add method of the parent class so the resulting test will be a integration test but if I want it to be a unit test? I don't want the the test for method add in class B fails because of the parent method in class A. In this case only the unit-test of the parent method should fail.
class B exends A
{
public function add($item)
{
parent::add($item);
//do some additional stuff
}
....
}
class A
{
protected $items = [];
public function add($item)
{
$this->items[] = $item;
}
....
}
Surely I could use object-aggregation and pass my parent object to the child contructor and therefore I would be able to mock the parent method add, but is this the best approach? I would rarely use object-inheritance anymore.
class B
{
protected $a;
public function __contruct(A $a)
{
$this->a = $a;
}
public function add($item)
{
$this->a->add($item);
//do some additional stuff
}
....
}
class A
{
protected $items = [];
public function add($item)
{
$this->items[] = $item;
}
....
}
I would be very grateful for your opinions. Thanks!
Ask yourself, what kind of inheritance do you want to achieve? If B is a kind of A, then you're wanting interface inheritance. If B shares a lot of code with A, then you're wanting implementation inheritance. Sometimes you want both.
Interface inheritance classifies semantic meaning into a strict hierarchy, with that meaning organized from generalized to specialized. Think taxonomy. The interface (method signatures) represent the behaviors: both the set of messages to which the class responds, as well as the set of messages that the class sends. When inheriting from a class, you implicitly accept responsibility for all messages the superclass sends on your behalf, not just the messages that it can receive. For this reason, the coupling between super- and sub-class is tight and each must strictly substitute for the other (see Liskov Substitution Principle).
Implementation inheritance encapsulates the mechanics of data representation and behavior (properties and methods) into a convenient package for reuse and enhancement by sub-classes. By definition, a sub-class inherits the interface of the parent even if it only wants the implementation.
That last part is crucial. Read it again: Sub-classes inherit the interface even if they only want the implementation.
Does B strictly require the interface of A? Can B substitute for A, in all cases matching co-variance and contra-varience?
If the answer is yes, then you have true sub-typing. Congratulations. Now you must test the same behaviors twice, because in B you are responsible for maintaining the behaviors of A: for every thing A can do, B must be able to do.
If the answer is no, then you merely need to share the implementation, test that the implementation works, then test that B and A separately dispatch into the implementation.
In practical terms, I avoid extends. When I want implementation inheritance, I use trait to define static behaviors † in one place, then use to incorporate it where needed. When I want interface inheritance, I define many narrow interface then combine with implements in all the concrete types, possibly using trait to leverage behavior.
For your example, I'd do this:
trait Container {
public function add($item) { $this->items[] = $item; }
public function getItems() { return $this->items; }
private $items = [];
}
interface Containable { public function add($item); }
class A implements Containable { use Container; }
class B implements Containable {
use Container { Container::add as c_add; }
public function add($item) {
$this->c_add($item);
$this->mutate($item);
}
public function mutate($item) { /* custom stuff */ }
}
Container::add and B::mutate would have unit tests, while B::add would have an integration test.
In summary, favor composition over inheritance because extends is evil. Read the ThoughtWorks primer Composition vs. Inheritance: How To Choose to gain a deeper understanding of the design trade-offs.
† "static behaviors", you ask? Yes. Low-coupling is a goal and this goes for traits. As much as possible, a trait should reference only variables it defines. The safest way to enforce that is with static methods that take all their input as formal arguments. The easiest way is to define member variables in the trait. (But, please, avoid having traits use member variables that are not clearly defined in the trait -- otherwise, that's blind coupling!) The problem, I find, with trait member variables is that when mixing in multiple traits you increase the chance of collision. This is, admittedly, small, but it is a practical consider for library authors.

Traits vs. interfaces

I've been trying to study up on PHP lately, and I find myself getting hung up on traits. I understand the concept of horizontal code reuse and not wanting to necessarily inherit from an abstract class. What I don't understand is: What is the crucial difference between using traits versus interfaces?
I've tried searching for a decent blog post or article explaining when to use one or the other, but the examples I've found so far seem so similar as to be identical.
Public Service Announcement:
I want to state for the record that I believe traits are almost always a code smell and should be avoided in favor of composition. It's my opinion that single inheritance is frequently abused to the point of being an anti-pattern and multiple inheritance only compounds this problem. You'll be much better served in most cases by favoring composition over inheritance (be it single or multiple). If you're still interested in traits and their relationship to interfaces, read on ...
Let's start by saying this:
Object-Oriented Programming (OOP) can be a difficult paradigm to grasp.
Just because you're using classes doesn't mean your code is
Object-Oriented (OO).
To write OO code you need to understand that OOP is really about the capabilities of your objects. You've got to think about classes in terms of what they can do instead of what they actually do. This is in stark contrast to traditional procedural programming where the focus is on making a bit of code "do something."
If OOP code is about planning and design, an interface is the blueprint and an object is the fully constructed house. Meanwhile, traits are simply a way to help build the house laid out by the blueprint (the interface).
Interfaces
So, why should we use interfaces? Quite simply, interfaces make our code less brittle. If you doubt this statement, ask anyone who's been forced to maintain legacy code that wasn't written against interfaces.
The interface is a contract between the programmer and his/her code. The interface says, "As long as you play by my rules you can implement me however you like and I promise I won't break your other code."
So as an example, consider a real-world scenario (no cars or widgets):
You want to implement a caching system for a web application to cut
down on server load
You start out by writing a class to cache request responses using APC:
class ApcCacher
{
public function fetch($key) {
return apc_fetch($key);
}
public function store($key, $data) {
return apc_store($key, $data);
}
public function delete($key) {
return apc_delete($key);
}
}
Then, in your HTTP response object, you check for a cache hit before doing all the work to generate the actual response:
class Controller
{
protected $req;
protected $resp;
protected $cacher;
public function __construct(Request $req, Response $resp, ApcCacher $cacher=NULL) {
$this->req = $req;
$this->resp = $resp;
$this->cacher = $cacher;
$this->buildResponse();
}
public function buildResponse() {
if (NULL !== $this->cacher && $response = $this->cacher->fetch($this->req->uri()) {
$this->resp = $response;
} else {
// Build the response manually
}
}
public function getResponse() {
return $this->resp;
}
}
This approach works great. But maybe a few weeks later you decide you want to use a file-based cache system instead of APC. Now you have to change your controller code because you've programmed your controller to work with the functionality of the ApcCacher class rather than to an interface that expresses the capabilities of the ApcCacher class. Let's say instead of the above you had made the Controller class reliant on a CacherInterface instead of the concrete ApcCacher like so:
// Your controller's constructor using the interface as a dependency
public function __construct(Request $req, Response $resp, CacherInterface $cacher=NULL)
To go along with that you define your interface like so:
interface CacherInterface
{
public function fetch($key);
public function store($key, $data);
public function delete($key);
}
In turn you have both your ApcCacher and your new FileCacher classes implement the CacherInterface and you program your Controller class to use the capabilities required by the interface.
This example (hopefully) demonstrates how programming to an interface allows you to change the internal implementation of your classes without worrying if the changes will break your other code.
Traits
Traits, on the other hand, are simply a method for re-using code. Interfaces should not be thought of as a mutually exclusive alternative to traits. In fact, creating traits that fulfill the capabilities required by an interface is the ideal use case.
You should only use traits when multiple classes share the same functionality (likely dictated by the same interface). There's no sense in using a trait to provide functionality for a single class: that only obfuscates what the class does and a better design would move the trait's functionality into the relevant class.
Consider the following trait implementation:
interface Person
{
public function greet();
public function eat($food);
}
trait EatingTrait
{
public function eat($food)
{
$this->putInMouth($food);
}
private function putInMouth($food)
{
// Digest delicious food
}
}
class NicePerson implements Person
{
use EatingTrait;
public function greet()
{
echo 'Good day, good sir!';
}
}
class MeanPerson implements Person
{
use EatingTrait;
public function greet()
{
echo 'Your mother was a hamster!';
}
}
A more concrete example: imagine both your FileCacher and your ApcCacher from the interface discussion use the same method to determine whether a cache entry is stale and should be deleted (obviously this isn't the case in real life, but go with it). You could write a trait and allow both classes to use it to for the common interface requirement.
One final word of caution: be careful not to go overboard with traits. Often traits are used as a crutch for poor design when unique class implementations would suffice. You should limit traits to fulfilling interface requirements for best code design.
An interface defines a set of methods that the implementing class must implement.
When a trait is use'd the implementations of the methods come along too--which doesn't happen in an Interface.
That is the biggest difference.
From the Horizontal Reuse for PHP RFC:
Traits is 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.
A trait is essentially PHP's implementation of a mixin, and is effectively a set of extension methods which can be added to any class through the addition of the trait. The methods then become part of that class' implementation, but without using inheritance.
From the PHP Manual (emphasis mine):
Traits are a mechanism for code reuse in single inheritance languages such as PHP. ... It is an addition to traditional inheritance and enables horizontal composition of behavior; that is, the application of class members without requiring inheritance.
An example:
trait myTrait {
function foo() { return "Foo!"; }
function bar() { return "Bar!"; }
}
With the above trait defined, I can now do the following:
class MyClass extends SomeBaseClass {
use myTrait; // Inclusion of the trait myTrait
}
At this point, when I create an instance of class MyClass, it has two methods, called foo() and bar() - which come from myTrait. And - notice that the trait-defined methods already have a method body - which an Interface-defined method can't.
Additionally - PHP, like many other languages, uses a single inheritance model - meaning that a class can derive from multiple interfaces, but not multiple classes. However, a PHP class can have multiple trait inclusions - which allows the programmer to include reusable pieces - as they might if including multiple base classes.
A few things to note:
-----------------------------------------------
| Interface | Base Class | Trait |
===============================================
> 1 per class | Yes | No | Yes |
---------------------------------------------------------------------
Define Method Body | No | Yes | Yes |
---------------------------------------------------------------------
Polymorphism | Yes | Yes | No |
---------------------------------------------------------------------
Polymorphism:
In the earlier example, where MyClass extends SomeBaseClass, MyClass is an instance of SomeBaseClass. In other words, an array such as SomeBaseClass[] bases can contain instances of MyClass. Similarly, if MyClass extended IBaseInterface, an array of IBaseInterface[] bases could contain instances of MyClass. There is no such polymorphic construct available with a trait - because a trait is essentially just code which is copied for the programmer's convenience into each class which uses it.
Precedence:
As described in the Manual:
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in return override inherited methods.
So - consider the following scenario:
class BaseClass {
function SomeMethod() { /* Do stuff here */ }
}
interface IBase {
function SomeMethod();
}
trait myTrait {
function SomeMethod() { /* Do different stuff here */ }
}
class MyClass extends BaseClass implements IBase {
use myTrait;
function SomeMethod() { /* Do a third thing */ }
}
When creating an instance of MyClass, above, the following occurs:
The Interface IBase requires a parameterless function called SomeMethod() to be provided.
The base class BaseClass provides an implementation of this method - satisfying the need.
The trait myTrait provides a parameterless function called SomeMethod() as well, which takes precedence over the BaseClass-version
The class MyClass provides its own version of SomeMethod() - which takes precedence over the trait-version.
Conclusion
An Interface can not provide a default implementation of a method body, while a trait can.
An Interface is a polymorphic, inherited construct - while a trait is not.
Multiple Interfaces can be used in the same class, and so can multiple traits.
I think traits are useful to create classes that contain methods that can be used as methods of several different classes.
For example:
trait ToolKit
{
public $errors = array();
public function error($msg)
{
$this->errors[] = $msg;
return false;
}
}
You can have and use this "error" method in any class that uses this trait.
class Something
{
use Toolkit;
public function do_something($zipcode)
{
if (preg_match('/^[0-9]{5}$/', $zipcode) !== 1)
return $this->error('Invalid zipcode.');
// do something here
}
}
While with interfaces you can only declare the method signature, but not its functions' code. Also, to use an interface you need to follow a hierarchy, using implements. This is not the case with traits.
It is completely different!
For beginners above answer might be difficult, this is the easiest way to understand it:
Traits
trait SayWorld {
public function sayHello() {
echo 'World!';
}
}
so if you want to have sayHello function in other classes without re-creating the whole function you can use traits,
class MyClass{
use SayWorld;
}
$o = new MyClass();
$o->sayHello();
Cool right!
Not only functions you can use anything in the trait(function, variables, const...). Also, you can use multiple traits: use SayWorld, AnotherTraits;
Interface
interface SayWorld {
public function sayHello();
}
class MyClass implements SayWorld {
public function sayHello() {
echo 'World!';
}
}
So this is how interfaces differ from traits: You have to re-create everything in the interface in an implemented class. Interfaces don't have an implementation and interfaces can only have functions and constants, it cannot have variables.
I hope this helps!
Traits are simply for code reuse.
Interface just provides the signature of the functions that is to be defined in the class where it can be used depending on the programmer's discretion. Thus giving us a prototype for a group of classes.
For reference-
http://www.php.net/manual/en/language.oop5.traits.php
An often-used metaphor to describe Traits is Traits are interfaces with implementation.
This is a good way of thinking about it in most circumstances, but there are a number of subtle differences between the two.
For a start, the instanceof operator will not work with traits (ie, a trait is not a real object), therefore you can't use that to see if a class has a certain trait (or to see if two otherwise unrelated classes share a trait). That's what they mean by it being a construct for horizontal code re-use.
There are functions now in PHP that will let you get a list of all the traits a class uses, but trait-inheritance means you'll need to do recursive checks to reliably check if a class at some point has a specific trait (there's example code on the PHP doco pages). But yeah, it's certainly not as simple and clean as instanceof is, and IMHO it's a feature that would make PHP better.
Also, abstract classes are still classes, so they don't solve multiple-inheritance related code re-use problems. Remember you can only extend one class (real or abstract) but implement multiple interfaces.
I've found traits and interfaces are really good to use hand in hand to create pseudo multiple inheritance. Eg:
class SlidingDoor extends Door implements IKeyed
{
use KeyedTrait;
[...] // Generally not a lot else goes here since it's all in the trait
}
Doing this means you can use instanceof to determine if the particular Door object is Keyed or not, you know you'll get a consistent set of methods, etc, and all the code is in one place across all the classes that use the KeyedTrait.
You can consider a trait as an automated "copy-paste" of code, basically.
Using traits is dangerous since there is no mean to know what it does before execution.
However, traits are more flexible because of their lack of limitations such as inheritance.
Traits can be useful to inject a method which checks something into a class, for example, the existence of another method or attribute. A nice article on that (but in French, sorry).
For French-reading people who can get it, the GNU/Linux Magazine HS 54 has an article on this subject.
If you know English and know what trait means, it is exactly what the name says. It is a class-less pack of methods and properties you attach to existing classes by typing use.
Basically, you could compare it to a single variable. Closures functions can use these variables from outside of the scope and that way they have the value inside. They are powerful and can be used in everything. Same happens to traits if they are being used.
Other answers did a great job of explaining differences between interfaces and traits. I will focus on a useful real world example, in particular one which demonstrates that traits can use instance variables - allowing you add behavior to a class with minimal boilerplate code.
Again, like mentioned by others, traits pair well with interfaces, allowing the interface to specify the behavior contract, and the trait to fulfill the implementation.
Adding event publish / subscribe capabilities to a class can be a common scenario in some code bases. There's 3 common solutions:
Define a base class with event pub/sub code, and then classes which want to offer events can extend it in order to gain the capabilities.
Define a class with event pub/sub code, and then other classes which want to offer events can use it via composition, defining their own methods to wrap the composed object, proxying the method calls to it.
Define a trait with event pub/sub code, and then other classes which want to offer events can use the trait, aka import it, to gain the capabilities.
How well does each work?
#1 Doesn't work well. It would, until the day you realize you can't extend the base class because you're already extending something else. I won't show an example of this because it should be obvious how limiting it is to use inheritance like this.
#2 & #3 both work well. I'll show an example which highlights some differences.
First, some code that will be the same between both examples:
An interface
interface Observable {
function addEventListener($eventName, callable $listener);
function removeEventListener($eventName, callable $listener);
function removeAllEventListeners($eventName);
}
And some code to demonstrate usage:
$auction = new Auction();
// Add a listener, so we know when we get a bid.
$auction->addEventListener('bid', function($bidderName, $bidAmount){
echo "Got a bid of $bidAmount from $bidderName\n";
});
// Mock some bids.
foreach (['Moe', 'Curly', 'Larry'] as $name) {
$auction->addBid($name, rand());
}
Ok, now lets show how the implementation of the Auction class will differ when using traits.
First, here's how #2 (using composition) would look like:
class EventEmitter {
private $eventListenersByName = [];
function addEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName][] = $listener;
}
function removeEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName] = array_filter($this->eventListenersByName[$eventName], function($existingListener) use ($listener) {
return $existingListener === $listener;
});
}
function removeAllEventListeners($eventName) {
$this->eventListenersByName[$eventName] = [];
}
function triggerEvent($eventName, array $eventArgs) {
foreach ($this->eventListenersByName[$eventName] as $listener) {
call_user_func_array($listener, $eventArgs);
}
}
}
class Auction implements Observable {
private $eventEmitter;
public function __construct() {
$this->eventEmitter = new EventEmitter();
}
function addBid($bidderName, $bidAmount) {
$this->eventEmitter->triggerEvent('bid', [$bidderName, $bidAmount]);
}
function addEventListener($eventName, callable $listener) {
$this->eventEmitter->addEventListener($eventName, $listener);
}
function removeEventListener($eventName, callable $listener) {
$this->eventEmitter->removeEventListener($eventName, $listener);
}
function removeAllEventListeners($eventName) {
$this->eventEmitter->removeAllEventListeners($eventName);
}
}
Here's how #3 (traits) would look like:
trait EventEmitterTrait {
private $eventListenersByName = [];
function addEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName][] = $listener;
}
function removeEventListener($eventName, callable $listener) {
$this->eventListenersByName[$eventName] = array_filter($this->eventListenersByName[$eventName], function($existingListener) use ($listener) {
return $existingListener === $listener;
});
}
function removeAllEventListeners($eventName) {
$this->eventListenersByName[$eventName] = [];
}
protected function triggerEvent($eventName, array $eventArgs) {
foreach ($this->eventListenersByName[$eventName] as $listener) {
call_user_func_array($listener, $eventArgs);
}
}
}
class Auction implements Observable {
use EventEmitterTrait;
function addBid($bidderName, $bidAmount) {
$this->triggerEvent('bid', [$bidderName, $bidAmount]);
}
}
Note that the code inside the EventEmitterTrait is exactly the same as what's inside the EventEmitter class except the trait declares the triggerEvent() method as protected. So, the only difference you need to look at is the implementation of the Auction class.
And the difference is large. When using composition, we get a great solution, allowing us to reuse our EventEmitter by as many classes as we like. But, the main drawback is the we have a lot of boilerplate code that we need to write and maintain because for each method defined in the Observable interface, we need to implement it and write boring boilerplate code that just forwards the arguments onto the corresponding method in our composed the EventEmitter object. Using the trait in this example lets us avoid that, helping us reduce boilerplate code and improve maintainability.
However, there may be times where you don't want your Auction class to implement the full Observable interface - maybe you only want to expose 1 or 2 methods, or maybe even none at all so that you can define your own method signatures. In such a case, you might still prefer the composition method.
But, the trait is very compelling in most scenarios, especially if the interface has lots of methods, which causes you to write lots of boilerplate.
* You could actually kinda do both - define the EventEmitter class in case you ever want to use it compositionally, and define the EventEmitterTrait trait too, using the EventEmitter class implementation inside the trait :)
The main difference is that, with interfaces, you must define the actual implementation of each method within each class that implements said interface, so you can have many classes implement the same interface but with different behavior, while traits are just chunks of code injected in a class; another important difference is that trait methods can only be class-methods or static-methods, unlike interface methods which can also (and usually are) be instance methods.
The trait is same as a class we can use for multiple inheritance purposes and also code reusability.
We can use trait inside the class and also we can use multiple traits in the same class with 'use keyword'.
The interface is using for code reusability same as a trait
the interface is extend multiple interfaces so we can solve the multiple inheritance problems but when we implement the interface then we should create all the methods inside the class.
For more info click below link:
http://php.net/manual/en/language.oop5.traits.php
http://php.net/manual/en/language.oop5.interfaces.php
An interface is a contract that says “this object is able to do this thing”, whereas a trait is giving the object the ability to do the thing.
A trait is essentially a way to “copy and paste” code between classes.
Try reading this article, What are PHP traits?

Categories