make a factory of factory - php

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.

Related

PHP Traits: How to circumvenient constructors or force them to be called?

Have a look at the following trait:
trait PrimaryModelRest {
use RestController;
protected $primaryModel;
public function __construct() {
$mc = $this->getPrimaryModelClass();
try {
$this->primaryModel = new $mc();
if(!($this->primaryModel instanceof Model)) {
throw new ClassNotFoundException("Primary Model fatal exception: The given Class is not an instance of Illuminate\Database\Eloquent\Model");
}
} catch (Exception $e) {
throw new WrongImplementationException("Primary Model Exception: Class not found.");
}
}
/**
* #return string: Classname of the primary model.
*/
public abstract function getPrimaryModelClass();
// various functions here
}
As you can see the trait makes sure that the using class holds a certain model instance and it implements certain methods. This works as long as the implementing class does not override the constructor.
So here is my question: I want to make sure that either the constructor is called or a better solution, such that I can instantiate this model on initialization.
Please make in answer which respects Multiple inheritance as well es Multi-Level inheritance.
I think you are trying to make the trait do a job it is not designed for.
Traits are not a form of multiple inheritance, but rather "horizontal reuse" - they're often described as "compiler-assisted copy-and-paste". As such, the job of a trait is to provide some code, so that you don't have to copy it into the class manually. The only relationship it has is with the class where the use statement occurs, where the code is "pasted". To aid in this role, it can make some basic requirements of that target class, but after that, the trait takes no part in inheritance.
In your example, you are concerned that a sub-class might try to access $primaryModel without running the constructor code which initialises it, and you are trying to use the trait to enforce that; but this is not actually the trait's responsibility.
The following definitions of class Sub are completely equivalent:
trait Test {
public function foo() {
echo 'Hello, World!';
}
}
class ParentWithTrait {
use Test;
}
class Sub inherits ParentWithTrait {
}
vs:
class ParentWithMethodDefinition {
public function foo() {
echo 'Hello, World!';
}
}
class Sub inherits ParentWithMethodDefinition {
}
In either case, class Sub could have its own definition of foo(), and by-pass the logic you'd written in the parent class.
The only contract that can prevent that is the final keyword, which in your case would mean marking your constructor as final. You can then provide an extension point that can be overridden for sub-classes to add their own initialisation:
class Base {
final public function __construct() {
important_things(); // Always run this!
$this->onConstruct(); // Extension point
}
protected function onConstruct() {
// empty default definition
}
}
class Sub {
protected function onConstruct() {
stuff_for_sub(); // Runs after mandatory important_things()
}
}
A trait can also mark its constructor as final, but this is part of the code being pasted, not a requirement on the class using the trait. You could actually use a trait with a constructor, but then write a new constructor as well, and it would mask the trait's version completely:
trait Test {
final public function __construct() {
echo "Trait Constructor";
}
}
class Noisy {
use Test;
}
class Silent {
use Test;
public function __construct() {
// Nothing
}
}
As far as the trait is concerned, this is like buying a bottle of beer and pouring it down the sink: you asked for its code and didn't use it, but that's your problem.
Crucially, though, you can also alias the methods of the trait, creating a new method with the same code but a different name and/or a different visibility. This means you can mix in code from traits which declare constructors, and use that code in a more complex constructor, or somewhere else in the class altogether.
The target class might also use the "final + hook" pattern:
trait TestOne {
final public function __construct() {
echo "Trait TestOne Constructor\n";
}
}
trait TestTwo {
final public function __construct() {
echo "Trait TestTwo Constructor\n";
}
}
class Mixed {
final public function __construct() {
echo "Beginning\n";
$this->testOneConstructor();
echo "Middle\n";
$this->testTwoConstructor();
echo "After Traits\n";
$this->onConstruct();
echo "After Sub-Class Hook\n";
}
use TestOne { __construct as private testOneConstructor; }
use TestTwo { __construct as private testTwoConstructor; }
protected function onConstruct() {
echo "Default hook\n";
}
}
class ChildOfMixed extends Mixed {
protected function onConstruct() {
echo "Child hook\n";
}
}
The trait hasn't forced the Mixed class to implement this pattern, but it has enabled it, in keeping with its purpose of facilitating code reuse.
Interestingly, the below code doesn't work, because the as keyword adds an alias, rather than renaming the normal method, so this ends up trying to override the final constructor from Mixed:
class ChildOfMixed extends Mixed {
use TestTwo { __construct as private testTwoConstructor; }
protected function onConstruct() {
$this->testTwoConstructor();
echo "Child hook\n";
}
}
Use a base class, this will let you handle the trait as a parent.
<?php
trait StorageTrait
{
public function __construct()
{
echo "Storage Trait";
}
}
class StorageAttempt
{
use StorageTrait;
public function __construct()
{
parent::__construct();
echo " - Storage Attempt";
}
}
abstract class StorageBase
{
use StorageTrait;
}
class MyStorage extends StorageBase
{
public function __construct()
{
parent::__construct();
echo ' - My Storage';
}
}
new StorageAttempt(); // won't work - will trigger error
new MyStorage(); // will display "Storage Trait - My Storage"
Also if you are using traits you can also work with properties and getters & setters.
Example: A Storage trait involves that a Storage Engine will be used. You can add the storageEngine property and its getters and setters. (with or without Type Hinting)
interface StorageEngineInterface{}
trait StorageTrait
{
/**
* #var StorageEngineInterface
*/
protected $storageEngine;
/**
* #return StorageEngineInterface
*/
public function getStorageEngine(): StorageEngineInterface
{
return $this->storageEngine;
}
/**
* #param StorageEngineInterface $storageEngine
*/
public function setStorageEngine(StorageEngineInterface $storageEngine)
{
$this->storageEngine = $storageEngine;
return $this;
}
}
Note: this is just an explanation so you can better understand how Traits work
UPDATE
To avoid conflict you can use aliases for trait methods. This way you can use both constructors (from trait and from extended class) you can do the following
class DifferentStorage
{
public function __construct()
{
echo ' diff ';
}
}
class MyDifferentStorage extends DifferentStorage
{
use StorageTrait {
StorageTrait::__construct as otherConstructor;
}
public function __construct()
{
parent::__construct();
self::otherConstructor();
}
}
You could use the interface injection pattern: implement an interface iPrimaryModelRest into the same class that uses the trait PrimaryModelRest:
interface iPrimaryModelRest {
public function init();
public abstract function getPrimaryModelClass();
}
The class that uses the trait woud look like this:
class cMyClass implements iPrimaryModelRest {
use PrimaryModelRest;
}
Then, whenever the class is instantiated (not only autoloaded) you could call a special factory-like initialisation function like this:
class cMyApp {
public function start() {
/** #var cMyClass $oClass */ // enlighten IDE
$oClass = $this->init(new cMyClass);
}
public function init($oClass) {
if ($oClass instanceof iPrimaryModelRest) {$oClass->init();}
if ($oClass instanceof whateverinterface) {
// pass optional stuff, like database connection
}
}
}
The interface is used to determine the capabilities of the class, and sets data/runs corresponding functions. If I'm not mistaken then this pattern is called a Service Locator.
I needed a trait for database connection. To avoid using the __construct in a trait, I've used a magic getter instead:
trait WithDatabaseConnection
{
public function __get(string $name)
{
if ($name === 'pdo') {
return App::make(\PDO::class);
}
trigger_error("Property $name does not exist.");
return null;
}
}
class Foo {
use WithDatabaseConnection;
public function save() {
$this->pdo->query('...');
}
}

What's the difference between Laravel automatic injection and manually specifying the dependencies in the constructor body?

I'm using a Repository pattern in my Laravel project. This pattern is not really explained in the official documentation, except for this snippet:
You may type-hint a repository defined by your application in a controller's constructor. The repository will automatically be resolved and injected into the class.
This is my code, in accordance with the documentation:
class CategoriesController extends Controller
{
protected $repo;
public function __construct(CategoriesRepository $repo)
{
$this->repo = $repo;
}
I've type-hinted the CategoriesRepository so it gets automatically loaded by the Service Container.
However, if I directly create a new instance of the CategoriesController class (without using the Service Container), I have to specify that I need a new instance of the CategoriesRepository too, like this:
$example = new CategoriesController(new CategoriesRepository());
Now, let's suppose I write the following code.
class CategoriesController extends Controller
{
protected $repo;
public function __construct()
{
$this->repo = new CategoriesRepository();
}
This way, I don't have to load the class through the Service Container, nor call it by passing a new instance of CategoriesRepository as the argument, because it's automatically created inside of the constructor.
So, my question is: would this be bad practice? What's the difference between type-hinting as a parameter and creating a new instance inside of the constructor?
Here's the beauty of dependency injection:
Complex initialization
class MyController {
public function __construct(A $a) { }
}
class A {
public function __construct(B $b) { }
}
class B {
public function __construct(C $c) { }
}
class C {
public function __construct(D $d) { }
}
class D {
public function __construct() { }
}
Now you can ask laravel to create that class for you e.g:
$controller = make(MyController::class);
or you can do:
$controller = new MyController(new A(new B(new C(new D())))));
In addition you can specify more complex rules on how to create the variables:
app()->bind(D::class, function ($app) {
$d = new D();
$d->setValueOfSomething($app->make(AnotherClass::class));
return $d;
});
Testing
That's one advantage of dependency injection over manual creation of things. Another is unit testing:
public function testSomeFunctionOfC() {
$this->app->bind(D::class, function () {
$dMock = $this->createMock(D::class);
});
$c = make(C::class);
}
Now when you create C the class D will be the mocked class instead which you can ensure works according to your specification.

Factory Method Design Pattern -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

Confusion about adapter pattern and inheritance (PHP)

I'm having some confusion with the adapter pattern and am wondering if it is the right tool for what I'm trying to accomplish.
Basically, I'm trying to get a class written by another developer to conform to an interface that I've written while also retaining the other methods from that class.
So I've written the following interface for a container object:
interface MyContainerInterface
{
public function has($key);
public function get($key);
public function add($key, $value);
public function remove($key);
}
I've also written an adapter that implements that interface:
class OtherContainerAdapter implements MyContainerInterface
{
protected $container;
public function __construct(ContainerInteface $container) {
$this->container = $container;
}
public function has($key) {
$this->container->isRegistered($key);
}
...
}
And am using it in my class as follows:
class MyClass implements \ArrayAccess
{
protected $container;
public function __construct(MyContainerInterface $container) {
$this->setContainer($container);
}
public function offsetExists($key) {
$this->container->has($key);
}
...
}
Then my application uses the class as so:
$myClass = new MyClass(new OtherContainerAdapter(new OtherContainer));
The issue I'm having is that in order to use the methods from the adapter I have to write the following:
$myClass->getContainer()->getContainer()->has('some_key');
When ideally it would just be:
$myClass->getContainer()->has('some_key');
$myClass->getContainer()
should return an instance of MyContainerInterface and that has a has() function. It shouldn't have a getContainer() function.
I don't think you need the Adapter Pattern for this. It looks to me like you're after a polymorphic solution, which can be accomplished by simply using an abstract class. No adapter needed.
The interface
interface MyContainerInterface
{
public function has($key);
public function get($key);
public function add($key, $value);
public function remove($key);
}
Then the abstract base class:
class MyContainerBaseClass implements MyContainerInterface, \ArrayAccess
{
public function offsetExists($key) {
$this->has($key);
}
...
}
Then, the sub-class from the other developer:
class ClassByOtherDeveloper extends MyContainerBaseClass
{
public function has($key) {
$this->isRegistered($key);
}
//you also need to implement get(), add(), and remove() since they are still abstract.
...
}
You can use it in your application like this:
$object = new ClassByOtherDeveloper();
$x = $object->has('some_key');
I'm assuming the isRegistered method lives in the implementation from the other developer.
To make it truly polymorphic you wouldn't hard-code the class name, but you'd use a variable that could come from a config file, database, or a Factory.
For example:
$className = "ClassByOtherDeveloper"; //this could be read from a database or some other dynamic source
$object = new $className();
$x = $object->has('some_key');

is it possible to define a interface Singleton in PHP?

I want to define a Singleton base type from which the user will derive his classes, so this is what I thought:
interface SingletonInterface {
public static function getInstance();
}
abstract class SingletonAbstract implements SingletonInterface {
abstract protected function __construct();
final private function __clone() {}
}
But using this aproach the user may implement this singleton...
class BadImpl implements SingletonInterface {
public static function getInstance() {
return new self;
}
}
What would be your aproach?
Remember PHP doesn't allow multiple inheritance so you must carefully choose what you base your classes on. Singleton is so easy to implement it's probably better to let each class define it.
Beware also that private fields are not ported to descendant classes and therefore you can have two different fields with the same name.
I am using this code for creating a Singleton:
abstract class Singleton {
private static $_aInstance = array();
private function __construct() {}
public static function getInstance() {
$sClassName = get_called_class();
if( !isset( self::$_aInstance[ $sClassName ] ) ) {
self::$_aInstance[ $sClassName ] = new $sClassName();
}
$oInstance = self::$_aInstance[ $sClassName ];
return $oInstance;
}
final private function __clone() {}
}
This is using of this pattern:
class Example extends Singleton {
...
}
$oExample1 = Example::getInstance();
$oExample2 = Example::getInstance();
if(is_a( $oExample1, 'Example' ) && $oExample1 === $oExample2){
echo 'Same';
} else {
echo 'Different';
}
First of all: if you have so much Singletons over the project then you probably mess up something on projection level
Second of all: Singleton should be used there, and only there, where more that one instance of a class makes totally no sense or might cause some errors
Finally: the inheritance ain't designed to reduce the amount of code
You can now use traits, but do you need so much singletons ?

Categories