1

I'm trying to understand OOP and having some trouble with a couple of concepts as I try to make the code workable and testable.

What if I have two tables: users and logins and I want to get all the logins for a specific user but also the user information, like name, job title, whatever.

$mdlLogins= new Logins();
$mdlUsers = new Users();
$mdlUsers->setMdlLogins($mdlLogins);
$mdlUsers->getAll();

class Logins
{
    function getLogins($user_id)
    {
        // db query by $user_id and fetch loop into $logins
        return $logins;
    }
}

class Users
{
    function setMdlLogins($model)
    {
        $this->mdlLogins = $model;
    }

    public function getAll()
    {
        // db query
        foreach ($user=mysql_fetch_object($result))
        {
            $this->users[] = $this->mdlLogins->getLogins($user->getID());
        }
    }
}

Is that right? Or, should I be using static methods (skip the ->setMdlLogins() and change getLogins to Logins::getLogins($user->getID()))? Why not just use a regular function: get_user_logins()?

What if I wanted to create a User object with Logins and each logins shows the Posts during that login and each Post shows the number of people who Viewed the post? Would it be best to use static methods to pull all that in, or create empty objects and inject them as dependencies:

$mdlViews = new Views;
$mdlPosts = new Posts;
$mdlPosts->setViews($mdlViews);
$mdlLogins = new Logins;
$mdlLogins->setPosts($mdlPosts);
$mdlUsers = new Users;
$mdlUsers->setLogins($mdlLogins);
$mdlUsers->getAll();

seems like a lot of work ... is that just too much for one object or it that typical of an object but maybe I should be less worried about unit testing and just use static methods instead of setting so many models the original model depends on?

How to keep things OOP, Unit Testable, but not make it so complicated?!?

I'm pretty dense about this stuff but I really want to understand it before starting my next probjects in January so I don't create a nightmare.

Thanks, Hans

Hans
  • 3,403
  • 3
  • 28
  • 33
  • I have a lot of trouble understanding what the goal of this program is, with the lack of punctuation in your explanations. Since I don't know what all this is supposed to do, it's very hard to suggest a solution. – netcoder Dec 23 '10 at 21:41
  • @netcoder - I don't understand the fundamentals of OOP so I'm using this as an example so that I may get a better understanding. I'll edit the question to make this clear. – Hans Dec 23 '10 at 21:43

2 Answers2

1

Read this: Static Methods and Properties. Read the entire thing you'll only know more after wards. It helped me a lot.

Babiker
  • 18,300
  • 28
  • 78
  • 125
1

What @Babiker linked to helped but this SO question was the most useful to me:

When to use static vs instantiated classes

It's not particularly about what I was after -- how to inject different dependencies -- but it does help me understand when to use static and when to instantiate.

@grantwparks said:

If I have a set of functions that are related in subject matter, but instance data is totally inappropriate, I would much rather have them defined in a class and not each of them in the global namespace. I'm just using the mechanics available in PHP5 to

* give them all a namespace -- avoiding any name clashes
* keep them physically located together instead of becoming scattered

across a project -- other developers can more easily find what's already available and are less likely to re-invent the wheel * let me use class consts instead of global defines for any magic values

And now I see why people are doing that. I was always lost, wondering why they didn't just create a regular ole function for it.

@troelskn said:

I would suggest that - as a beginner in oop - you try to avoid static members all together. It will force you in the direction of writing in an object oriented rather than procedural style.

That helped me, too because it made it clear, from @troelskn's perspective at least, that static members are more procedural that OO, which is something that I'd thought, too, but wasn't sure of.

@Michael Aaron Safyan said:

Using member data and member functions allows you to reuse your functions for multiple different pieces of data, whereas you can only have one copy of data on which you operate if you use static data and functions.

More re-inforcement.

The answer from @Ionuț G. Stan was the most important to me, though, especially:

The main idea is to decouple the dependencies out of your classes. This way the code is much more extensible and, the most important part for me, testable. Why is it more important to be testable? Because I don't always write library code, so extensibility is not that important, but testability is important when I do refactoring. Anyways, testable code usually yields extensible code, so it's not really an either-either situation.

So, while not the perfect answers, combined they helped me understand this a lot more and I think that I'm beginning to understand all of this much better.

Community
  • 1
  • 1
Hans
  • 3,403
  • 3
  • 28
  • 33