I took clues from DataMapper pattern to create something like this:
class BusinessObjectCreator
{
public function create()
{
//Acquire Data
$number = filter_input(INPUT_POST, "number", FILTER_SANITIZE_INT);
//create and populate object
$object = new Object();
$object->setNumber($number);
return $object;
}
}
//usage:
$objectInstance = (new BusinessObjectCreator())->create();
//examples of usage once created
$objectInstance->someBusinessFunction();
echo $objectInstance->getNumber();
But to me it also looks like a Factory pattern or a Builder pattern.
Which is it? and did I code it up correctly?
Purpose is to create an object instance populated with data. Then I can use the created object to do operations on the data.
This looks like a Factory Method. The naming convention leads you to think it's the builder pattern which has a separate object for the building of the concrete object. You have a separate object but are not setting the data like a builder would.
I'm not too familiar with PHP but to make it a builder pattern you'd create methods for the data, then call create()/build() at the end of the method chain.
It's creation would look like this
$objInstance = (new BusinessObject())->number($number)->create();
Since you only have a class with a method that creates an object, this pattern falls into the factory method category. Usually you use a builder when there are a lot of potential different configurations of an object upon creation, so you may just stick the factory method, if you only are setting one piece of data.
Builder Pattern
Related
its gonna be a fully theoretical thread.
Let's talk about change arrays to specially object's, to compare and work on it.
For example we have a EntityClass, EntityInterface, SomeRepository, SomeManager, SomeCommand.
Entities is a clear object, example:
class EntityClass implements EntityInterface {
public $name;
public funtion getName() {
return $this->name;
}
public function assign($data) {
$this->name = $data['name'];
}
...
}
Repository ofc. have method's to save object in source and get it from source.
Manager have all of 'busines logic', it can modify a entities using command pattern, one command for one properties, so a busines logic for all properties its store in separate's command's, and manager fire it's.
Now, in manager start all logic and fun.
Little shorthand:
Repository create new entity by getOne().
We create a new instance of manager and pass by constructor some dependencies like array of data from controller and Entity.
Array of data have information about changes, example: ['name' => 'New name']; mapper resolve what command should have been fired by manager for given array.
Manager execute all commands for this request and passing raw array to each command.
Now, why we passing a array ? when we are in OOP, why don't use special variation of EntityClass ??
Now let's add a new interface EntityProposeInterface, and change a raw array to class implements this interface, and pass them.
for example we can add to SomeManager speciall method to morph entity like this (PHP7+):
class SomeManager {
public function morph($entity) {
$buff = new class extends EntityClass implements EntityProphoseInterface{};
$buff->assign($entity->toArray());
return $buff;
}
And now we have a EntityProphose lets make some changes on it, now manager change a EntityProphose from raw data array, and all commands and other method's in our code work's on object kinde EntityProphose instead of array.
But ofc. our repository cant save object's instance of EntityProphoseInterface.
And that's all...
Is there some design pattern name ? or something like this ?
Or this idea is very bad ?
I hope it's clear for all of you, if not please ask.
Any ideas ? advice ?
What makes me go crazy is why you would implement a function to assign values from an array to the whole class instead of just using regular assignments:
$entity->name = name;
$entity->age = age;
Perhaps you want to simplify this code... but what's the point of using arrays?
Your manager class (actually, a service) should provide functions with either parameters corresponding to whatever entity you want to modify or operate with, or just receive a DTO or the entity itself.
In the other hand, if you want to centralize how DTOs or entities are mapped one to another, maybe you need to implement object mappers:
class EntityMapper {
public function mapCustomerToCustomer($customerA, $customerB) {
if($customerA->name != null) {
$customerB->name = $customerA->name;
}
// and so on...
}
}
...and you can inject it wherever you want to map entities. For example, a CustomerService might look as follows:
class CustomerService {
function __construct($entityMapper) {
$this->entityMapper = $entityMapper;
}
public function update($customer) {
$customerToUpdate = $this->repository.getById($customer->id);
$this->entityMapper->mapCustomerToCustomer($customer, $customerToUpdate);
$this->repository.addOrUpdate($customerToUpdate);
}
}
Assuming we have an object that gets 3 objects in constructor:
$SomeObject = new Object($UrlChecker, $UrlModifier, $UrlComposer);
Wouldn't it be better to create an wrapper object $Url like this:
class Url {
public $Modifier;
public $Composer;
public $Checker;
public function __construct(){
$this->Modifier = new UrlModifier();
$this->Composer = new UrlComposer();
$this->Checker = new UrlChecker();
}
}
And then pass only this $Url object:
$Url = new Url();
$SomeObject = new Object($Url);
Now all the objects will be created in the $Url object and I can call their memebers within the object $SomeObject like this:
$Url->modifier->set_parameter($param);
Is it a good practice to set embedded object as public or should I create for every object a getter-method? Or maybe I should stick with the first variant by passing all three objects to the $SomeClass?
I thought I could use public methods like Java's "System.out" does, where "out" is an public member/object within the System-object.
I don't see how this:
$this->url->modifier->set_parameter($param);
is better than this:
$this->modifier->set_parameter($param);
You're requiring additional steps for the caller and the callee without clear benefit. The first approach makes it appear that the methods are somehow working of the same base data (somehow stored in $url). However, that is not the case (your goal appears to be organization but really you should be driven by which object controls the state/base data). The base data would/should be stored in the controlling object (represented by $this). So, having said that...
Is it a good practice to set embedded object as public or should I
create for every object a getter-method?
... you should hide the objects and create getters/setters on the main object since it needs to control (the basis of encapsulation) the injected objects (which is why you injected them in the first place).
Definitely use private variable if you intend to use $modifier, $composer, and $checker internally and create getter and setter method for those variables. It's OOP concept called encapsulation. The main purpose is to protect an object integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state.
Not sure if my title is correct cause I am not even sure I am using the correct terms.
I have a class that has a property that is an object. When setting this property the object has to be created. My question is how do I do this without tight coupling?
Example:
class A
{
protected $_depending;
protected $_somePropertyObject;
public function __construct(\Lib\Dependency $depending)
{
$this->_setDepending($depending);
}
protected function _setDepending(\Lib\Dependency $depending)
{
$this->_depending = $depending;
}
public function setSomeProperty($someProperty)
{
// I want to prevent this
$this->_somePropertyObject = new \Lib\some\Object($someProperty);
}
}
I could just pass the required object through the construct but what happens more are needed?
When if I understand correctly the factory pattern, what would this change? I would still need to create the object somewhere? Not the object itself but the factory. Again tight coupling? Seems endless to me. When re factoring class(es) it however is isolated where and how the class(es) are made.
If I set the setSomeProperty function to only accept \Lib\some\Object then is still needs to be created by the parent object that is passing it to begin with. Seems only to shift the placement of where it is created?
Hopefully I am clear enough in what I am trying to ask.
Thanks in advance!
EDIT What I am asking is the sequence of what is created when,where,why.
The purpose of a factory in dependency injection patterns is to produce instances for another instance, without that other instance needing to know how to produce it.
At its core, a "factory" is just an object-returner: something that returns an instance when invoked.
This is easier to see in more capable languages. For example in Python classes are callable (there is no new operator), and invoking a class produces an instance of the class. So classes can be their own factories if the class requires no arguments. Likewise any zero-argument function that returns an instance can be considered a factory. This makes dependency injection very clear and free-of-boilerplate.
In more rigid languages (Java/C++/C# static-typed tradition, or where classes or functions are not completely first-class like in PHP), you need to obscure dependency injection behind a "pattern", because "design patterns" are missing language features. In PHP 5.3+ you can use a closure as a factory, or you can go the Java/C# way and define a FactoryInterface and a new class per factory.
For example, with your class, you could do this:
class Aprime extends A
{
public function setSomeProperty($somePropertyFactory)
{
$this->_somePropertyObject = $somePropertyFactory();
}
}
In this class, setSomeProperty requires a zero-argument callable "factory", which you could produce like this:
$other_dep_factory = function(){ return new SomeOtherClass(); };
Or like this:
class ClassFactory {
function __construct($classname, $args=array()) {
$this->class = new ReflectionClass($classname);
$this->args = $args;
}
function __invoke() {
return $this->class->newInstanceArgs($this->args);
}
}
$other_dep_factory = new ClassFactory('SomeOtherClass');
Prior to PHP 5.3, you need to do it like Java would:
interface IObjectFactory {
function getObject();
}
// this B-and-D interface is optional
// it has no body because PHP doesn't support
// type-hinting return values
interface ISomeOtherClassFactory {}
class SomeOtherClassFactory implements ISomeOtherClassFactory {
function getObject() {
return new SomeOtherClass();
}
}
class Aprime extends A
{
public function setSomeProperty(ISomeOtherClassFactory $somePropertyFactory)
{
$this->_somePropertyObject = $somePropertyFactory->getObject();
}
}
$other_dep_factory = new SomeOtherClassFactory();
$myAprimeObject->setSomeProperty($other_dep_factory);
So when do you use a factory? Whenever an object needs to create another object. If the object just needs to use another object, just pass in an instance.
I like to use the Factory Pattern when you need to collect "information" to create the object that's stored in $_somePropertyObject. For instance let's say you have to assign values to some properties to instantiate it or run a couple of methods right after you instantiate it.
Also, you'll want to consider whether you might need to later change the inheritance tree. If you might be assigning $_somePropertyObject a \Lib\some\Object now, you might find yourself wishing you could easily swap it out for a \Lib\some\FancyObject later. If you use Dependency Injection, you can easily swap subtypes.
Here's a primer: http://net.tutsplus.com/tutorials/php/the-whens-and-whys-for-php-design-patterns/
Also, too: https://stackoverflow.com/a/2083455/1121827
I want to refactor my model so I can properly write a unit test for it. But I have some dependencies. Can anybody point me in the right direction how I can remove these dependencies?
class Customer
{
public function save(array $data, $id = NULL)
{
// create or update
if (empty($id)) {
$customer = new \Entities\Customer();
} else {
$customer = $this->findById((int) $id);
}
$birthday = new DateTime();
list($day, $month, $year) = explode("/", $data['birthday']);
$birthday->setDate($year, $month, $day);
$customer->setFirstName($data['firstName']);
$customer->setLastName($data['lastName']);
$customer->setCompany($data['company']);
$languageModel = new Application_Model_Language();
$customer->setLanguage($languageModel->findById($data['language']));
$resellerShopModel = new Application_Model_ResellerShop();
$customer->setResellerShop($resellerShopModel->findById($data['resellerShop']));
$customer->setEmail($data['email']);
$customer->setPhone($data['phone']);
$customer->setGender($data['gender']);
$customer->setBirthday($birthday);
$customer->setType($data['type']);
$customerSectorModel = new Application_Model_CustomerSector();
$customer->setSector($customerSectorModel->findById($data['sector']));
$customerReferenceModel = new Application_Model_CustomerReference();
$customer->setReference($customerReferenceModel->findById($data['reference']));
if (isset($data['password'])) {
$customer->setPassword($this->_hashPassword($data['password']));
}
return $customer;
}
}
I guess your dependencies are the constructor calls in the function body. Out of my mind there are 3 ways to replace them in the unit test:
Create a mock library where all the different classes are implemented, and to run the test include the mock library instead of the real modules.
Add a set of default parameters for the external classes to your function declaration. In the end your new function declaration would look like public function save(array $data, $id = NULL, $newCustomer=\Entities\Customer(), $newLangModel = Application_Model_Language, ...). Also in the function body you use the variables to create the actual objects, like $customer = new $newCustomer(). In the test code you can override every depended class by a mock class.
You do not add a parameter for every class, but create two factories: one which creates the current objects, and one which creates mock objects. Inside of the function you request new objects only from the factory.
This approach is useful if there are many different places where the construction should be intercepted. If there is only one function which should be changed, a factory is over-engineering.
After looking back over your code, it appears this class is acting as both a Factory and Repository to the \Entities\Customer class (this was not obvious, so you could consider renaming to be more explicit your intentions). I also disagree with that function being named save since it is only returning an object that then needs to be persisted, but that is more semantics.
With the code as you have it now, I see two different tests that are needed.
1) Test your \Entities\Customer class.
Verify that each of your getters and setters are working correctly, or at least any one that has business logic behind it. For instance make sure that if you set the ResellerShop, then if you get a correct/valid ResellerShow object.
More or less, you need to test your business logic. Get/Set of basic fields (ex. Name) don't really necessitate their own tests (unless 100% code coverage is a goal, I don't think it is).
2) Test the (Factory\Repository) class.
Ensure the class you showed correctly creates (or fails) depending on the data passed into the array. For instance it should fail if required fields are not passed in, and it should not return a customer entity object.
The idea is for separation of concerns. Your Entity class should contain your business logic and should be tested separately from your object instantiation code.
Our current ORM solution uses Data Mappers to represent tables / views in the database which then return a Collection object that can be used to iterate through the retrieved records as Model objects. Between the Data Mapper and Model layers is a Repository layer that handles domain requests to the data mappers and returns the corresponding collections or domain objects.
We are currently looking at refactoring the responsibilities of the Repository and Data Mapper layers so that all application requests to the Data Mapper layer are routed through the Repository and the Data Mapper returns the retrieved data rows to the Repository which then returns the necessary collection to the requesting object.
What I'm wondering is whether it is valid / good practice to pass the entire Repository object into the corresponding Data Mapper so that we can enforce access to the Data Mappers only through the Repository layer.
As an example this is basically how it works now:
class DataMapper {
public function findAll(Criteria $criteria)
{
$select = $criteria->getSelect();
// Build specific select statement
$rows = $this->_fetchAll($select);
return new Collection(array('data' => $rows, 'mapper' => get_class($this)));
}
}
I thinking of doing something like this:
class Repository {
public function findAllByName(Model $model)
{
$this->_criteria->addCondition('name LIKE ?', $model->name);
$rows = $this->_mapper->findAll($this);
return new Collection(array('data' => $rows, 'repository' => get_class($this)));
}
}
class DataMapper {
public function findAll(Repository $repository)
{
$select = $repository->getCriteria()->getSelect();
// Build specific select statement
$rows = $this->_fetchAll($select);
return $rows;
}
}
And then in this version, the Collection object would issue a call to the Repository which could first search through its cached objects and then only issue a call to the database to load the record if its needed.
Chris has a valid suggestion.
It partially depends on the context of the code, but dependency injecting the repository into the DataMapper instances you create, i.e:
$repo = new Repository();
$mapper = new DataMapper($repo);
Will spare you from subsequently having to pass that $repo around whenever you want to use findAll(). IE:
$mapper->findAll();
$mapper->findAllByName();
I find when parameters become a ubiquitous part of every function call I'm making, it makes sense to consider turning them into instance variables (especially when they're identical every time).
If your repository varies from between context/instances then the injection makes more sense. If you find that you're always creating one repo instance and would like to recycle it, a singleton might be appropriate.
The nice thing about Dependency Injection is it does clarify this dependency idea (ironic!). If you want to enforce it, you can do something like throw an exception if the $repo object is null, or not a Repository instance, in your __construct() method.
I would perhaps do this a little bit differently. I would add a setRepository(Repository $repos) method as well as a getRepository() method. Then, in your findAll method, call getRepository(). If setRepository() has not been called yet, then getRepository can return a default repository instance.
I would also perhaps create an interface for the Repository class so that different implementations of Repository can be used within the DataMapper class.
So the get method could look something like
public function getRepository()
{
if (!$this->_repository) {
$this->_repository = new Repository();
}
return $this->_repository;
}
and the set method could look something like
public function setRepository(RepositoryInterface $repos)
{
$this->_repository = $repos;
}