2

I would like your advice on how to design objects in modular CMS system. I've been searching for hours but I just couldn't find right answers.

How to design the classes for interaction with things? Lets say I have these classes:

cDb() // for database interactions
cUser() // for all user actions
cSession() // for interactions with session data.
cAnotherObject // multiple another objects from future modules

Should I somehow extend them all, so in the end, I end up with one object like this:

$myvar = new cLatestClass(); 

[cSession extends cDb, cUser extends cSession ... etc.]

If so, how to do it with dynamicly loaded classes in modules? Is it better to just use multiple vars holding the objects?

$user = new cUser(); 
$session = new cSessions();
 ... etc.

I really hope somebody in here can answer me and hopefully teach me how to do it properly.

totymedli
  • 29,531
  • 22
  • 131
  • 165
mchamuty
  • 113
  • 8

2 Answers2

3

First of all I would recommend taking a step back and learning what object orientation is all about. Alan Kay, who coined the term "object-oriented programming," once described it as follows:

I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages. (source)

In PHP (and in most object-oriented languages), those messages are usually method calls, or in the case of public properties, getting and setting their values.

So think about the objects in your system as individual cells in a larger organism that collaborate to achieve a greater goal, rather than about trying to mix all the behavior you need together into one object.

This is a large topic, and many books have been written on it, but in terms of the objects you mentioned in your question, I would first make a differentiation between the different categories they fall into. A database or session object can be thought of as a type of "service" on which other objects (for example your Controllers, if you're using an MVC framework) will depend. As others have mentioned, dependency injection is a good solution for handling such services, but in most cases I wouldn't recommend using it for something like a User class, for which there should be one instance per user (not literally of course - you'd only load the specific user objects into memory that you need to handle a particular request, in many cases just an instance for the current user).

To learn more about dependency injection, I recommend this article where Martin Fowler coined the term, and also where he mentions a simpler alternative to a dependency injection container called a Service Locator.

(The dependency injection container approach is more robust but also more complicated; fortunately there's a good open-source library for it).

User, Article, and Category would all be examples of domain objects in a CMS. These are part of the "M" (Model) of MVC (also known as the domain model). Of course you still need a way to get these objects in and out of the database, so you'll probably also need some sort of Repository or Query classes (a Repository class can be considered a service). Not all PHP systems have true domain objects; many just have repository-like classes that return arrays or stdClass objects (simple, anonymous objects created like this: $someObj = new stdClass), which means that these systems fall short of true object-oriented programming, but there are often practical reasons that such decisions are made.

The real purpose of object-oriented programming goes deeper than what I've mentioned above: it's about designing the objects in a system to reflect our mental model of it (a joint mental model that includes the perspective of both end users and the programmers). Here's another good quote, this time from Trygve Reenskaug, who invented the MVC pattern:

I think of the difference between procedure oriented and object oriented programming as being that procedure oriented answers the question: "What happens?". Object oriented answers an additional question: "Who does it?" (source)

Finally, I'd recommend reading a book that specifically covers object-oriented programming in PHP. A very good one is PHP Objects, Patterns and Practice by Matt Zandstra.

Matt Browne
  • 12,169
  • 4
  • 59
  • 75
  • 1
    Thank you for your exhausting answer :) I'm going to read through those articles you pointed out. I really appreciate that you invested your time into this answer, this is why I knew it was good idea to ask here on stackoerflow! :) – mchamuty Jun 23 '13 at 08:11
  • You're welcome. BTW I think you meant "exhaustive", not "exhausting", although I can see how my answer could be exhausting too! ;) – Matt Browne Jun 23 '13 at 12:34
1

Should I somehow extend them all, so in the end, I end up with one object like this:

No you certainly should not. When extending classes you should have an is-a relation.

A session is not a database. And a user is certainly not a session. What you are looking is likely to be dependency injection.

Lets say your User class needs a database connection. That would look something like:

class User
{
    private $dbConnection;

    public function __construct(\PDO $dbConnection)
    {
        $this->dbConnection = $dbConnection;
    }

    public function doSomethingWithDb()
    {
        $this->dbConnection->query('SELECT...');
    }
}

$dbConnection = new PDO('/* dsn string */', 'user', 'pass');
$user = new User($dbConnection);

It would be even better if you would extract the database query away from the User class so that you are not bound to using a database it all.

Also as a CS note: why do you prepend your classes with c?

Regarding your module system. That will depend how you are going to setup your modules, but you might need to look into a dependency injection container to wire together the dynamic modules.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
  • Don't mind the "c", just a silly habit :D I don't do it in most of my projects :) I just started that because of example in one book :) But thank you for answer, i'll lok into dependency injections later today :) Thank you! :) – mchamuty Jun 23 '13 at 08:12