Factory Method Design Pattern -PHP - php

I am reading about factory design pattern, this pattern comes in 3 forms, simple factory, factory method and abstract factory.
what I understand, that's simple factory is not a design pattern, it just a type of encapsulate the object creation code in conjunction with if/switch statement or direct loading for the classes with exception if the class not exist!.
When I tried to move to factory method I can't find a clear enough example to defer it from simple factory.
could you guys give an example that's explain the factory method and how its defer from simple factory?
Thank you.

Simple Factory
A simple class with different methods (or one with a switch) that is fully implemented with the creation logic. In PHP it can look like:
class AnimalFactory
{
public function CreateAnimal($type)
{
if ($type == 'Dog') {
return new Dog();
} else {
return new Cat();
}
}
}
If tommorow you'll have a new animal to support, you will have to change this class implementation.
There are no subclasses here - this class knows everything about Animal creation.
Factory Method
Is what you use when you have a class that does some proccessing with Animal but doesn't know how or which Animal to create yet, therfore would like to have subclasses that will determine that. So we create a factory method that the sucblasses can override.
abstract Class MyAnimalProcess
{
abstract function CreateAnimal();
public function Process()
{
$animal = $this->CreateAnimal();
...
...
}
}
class DogProcess extends MyAnimalProcess
{
function CreateAnimal()
{
return new Dog();
}
}
So, here you can have and abstract class that does something with an Animal, but let the subclasses of it determine which Animal it will be.
Abstract Factory
Take the factory method one step forward, and delegates the creation to another class - "the factory" class.
So it uses composition rather than inheritance.
abstract class AnimalFactory
{
public abstract function CreatePet();
public abstract function CreateWildAnimal();
}
class DogAnimalFactory extends AnimalFactory
{
public function CreatePet()
{
return new Dog();
}
public function CreateWildAnimal()
{
return new AfricanWildDog();
}
}
class CatAnimalFactory extends AnimalFactory
{
public function CreatePet()
{
return new Cat();
}
public function CreateWildAnimal()
{
return new Tiger();
}
}
class MyAnimalProcess
{
function __construct($animalFactory) {
$this->factory = $animalFactory;
}
public function ProcessPet()
{
$animal = $this->factory->CreatePet();
...
...
}
public function ProcessWild()
{
$animal = $this->factory->CreateWild();
...
...
}
}

Maybe this will help, to make it more clear,
Abstract Factory is collection of the Factory Methods.
examples from real life:
Factory Method - plasticine/mold
Abstract Factory - cards factory

Related

make a factory of factory

I have two factory:
class Factory
{
public static function getInstance($type) {
.....
}
}
and
class Factory
{
public static function getInstance($type) {
.....
}
}
so, now I want to make an factory of my two factory like this :
class FactoryOfFactory
{
public static function getFactory($service)
{
switch ($service) {
case 'fac1':
$Factory = new Factory();
break;
case 'fac2':
$Factory = new Factory();
}
return $Factory
}
}
so I don't know to differentiate my two factory
thank for help
For a start, your Singleton design should be a trait, not repeated through-out the classes.
trait Singleton
{
private ?object $_instance;
protected function __construct() {}
private function __clone () {}
public static function GetInstance() {
if(($i &= self::$_instance)) return $i;
$i = new self();
return $i;
}
}
Secondly, you cannot require two classes that are within the same namespace. You must declare separate namespaces.
namespace App;
class Factory {
use Singleton;
}
namespace App\Custom;
class Factory {
use Singleton;
}
From here, you can now use them like so:
namespace App;
use App\Custom\Factory as FactoryTwo;
class FactoryOfFactory {
use Singleton;
protected function __construct() {
FactoryTwo::GetInstance();
Factory::GetInstance();
}
}
Use meaningful names.
Factories are generally used (and misused) to initialize complex objects, hiding the creational complexity. They're different from the Builder pattern because a Factory might execute calls to external services before returning a result.
In your example, you should rename the factories based on the domain object they're trying to build. Eg: CustomerRepositoryFactory, OrderFactory and so on.
But before you do that, let me ask you this: why in the world would you need a Factory of a Factory? From your usage of the static keyword, I suppose you're not making use of Dependency Injection. Try to refactor your code in that direction instead.

Call method from another class in a new class - PHP

I'm learning OOP PHP. I want to call a method from another class to a new class.
For just a example:
<?php
class Aclass {
function aMethod($input)
{
echo 'Hello a world ';
}
}
?>
And i want to call the method aMethod from the class 'Aclass' into the new class.
<?php
class Bclass {
//calling the method here?
}
?>
i tried extending , still not working for me.
Thanks.
In your class Bclass you should create some functions. In case below you are creating a new instance of Aclass and then using function aMethod.
Example
<?php
class Bclass {
public function __construct() {
$a = new Aclass();
$a->aMethod("some_text");
}
}
?>
Other way is extend Bclass. In this case your class Bclass extends everything what's in Aclass so you can use it just with $this.
Example
<?php
class Bclass extends Aclass {
public function __construct() {
$this->aMethod("some_text");
}
}
?>
Also your function aMethod in Aclass should have public or protected visibility. Public if you create an instance, protected if you extends. More informations can be found in manuals at the end.
Example
<?php
class Aclass {
public function aMethod($input) // protected if you will extend this class
{
echo 'Hello a world ';
}
}
?>
You can of course use both methods not only in __construct but also in other functions.
Manuals
PHP: Visibility
PHP: Constructors and Destructors
For this I'd use dependency injection. Which is just a fancy way of saying "sending an object of the A class when creating B".
In other words, something like this:
class typeA {
public function __construct () {};
public function test () {
return 'Test string';
}
}
class typeB {
protected $testObj;
public function __construct (typeA $testCase)  {
$this->testObj = $testCase;
}
public function getTest () {
return $this->testObj->test ();
}
}
$a = new typeA ();
$b = new typeB ($a);
echo $b->getTest ();
Constructors are meant to be used to create an object that's ready to be used, which is why I've just stored the dependency inside the typeB object itself. Then, in the getTest() method I invoke the test() method of the object I'm depending upon, in order to get the needed data from it.
Doing it in this manner will allow you to write flexible OOP code, which can easily be expanded and extended as you require. Hiding the dependencies inside the constructors, by creating objects there, creates a hidden and hard dependency. Something which makes it a lot harder, if not down right impossible, to properly leverage the extensible nature of the class-based designs.

Are non-implemented abstract methods a design flaw?

Here is an example of my class structure for a data mapping pattern (simplified). Notice that the save and find methods are technically implemented in the concrete class, but do not do anything yet. What alternatives are there to avoid this? One option I am currently using is an abstract DataMapperAbstract class that implements the interface, throws an exception for every method, then all concrete data mappers only have to implement the functions they use - it just smells bad. Personally, I have thought of creating a separate interface for each method (DataMapper_FindInterface, DataMapper_SaveInterface, DataMapper_DeleteInterface, etc.) but it seems a bit smelly.
interface DataMapperInterface
{
public function find($params);
public function save($object);
public function delete($object);
}
class DataMapper_User implements DataMapperInterface
{
public function find($params)
{
//Execute code to retrieve data from data source
return someDataRetrievalMethod($params);
}
public function save($object)
{
throw new Exception('Method not yet implemented.');
}
public function delete($object)
{
throw new Exception('Method not yet implemented.');
}
}
As long as you are not in the class that has al methods implement, make the class abstract.
Abstract classes can not be instantiated, and there must be another class thats extends the abstract class with a implementation.
So your code so far would look like this:
interface DataMapperInterface
{
public function find($params);
public function save($object);
public function delete($object);
}
abstract class DataMapper_User implements DataMapperInterface
{
public function find($params)
{
//Execute code to retrieve data from data source
return someDataRetrievalMethod($params);
}
}

What's the best way to implement a factory method for an extended class?

Consider the following code:
class Vehicle {
/**
* Create a new instance of Vehicle
*
* #return Vehicle
*/
public static function create(){
return eval( "return new " . get_called_class() . '();' );
// return self(); would always return Vehicle reg ardless
}
public function drive(){
echo "I am a Vehicle!";
}
}
class Bus extends Vehicle {
public function drive(){
parent::drive();
echo "\nSpecifically, a bus!";
}
}
class Car extends Vehicle {
public function drive(){
parent::drive();
echo "\nSpecifically, a car!";
}
}
// Drive a car
Car::create()->drive();
// Drive a bus
Bus::create()->drive();
I've implemented a factory "create" method in the Vehicle class that allows me to get an instance of the class that I want to use.
I tried using "return new self();" but that always returns an instance of Vehicle, so I resorted to using eval.
question: Is there a non-eval way to implement the create() method so that:
it returns an instance of the class you're using
it doesn't require implementing create() on each of the extending classes
Use static instead of self, e.g.
<?php
class Vehicle {
public static function create(){
return new static();
}
public function drive(){
echo "I am a Vehicle!";
}
}
class Bus extends Vehicle {
public function drive(){
parent::drive();
echo "\nSpecifically, a bus!";
}
}
$b = Bus::create();
$b->drive();
prints
I am a Vehicle!
Specifically, a bus!
(VolkerK beat me, but this has a slight variation)
Wait, why do you need to eval() at all? Wouldn't:
public static function create() {
$class = get_called_class();
return new $class();
}
work?
The best way is to move the factory method out of the concrete type and into a factory class of it's own. You can then not only handle this more easily but you can also replace the factory with another factory easily.
I assume you know how inheritance with objects work, so you don't have to deal with anything static which is less straight forward and starts to stand in someones way pretty fast.

Inheritance & method params PHP

Let say I have a PHP Class:
class MyClass {
public function doSomething() {
// do somthing
}
}
and then I extend that class and override the doSomething method
class MyOtherClass extends MyClass {
public function doSomething() {
// do somthing
}
}
Q: Is it bad practice to change, add and or remove method params? e.g:
class MyOtherClass extends MyClass {
public function doSomething($newParam) {
// do somthing
// do something extra with $newParam
}
}
Thanks
In general, yes it is bad design. It breaks the design's adherence to the OOP principle of polymorphism (or at least weakens it)... which means that consumers of the parent interface will not be able to treat instances of your child class exactly as they would be able to treat instances of the parent.
Best thing to do is make a new semantically named method (semantic in this case meaning that it conveys a similar meaning to the original, with some hint as to what the param is for) which either calls the original, or else in your overridden implementation of the original method, call your new one with a sensible default.
class MyOtherClass extends MyClass {
public function doSomething() {
return $this->doSomethingWithOptions(self::$soSomethingDefaultOptions);
}
public function doSomethingWithOptions($optsParam) {
parent::doSomething();
// ...
}
}

Categories