OOP: Composition and public property? - php

So lets say I have a class that is composed of other classes.
class HttpRequest
{
public $session = new Session();
// .. the rest of the HttpRequest code
}
Now, I want to have access to Session class through HttpRequest class so Im using composition.
But does this breaks laws of OOP Encapsulation or Data hidding that states that all properties should be protected, and accessed through setter and getter methods?
Is this wrong:
$request = new HttpRequest();
$request->session->set('id', 5);
or should I use this:
$request = new HttpRequest();
$session = $request->getSession();
$session->set('id', 5);
Encapsulation states that properties shoud be protected.
How to provide access to inner classes then? Is the first example wrong as far as proper OOP goes?

There are valid reasons to not allow direct access to the object:
Allows for manipulation of the object outside of the object itself. If you make the property public, any part of your code could overwrite $session on the HttpRequest class, and you'd have a tough time tracking it down. Encapsulation from a data protection standpoint is there to ensure that only the object's methods can directly alter the object.
Allows you to gracefully handle the case in which that variable is not set. If, for some reason, $session does not get set on your class - you'll immediately have a fatal when you try to call a method on it. If you wrap it in a getter, you could check for that condition and create a new instance of the class on the fly.
Follows true "OO" paradigms
However, in some cases I would say it is okay to do this. Particularly if you know that the property will always be set (and the only way in which it would not be set is not a supported way to use the object).
It also makes sense depending on how the property is going to be accessed. Symfony2 uses this in their Request classes. It feels natural in that case, as the "query" "post" and "request" vars are all "ParameterBag"s (glorified arrays). However, they do expose a getter for the Session object - likely because of it's use case.
In short: it really depends on how you'll be using the variable. In this particular case, I'd say it doesn't much matter.

I like your first option, (It's the one using composition), and look that has encapsulation (I don't know what makes the function set), but I suppose that it's modifying some attribute through the function of the "component" object "session", that pattern is also known as "delegation".
On the other hand if you use encapsulation you cannot user "public", that is allowing to be modified for everybody. It's because of this that you user setters or getter, or in your code "set"

I know this is old, but I would use neither of these. Does your HttpRequest object really need to hold onto the Session object or can a Session object be passed into some functions of the HttpRequest object that need it? Is there a strong case for having HttpRequest store this object?

Related

php: "Dynamic Class Instantiation" what is the purpose of this pattern\snippet

I reading the following article and got very confused on the "Dynamic Class Instantiation" part. Specifically this code snippet:
$obj = new $className();
if (!$obj instanceof SomeBaseType) {
throw new \InvalidTypeException();
}
I don't understand what this is actually doing for you. If its not an instance of a base class it errors out. How is that helpful? It doesn't get an instance of the correct type, or perform a different action based on the current type, it just throws an exception. I'm having trouble conceptualizing the purpose of this code and the article didn't really clear it up for me.
---------Complete section from the article----------
"Dynamic Class Instantiation
Generally speaking, the following code, while legal, should be used very seldom, and only when other possible instantiation patterns have been exhausted:
$obj = new $className();
if (!$obj instanceof SomeBaseType) {
throw new \InvalidTypeException();
}
Why is this a bad pattern? First, it makes the assumption up front that the constructor signature is free from any required parameters. While this is good for object types that are already known to this factory, it might not always be true of a consumers subtype of the base object in question. This patten should never be used on objects that have dependencies, or in situations where it is conceivable that a subtype might have dependencies because this takes away the possibility for a subtype to practice constructor injection.
Another problem is that instead of managing an object, or a list of objects, you are now managing a class name, or list of class names in addition to an object or list of objects. Instead, one could simply manage the objects.
If, on the other hand, you know this particular object type is no more than a value object (or similar), with no chance of it needing dependencies in subtypes, you can then cautiously use this instantiation pattern."

Global vs function vs static class method

Let's say you have a object that is unique, and it's used by all other classes and functions ...something like $application.
How would you access this object in your functions?
using a global variable in each of you functions:
global $application;
$application->doStuff();
creating a function, like application() that instantiates the object into a static variable and returns it; then use this function everywhere you need to access the object:
application()->doStuff();
create a singleton thing, like a static method inside the object class which returns the only instance, and use this method to access the object:
Application::getInstance()->doStuff();
KingCrunch & skwee: Pass the application object as argument to each function/class where is needed
...
public function __construct(Application $app, ...){
....
If there are other options please post them. I'm wondering which of these options is the most efficient / considered "best practice".
I'd pass it to all the needed methods.
i.e.
function doFoo(Application $app) {
$app->doStuff();
}
Both global and singleton considered bad and ties your code too much and this makes unit testing more difficult.
There is one rule when you are allowed to use singleton, if you answer "yes" to the following statement:
Do I need to introduce global state to my application AND I must have a single instance of given object AND having more than one instance will cause error
If you answer yes to all the 3 parts then you can use singleton. In any other case just pass all the instances to all the method who needs them. If you have too much of them, consider using something like Context
class Context {
public $application;
public $logger;
....
}
========
$context = new Context();
$context->application = new Application();
$context->logger = new Logger(...);
doFoo($context);
========
function doFoo(Context $context) {
$context->application->doStuff();
$context->logger->logThings();
}
(you can use getters/setters if you need to protect the data or manipulate it or if you want to use lazy initiation etc).
Good luck!
Singletons, God Classes, monolithic classes, etc. are all anti patterns, so I would suggest a fourth option: dependency injection. You can create an instance of application in your application via a factory (or perhaps even new if it has no dependencies, but this can end up complicating things later).
Then, any class that needs access to application can get it as a member, helpfully via the constructor. I'm sure that not every class needs access to application. Remember the Law of Demeter.
If you need some generic functionality like converting one static string to another, I suggest using php's global functions (as opposed to, for instance, a faux static class). I believe they were designed for that purpose.
Or just give it to the ones, that are interested in it. All the suggestions you made are like global variables, even if you call it not that in 2 of 3 variants.
Before it comes to that: If you want to say "Thats not possible, because everything needs it", than maybe it does too much, can too much, and/or knows too much.

In PHP, how can I unserialize into the current object?

This is probably a noob question, so please be kind.
I'm trying to implement a cache on an expensive "activity" object. In the constructor I first check the cache to see if this Activity instance already exists. If not, I do all the queries to build up the object, serialize it and save it to cache. The next time I come in, I check the cache and my object is there, so I unserialize it. Now is my problem, how do I put that object into $this, the current object? I can't just say "$this = unserialize($row[0]);" That fails with the error message, "Cannot re-assign $this in ActivityClass.php". What am I missing?
Thanks a ton!
Mike
If you don't want your construction to leave the class, you can create a factory method:
class Activity
{
public static function Create(/* your params */)
{
// construct cache and key, whatever
$obj = unserialize($cache->get($key));
if ($obj) return $obj;
return new Activity(/* params */);
}
// rest of your stuff
}
You'll have to serialize only your object's internal state, i.e. its parameters (aka "member variables"). In fact, in this instance, serialize() isn't really what you want to do; rather, you want to store your ActivityClass's data to your cache, not the serialization of the entire object. This gets tricky, though, because as you add new parameters later you need to remember to store these in your cache as well.
Alternatively, you can implement a singleton or factory pattern for your ActivityClass. Since you say you're pulling the class from the cache in the constructor, I take it that only one instance of this class is meant to exist at any given time? In this case, you should make your class a singleton, by doing the following:
Make the __construct() method private or protected.
Create a public static method (I tend to call this getInstance()) that will check your cache for the object, or instantiate a new one and then cache it.
Now instead of directly instantiating a new ActivityClass object, you instead write $foo = ActivityClass::getInstance();, which gives you either a new object or unserializes and returns your cached one.
As you noticed, you cannot just override the current object as a whole.
Instead, a possibility would be to store the data you're serializing/unserializing into a property of your object.
This way, you wouldn't serialize your whole object, but only one of its properties -- and only that single property would be overriden when unserializing.
Typically, you wouldn't serialize the connection to the database, which could be another property of your object.
Another possibility would be to not have your object deal with its own (de-)serialization.
Instead, you should :
Use an external class to instanciate your object
With that external class being responsible of either :
Loading data from cache and pushing it into your object,
Or calling the right method of your class, to load data from the database -- and, then, save that object to cache.

PHP OOP: Avoid Singleton/Static Methods in Domain Model Pattern

I understand the importance of Dependency Injection and its role in Unit testing, which is why the following issue is giving me pause:
One area where I struggle not to use the Singleton is the Identity Map/Unit of Work pattern (Which keeps tabs on Domain Object state).
//Not actual code, but it should demonstrate the point
class Monitor{//singleton construction omitted for brevity
static $members = array();//keeps record of all objects
static $dirty = array();//keeps record of all modified objects
static $clean = array();//keeps record of all clean objects
}
class Mapper{//queries database, maps values to object fields
public function find($id){
if(isset(Monitor::members[$id]){
return Monitor::members[$id];
}
$values = $this->selectStmt($id);
//field mapping process omitted for brevity
$Object = new Object($values);
Monitor::new[$id]=$Object
return $Object;
}
$User = $UserMapper->find(1);//domain object is registered in Id Map
$User->changePropertyX();//object is marked "dirty" in UoW
// at this point, I can save by passing the Domain Object back to the Mapper
$UserMapper->save($User);//object is marked clean in UoW
//but a nicer API would be something like this
$User->save();
//but if I want to do this - it has to make a call to the mapper/db somehow
$User->getBlogPosts();
//or else have to generate specific collection/object graphing methods in the mapper
$UserPosts = $UserMapper->getBlogPosts();
$User->setPosts($UserPosts);
Any advice on how you might handle this situation?
I would be loathe to pass/generate instances of the mapper/database access into the Domain Object itself to satisfy DI - At the same time, avoiding that results in lots of calls within the Domain Object to external static methods.
Although I guess if I want "save" to be part of its behaviour then a facility to do so is required in its construction. Perhaps it's a problem with responsibility, the Domain Object shouldn't be burdened with saving. It's just quite a neat feature from the Active Record pattern - it would be nice to implement it in some way.
What I do, albeit maybe not the best course of action, is to have a clear naming convention for my classes, FI: user_User is the domain object and user_mapper_User is it's mapper.
In my parent domainObject class I code the logic to find it's mapper.
Then you have a couple options to delegate to it, an obvious one would be to use the __call() method in domainObject.

Parameters vs. Attributes(class variables)?

In OOP, is it better to use class attributes within class functions, or just pass parameters to them.
class User{
private $user = array();
public function Get_Existing_User($user_id){
//SQL selects user info for existing user
$this->user = mysqli_fetch_assoc();
}
public function Set_User($user_data){
$this->user = (array) $user_data;
}
public function Add_User(){
//insert everything from $this->user into database
}
public function Get_User(){
return $this->user;
}
}
VS
class User{
public function Get_Existing_User($user_id){
//SQL selects user info for existing user
$user = mysqli_fetch_assoc();
return $user;
}
public function Add_User($user_data){
//insert everything from $user_data into database
}
}
Whats the better way to go?
Between your solutions, first is better, but you have to change the names of the functions. 'get' should be used only if function returns something.
The reason it is better is that it doesn't use side effects, side effects always bad as they are invisible to user of the class but change class behavior. So you should try to minimize them or make them obvious as they are in the first case, when they not really 'side'.
But in this particular case, Get_Existing_User and Add_User should be static functions, that return new User object, it is sometimes called as static constructor. The reason why it is much better is that it makes it clear what that functions do, they get something as parameter (user_id of existing user or first_name, last_name and other attributes for a new user) and create an object that represents the user. All database manipulation will be hidden away. Object itself should have properties for name and other attributes and even Save() method to push the changes back. But main idea is that you always work with constructed object, object that already have context and linked to something in the real world (that is, user in the database), not an empty shell that will be filled in as you go.
Some clarification on terminology first:
What you call class functions are more properly called methods. A method is a function on an object instance. Additionally, classes may have methods. These are called class methods or static methods. When you use the term class function, you are thus confusing the meaning.
That settled, there is no worse or better of the two approaches. You would use both, depending on the context. Parameters have a smaller scope, and thus cause less coupling. If everything else is the same, I would therefore say that parameters are preferable to setting an object property.
That said, there are usually other factors that can determine which to pick. You can think of an object as a scope for related variables. If a variable belongs to that scope, it would make sense to assign it to a property.
Class attributes are expected to describe the state of an instance of the class known as an object. As such, the attributes can be used by any function of the class to modify it's state. Function parameters on the other hand may have nothing to do with the current state of the object but can be used to modify it's state.
For example: a user object could be expected to have a user name attribute, a password attribute, and an authenticated attribute. this user object also has a function called authenticate that takes a parameter which describes an authentication method. The parameter is used to modify the state of the user object but would not be held as an attribute of it.
That entirely depends on wether you're going to re-use the data and how you're using the Class.
If you create many individual instances of the Class and each Object represents a unique user, it makes sense to persist the data in a member variable. If you're using the Class as a DAO (data access object) with a lot of one-off operations, it probably doesn't make a lot of sense to persist the data. But even in a DAO, depending on its inner workings, it might make sense to store the data at least temporarily in a member variable if there are many functions involved in a single call (like beforeQuery and afterQuery callbacks or the like).
There's no one-better-way-fits-it-all.
It is important that you choose the method that best suits your situation. Ignoring that not-so-helpful suggestion I encourage you to take a good look at some important principles in Object Oriented Design
Coupling
Cohesion
A strong understanding of these topics will help you assess your situation and code to suit the goals of the project. As your project grows, you'll likely find that you'll want to use methods that have optional parameters to interact with your objects to achieve high cohesion and loose coupling. Then you'll use methods and parameters like an expert.

Categories