Passing parameter to __construct with dependency injection - php

I am creating a User class and it is supposed to be an Entity class. In DataBase i created User table and it has 20 fields.
My question is : Is it good to create a "__construct()" with 20 parameters or i should user setter/getter?
I recently read some article about dependency injection and how it makes code more maintainable but i am confused in my own code.
Here it is my __construct function:
class User{
private $userName;
private $userLastName;
...//Other users fields
public function __construct($name,$lastname,$phone,...){
$this->userName = $name;
$this->userLastName = $lastname;
...
}
}
I am looking for best practice to write some readable,clean and maintainable code.
Regards

This has nothing to do with dependency injection. Here you wouldn't be injecting dependencies, but just values.
So the real question is: should you get those values in a constructor, or through getters/setters?
And I'd say using your constructor is a good thing, because it can prevent your model to exist in an invalid state. For example, if you user need to have an email, then by putting it in your constructor your are guaranteed that all users will have emails.
So I suggest that you put in your constructor all the properties that needs to be defined (not null), and use setters for all others (that will help avoid having a 20 parameters constructor).

By having 20 parameters there is a big chance that your class in question violates the Single Responsibility Principle and forms some sort of monolithic class without properly delegating, composing functionality.
Ensure that your class has a low coupling and a high cohesion.
See http://500internalservererror.wordpress.com/2009/02/23/what-do-low-coupling-and-high-cohesion-mean-what-does-the-principle-of-encapsulation-mean/
As we are not doing full code review here (go to https://codereview.stackexchange.com/ instead)
I suspect you are passing things like country, zip, phone number etc all as parameters.
Ask yourself what data is absolutely required to construct a valid object.
If you have a class Person which requires a property called Name then having a setter for Name but not a ctor argument allows you to create incomplete classes. This shifts the burden of maintaining consistency to every method as you cannot be sure that Name has been set. Such code is bad and typically results in carrying some "initialized" flag or a function and clutter your code with checks.
Your ctor should contain the minimal set of parameters. Everything else can be done via properties or being further composed, e.g. an Address class removing the complexity of passing zip, state, street, etc all in the parent ctor.
You may create a "Contact" class storing email and phone numbers, etc.

It's better to use getter and setter. A __construct method with 20 parameters is to huge. And without getter how you want to access to your private User attributes ?

Related

Should I apply the same practice to PHP access specifiers as I do to Java specifiers?

I'm currently doing a tutorial on PHP and it has me create a class Person which might represent a user on a website.
There are two public fields ($firstname and $lastname) and the tutorial has me access them using $some_person->firstname.
I know in Java we would most likely want to make these fields private and use getters and setters to access them. Should I apply this same practice to PHP?
Yes - PHP5+ supports public/protected/private methods in classes. You don't need to design getters/setters but if the class grows/adds functionality it'll be safer than letting people call the properties directly.
Yes, in general properties should be made protected or private and getters and setters offered. This will allow you to add in type hints in the setter signature or validation in the setter body, which will make it harder for bad data to slip into properties unnoticed. I tend to recommend this approach even if "you don't need it now" - you may do so later.
The argument against public properties in PHP is just the same as it is in Java: it opens up the "black box" of the class to the outside world, and starts to break down the encapsulation that classes are meant to offer in the first place.
Classes are usually meant to be extended, which has a bearing on whether properties should be protected or private. If child classes are trusted (e.g. part of the same codebase) the developer may be happy to allow direct access to the property, in which case it can be protected. However, if the code is intended for release (e.g. as a F/OSS library) then there's an argument for forcing child classes use the getter and setter methods, in which case the properties should be private.

Where to check for mandatory properties in a domain object?

I have a PHP MVC application, and my 'M' has a service layer, mapper layer and domain layer. Where and how should I check to ensure that an object has all it's required properties?
It seems to me that these responsibilities don't belong in the mapper or service layer, so that leaves the domain layer itself. I put a method, checkRequired(), in my base domain class. It checks the object's properties against an array of $_required properties, and throws an error if any are missing.
When retrieving objects from the database, I have been calling checkRequired() as the last command in the object's constructor. If the object is a new entity (i.e. not retrieved from the database), I supply some default values (in the constructor) and then call checkRequired().
While this has been working OK, I now come to put some behavioural methods on my (somewhat anaemic) domain objects, and I run in to trouble. For example, a User can own many Pets, so on my User model I put an addPet() method. I know that I need to pass the Pet object in, since it's best to inject dependencies, and my real method signature is therefore User::addPet(ConcretePet).
But that's the problem! My Pets can't exist without a User (as their Owner), so I can't instantiate ConcretePet! I could make the User optional on the Pet, but this would be a backward step. I could move the contents of checkRequired() somewhere else, but where?
What's the typical way to solve such a common problem?
That checkRequired is not a DDD way. An enntity should be valid all the time. In other words - you should not have a way to put it in an invalid state (like missing properties). How?
When you just have public properties that you set, that's anemic. Properties that you persist in DB should be private. The only way to set them is through methods with a business meaning. These methods should check all the invariants (not just required fields - all kind of constraints that would make an entity valid or not) and prevent the update if some of them are not met.
About User->Pet topic: If the Pet can't exist without the User then probably the User is an Aggregate Root that is responsible for protecting invariants related to User and Pets. That means there should be a method addPet... well... maybe something more meaningful? adoptPet and breedPet (they might have slightly different rules and input)? And this adoptPet should ensure the invariant of the pet having a User... By the way - why User and not an Owner?
But Pet also can be an Aggregate Root. That means it's constructor should require a User parameter.
Note that it depends from the use case what is the aggregate root. In some cases Pet is treated as aggregate root but in case of pet adoption it's a part of User aggregate.
Make a undirectional relationship as possible as you can. If a pet could be tracked alone (I mean without a user), consider it as an aggregate root.
Place a User attribute in Pet but no pets attribute in User. Therefore you don't need to have a addPet() method in User.
If you want to find all pets belonging to a user, use a query instead:
public class PetRepository {
public List<Pet> findByOwner(String uid) {
//omitted codes
}
}
Hope this helps.
When retrieving objects from the database, I have been calling
checkRequired() as the last command in the object's constructor.
Off topic, but this can be problematic. Suppose that the set of required attributes changes at some point such that persisted entities are no longer valid. You still want to be able to reconstitute them, so you shouldn't run that check upon reconstitution. Instead, only run validation upon creation or during behaviors.
With regards to the addPet method, instead of passing an instance of a concrete pet class, pass the data required to create an instance of a pet as method arguments or as an instance of a PetInfo class. This would allow the User class to create a fully valid instance of Pet.

Are there any valid use case for using public variables in PHP OOP?

Variable encapsulation, Set/Get methods are best practices but why do we have a chance to declare a variable public if it's not meant to be used anyway? Would it have been better if variables were always private by default with no chance of making them public since all of the tutorials I read says they should be encapsulated with set/get methods? Is there any valid use case for public variables at least in PHP OOP?
In fact it's just the other way round: Theoretically getters/setters are wrong. The properties defines the state of an object, where the methods defines the behaviour. Getters/Setters only intercept the read and write access to properties, but they break the semantic meaning completely: Now reading the status of an object is a behaviour of the object.
To make properties to look like properties again there is a RFC on the road :)
https://wiki.php.net/rfc/propertygetsetsyntax
Set/Get methods are best practices but why do we have a chance to declare a variable public if it's not meant to be used anyway?
Best practices and not meant to be used is not the same. A language needs to offer different tools for different use-cases and should be consistent.
PHP objects always supported public members and when differentiated visibility was introduced, for backwards compatible reasons public members are very useful.
Would it have been better if variables were always private by default with no chance of making them public since all of the tutorials I read says they should be encapsulated with set/get methods?
That question can not be specifically answered, it's too subjective and there are too many different use-cases that would result in a different answers.
Is there any valid use case for public variables at least in PHP OOP?
Start with backwards compatiblity. If you can not refactor your code but would need to rewrite it completely all the time, this would be very expensive.
let's see..
this's a real world Email API class from CakePHP EmailComponent. to use this class you only need to "set" some property then just send()
$this->Email->to = 'ss#b.co';
$this->Email->from = 'me#b.co';
$this->Email->title = 'xxx';
$this->Email->msg = 'blabla..';
$this->Email->send();
in fact there is a lot of private properties and function inside this class but it's private.
Class has (single) responsibility to do something.
Encapsulation is to publish only what people use to do that thing and keep technical/infrastructure inside as private.

Protected mutators (setters)

Problem
Suppose you have a class user. You want to be able to return this user object to others so they can use it to extract information using getters. However, you don't want people to be able to readily set the internal state because the internal information should directly relate to a row in the database. Does it make sense to have protected mutators (setters) so that only an extended class could set the variables? Is this a bad practice, irrelevant, overkill or useless?
I have considered trying to limit __construct to one use ( I believe this is sometimes refereed to as a singleton pattern - although I am not sure if I understand entirely. )
I am an amateur programer, forgive any ignorance. Thanks.
Example:
<?php
class user
{
private username;
protected function set_username($username)
{
$this->username = $username;
}
public function get_username()
{
return $this->username;
}
?>
Depends. If nothing in particular needs to happen when the state is changed then you can leave the setters out altogether. Any subclass will have direct access to the properties that are set protected or looser.
If you need something to happen when the state changes (for example having a database UPDATE happen when the state changes) then the setters will make your life a lot easier, as the call to the database updating code be put in the setter. This means if you always go through the setter then the DB will always update when you change the object's state.
So in short, it depends.
If you have a constructor that accepts an id for instance, why would you want to have setters at all. There is no rule forcing you to give an object setters just because it has getters. If your usecase is constructing the object somewhere and after that only use it to extract data from it, simply create no setter at all.
Extending objects can manipulate the protected class variables itself so they don't require any form of setter as well. If you don't want the "outside world" to be able to set something to the class, don't allow it.
Your code is totaly fine and IMHO it encapsulates perfectly. Tt also supports loose coupling.
For easier use, you can add all needed (must have) members as constructor parameters.
Regarding the singleton pattern, use it with care. Users in common aren't singletons. Refer to Refactoring to Patterns (Joshua Kerievsky).

The advantage / disadvantage of private variables?

I'm used to make pretty much all of my class variables private and create "wrapper" functions that get / set them:
class Something{
private $var;
function getVar(){
$return $this->var;
}
}
$smth = new Something();
echo $smth->getVar();
I see that a lot of people do this, so I ended up doing the same :)
Is there any advantage using them this way versus:
class Something{
public $var;
}
$smth = new Something();
echp $smth->var;
?
I know that private means that you can't access them directly outside the class, but for me it doesn't seem very important if the variable is accessible from anywhere...
So is there any other hidden advantage that I missing with private variables?
It's called encapsulation and it's a very good thing. Encapsulation insulates your class from other classes mucking about with it's internals, they only get the access that you allow through your methods. It also protects them from changes that you may make to the class internals. Without encapsulation if you make a change to a variable's name or usage, that change propagates to all other classes that use the variable. If you force them to go through a method, there's at least a chance that you'll be able to handle the change in the method and protect the other classes from the change.
It differs from case to case if you want to use private variables with public getters and setters or if you just want to declare a variable as public directly.
The reason it might be good to use "getters" and "setters" is if you want to have control over when someone accessess the data.
As an example, lets say you got this:
public setBirthday($date)
Then you can make sure that the date passed in to that setter is a valid birthdate.
But you can't if you just declare the variable as public like this
public $birthday;
Based on comments.
Also, if you decide change the
internal storage mechanism from a
string containing the date to the
number of seconds since 1/1/1970, you
can still present the date externally
in the same way if you use
encapsulation, but not if you expose
the variables directly. Every piece of
code that touched the internal
variable directly would now be broken.
This means that if the internal storage mechanism would change to numbers of seconds from 1/1/1970 then you don't have to change the 'External API'. The reason is because you have full control over it:
public getBirthday() {
// you can still return a string formatted date, even though your
// private variable contains number of seconds from 1/1/1970
}
Access modifiers don't make a whole lot of sense in scripting languages. Many actual object-oriented languages like Python or Javascript don't have them.
And the prevalence of naive getter/setter methods is simply due to PHP not providing an explicit construct for that. http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/
It is to demark variables that are internal to the implementation of the class, from variables that are intended for external change. There are also protected variables, which are for internal use, and use by extensions to the class.
We make the variables private so that only the code within the class can modify the variables, protecting interference from outside, guaranteeing control and expected behaviour of the variable.
The purpose of encapsulation is to hide the internals of an object from other objects. The idea is that the external footprint of the object constitutes it's defined type, think of it like a contract with other objects. Internally, it may have to jump through some hoops to provide the outward-facing functionality, but that's of no concern to other objects. They shouldn't be able to mess with it.
For example, let's say you have a class which provides calculations for sales tax. Some kind of utility service object, basically. It has a handful of methods which provide the necessary functionality.
Internally, that class is hitting a database to get some values (tax for a given jurisdiction, for example) in order to perform the calculations. It may be maintaining a database connection and other database-related things internally, but other classes don't need to know about that. Other classes are concerned only with the outward facing contract of functionality.
Suppose sometime later the database needs to be replaced with an external web service. (The company is going with a service for calculating sales tax rather than maintain it internally.). Because the class is encapsulated, you can change its internal implementation to use the service instead of the database very easily. The class just needs to continue to provide the same outward facing functionality.
If other classes were mucking around with the internals of the class, then re-implementing it would risk breaking others parts of the system.

Categories