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);
}
}
Related
I was wondering if you could help me with the following question. First of all, I would like to tell you that if I am asking this question here, it is because I have already tried many options and none have worked for me. It turns out that I am developing a package with Laravel and I am using Laravel's dependency injection. But I am at a crossroads from which I have not found a way out. I'm trying to get the instance of a class in an intermediate method from a method chain, let me explain. Here is the code very similar to what I have:
PackageServiceProvider.php
<?php
class PackageServiceProvider extends ServiceProvider
{
public function register()
{
$this->configureBindings();
}
private function configureBindings()
{
$this->app->when(A_Class::class)->needs(B_Interface::class)->give(function () {
return new B_Class();
});
}
...
A_Class.php
<?php
class A_Class implements A_Interface
{
private $b_interface;
public function __construct(B_Interface $b_interface)
{
$this->b_interface = $b_interface;
}
public function create($arg1, $arg2)
{
return $this->b_interface->method_1()->call_another_method_from_another_class();
}
}
A_Interface.php
<?php
interface A_Interface extends Arrayable, Rendereable
{
public function create($arg1, $arg2);
...
}
<?php
class B_Class implements B_Interface
{
public function __construct()
{
// Here is the question...
// How could I get here the instance of the class A_Class?
}
public function method_1()
{
// should return another class instance
}
public function method_2()
{
// should return another class instance
}
}
B_Interface.php
<?php
interface B_Interface
{
public function method_1();
public function method_2();
...
}
If you look at class B_Class``, in the __constructmethod I'm trying to get the instance of classA_Class``` from where that class is being called. I have tried the following:
class B_Class implements B_Interface
{
public function __construct(A_Interface $a_interface)
{
// Here is the question...
// How could I get here the instance of the class A_Class?
}
But I get the following error:
Segmentation fault
I guess there must be some way I can achieve what I need. I would appreciate any help in advance.
Because you are referring to class A inside your class B constructor, and class B in your class A constructor, you have introduced a cyclic dependency.
This will resolve to the error you are experiencing, which is the segmentation fault, as outlined here:
https://laravel.io/forum/11-08-2016-circular-dependency-causes-segmentation-fault-error-when-running-php-artisan-optimize
So the answer is to remove the cyclic dependency if possible, as you can have methods from A calling B that calls A for infinity at runtime, and you will get the above error above again.
If your class A and B are relatively small, I would recommend combining them before using a cyclic dependency.
For interest and prosperity, if you want achieve a cyclic dependency, this is possible by registering your Class A with a singleton from inside A's constructor, and putting the reference to the incomplete object into Class B with your code above. I try with laravels singleton here, its untested, but hopefully you'll get the idea.
class A_Class implements A_Interface
{
public function __construct(B_Interface $b_interface)
{
//I dont think you can pass $this to a function when construction is incomplete, hence $that.
$that = $this;
App::singleton('A_Class', function($that){
return $that;
});
$this->b_interface = $b_interface;
}
}
class B_Class implements B_Interface
{
public function __construct(A_Interface $a_interface)
{
//unfinished object, but no more error.
$this->aClass = App::make('A_Class')
}
}
Im working on a project where we're creating many objects throughout the code base.
For some objects thus we decided to use factories to control the process of creating the objects and all their dependencies. This is an example of what we are trying to do:
class CreateBranchFactory implements CreateBranchInterface {
private $branch;
public function __construct() {
$this->branch = new Branch();
$this->branch->scenario = 'create';
}
public function createBranch($branchForm) {
$this->branch->attributes = $branchForm->attributes;
//Example of all the things that I need to do after creating my object
$this->setOfficialNameAndPrinterName($branchForm->official_name, $branchForm->printer_name, $branchForm->name);
$this->createDependencies1();
$this->someOtherFunction();
return $this->branch;
}
public function setOfficialNameAndPrinterName($offName, $printerName, $branchName) {
$this->branch->official_name = $offName ?? $branchName;
$this->branch->printer_name = $printerName ?? $branchName;
$this->branch->save();
}
public function createDependencies1() {
}
And to have a proper contract I created an interface for this. This interface specifies the functions that should be defined
interface CreateBranchInterface {
public function setOfficialNameAndPrinterName(String $offName, String $printerName, String $branchName);
public function createDependencies1();
}
My problem though, is that the contract is specifying all the functions that should be defined, but isnt controlling which functions should get called. Is there any design pattern that I can use, that makes sure that those functions get called??
You can't create such contract by using interfaces - interfaces specifies which methods and how you can call. Calling all these methods is part of implementation, which cannot be provided by interface. You need to create abstract class with implementation and use final keyword to disallow overriding it:
abstract class CreateBranch {
abstract protected function getBranch(): Branch;
final public function createBranch($branchForm) {
$this->getBranch()->attributes = $branchForm->attributes;
//Example of all the things that I need to do after creating my object
$this->setOfficialNameAndPrinterName($branchForm->official_name, $branchForm->printer_name, $branchForm->name);
$this->createDependencies1();
$this->someOtherFunction();
return $this->getBranch();
}
abstract public function setOfficialNameAndPrinterName(String $offName, String $printerName, String $branchName);
abstract public function createDependencies1();
abstract public function someOtherFunction();
}
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
When defining the structure and inheriting Interface and/or Abstract Class, which one is the best practice? And why? Here are 2 examples:
Here is the example for [Interface] -> [Abstract Class] -> [Class]
Interface DataInterface
{
public function __construct($connection);
public function connected();
public function get();
}
Abstract class BaseData implements DataInterface
{
protected $connection;
public function __construct($connection)
{
$this->connection = $connection;
}
}
class UserData extends BaseData
{
public function exists()
{
return is_connected($this->connection);
}
public function get()
{
return get_data($this->connection);
}
}
$oUserData = new UserData(new Connection());
And here is the sample for [Abstract Class] -> [Class] without the Interface
Abstract class BaseData
{
protected $connection;
public function __construct($connection)
{
$this->connection = $connection;
}
abstract public function connected();
abstract public function get();
}
class UserData extends BaseData
{
public function exists()
{
return is_connected($this->connection);
}
public function get()
{
return get_data($this->connection);
}
}
$oUserData = new UserData(new Connection());
I am currently creating a small app (might grow larger) and confused on how to implement in the beginning correctly.
By the way, is this declaration for __construct() with parameter make sense in Interface?
public function __construct($connection);
Abstract classes defines an interface that must be implemented to the heirs of the abstract class. An Interface-Construct defines an interface that must be implemented by a class that implements the interface-construct, the implementation of the interface is not limited to a single interface, whereas class inheritance is coupled to a single (abstract) class.
Interfaces in PHP are intentionally used to allow typehints of an limited subset of an entire class interface. There is no reason for an interface on abstract classes aslong their receiver of instances of their heirs did not use them ( with typehinting or logical identification over instanceof / is_a ). The more valuable benefit of interface-constructs are the possibility of replacing an common implementation of an interfaces with a alternate implementation.
In case of your BaseData-Example, i recommend to drop the abstract idea and use a trait and seperate interfaces instead.
trait connectionBrokerConstructor {
protected $connection;
public function isConnected()
{
return $this->connection instanceof Connection;
}
public function setConnection(Connection $connection)
{
$this->connection = $connection;
}
}
interface connectable
{
public function setConnection(Connection $connection);
public function isConnected();
}
interface userDataRepositoryInterface
{
public function get();
}
class UserData implements connectable, userDataRepositoryInterface
{
use connectionBrokerConstructor;
public function __construct(Connection $connect = null)
{
$this->setConnection($connection);
}
public function get()
{
return array('something');
}
}
Really abstract classes and interfaces are different.
Consider an interface as a contract, it lays out the rules that other classes (which implement it) must follow.
Abstract classes on the other hand are more like starting points, which other classes can build on, hence why they are sometimes called base classes.
------- Edit with example
I'm not an expert on such things, but I've always just done interface -> class.
For example, here is a simple interface:
interface AnimalInterface {
public function all();
public function findBySlug($slug);
}
And here is the class which implements that interface (simplified):
class AnimalEloquentRepository implements AnimalInterface {
public function all()
{
return Animal::all();
}
public function findBySlug($slug)
{
return Animal::whereSlug($slug)->first();
}
}
I do often have a base class, which others extend, but I've only once used an abstract class in a real world app, and that ended up getting replaced.
I'm sure there are better ways to do things, but this has worked really well for me in the past.
My reputation doesn't allow comments, but this statement in tr0y's answer is misleading:
"Abstract classes defines an interface that must be implemented to the heirs of the abstract class."
One of the main differences between an interface and an abstract class is that you are not required to implement any of the methods of an abstract class in a class that extends it. It's quite common for the abstract class to have methods with default behavior and only provide those methods in the heirs if the default behavior is not what you want.
On the other hand, you are require to create all methods specified in an interface in any class that implements that interface.
Another difference is that methods in an interface cannot have a body, while methods in an abstract class must have a body.
I'm trying to decide the design pattern for a class structure I'm working with and I'm torn on the best way to implement the setup of the classes.
One approach calls an abstract setup function in the constructor of the abstract class, the other is to override the constructor in the classes which extend the abstract class.
A couple of (contrived and simplified) examples to outline my thinking:
Calling abstract method
<?php
abstract class VehicleAbstract implements VehicleInterface
{
protected $_wheels;
private $_engine;
public function __construct(EngineInterface $engine)
{
$this->setupWheels();
$this->_engine = $engine;
$this->_engine->setWheelsToDrive($this->_wheels);
}
public abstract function setupWheels();
}
class Car extends VehicleAbstract
{
public function setupWheels()
{
$this->_wheels = array(
"frontL",
"frontR",
"backL",
"backR"
);
}
}
Pros:
When implementing the concrete class it's obvious the method
"setupWheels" needs to be created.
Only the setup code needs to be written inside the "setupWheels"
method.
Cons:
When implementing it may not be immediately obvious what
"setupWheels" needs to do without looking through the parent class.
Someone new looking at the extended class may not realise the method
is called when the class is created.
Overriding constructor
<?php
abstract class VehicleAbstract implements VehicleInterface
{
protected $_wheels;
private $_engine;
public function __construct(EngineInterface $engine)
{
$this->_engine = $engine;
$this->_engine->setWheelsToDrive($this->_wheels);
}
}
class Car extends VehicleAbstract
{
public function __construct(EngineInterface $engine)
{
$this->_wheels = array(
"frontL",
"frontR",
"backL",
"backR"
);
parent::__construct($engine);
}
}
Pros:
When viewing the concrete class immediately obvious when the wheel data is being setup.
Cons:
When extending the abstract class it may be missed that the wheel
data needs to be setup at all.
While implementing the new constructor need to remember to call the
parent constructor.
Need to call parent constructor in correct position in new constructor.