Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm trying to learn PHP OOP, but when I've followed tutorials, all the examples seem to involve things like:

class Human {
    $_sex;

    public function setSex($sex) {
        $this->_sex = $sex;
    }

    public function getSex() {
        return $this->sex;
    }
}

(Pointless example, but hopefully you get what I mean -- An object has properties that are stored in the object.)

I've never come across a web application where I've needed to create objects about humans, dogs, cars, or any of the other weird examples you find when reading tutorials about OOP...

So I'm trying to find a similarly simple, but more realistic, project with which to learn OOP. I've chosen a website for an internet comic (e.g. XKCD.com). (This would allow people to view the comic, but also the author to edit and update it.)

So how would this translate to real-world PHP OOP?

My initial instinct would be to break the objects down thusly:

  • Catalogue
  • Episode

Where the Catalogue class would contain methods pertaining to all the episodes of the comic, e.g. getMostRecentEpisodeID(), deleteEpisode($episodeID), addNewEpisode($newEpisode), etc. etc.

And Episode would contain methods pertaining to the individual episode, e.g. getEpisodeComments($episodeID) (if the website allowed people to leave comments on individual episodes), editEpisode($episodeID), getEpisode($episodeID), etc.

Is this right, or have I made an absolute hash of what OOP is for?

Edit: Rather than just giving me a list of examples, it would really be helpful if your answer made specific reference to the problem I'm trying to solve.

Thanks.

share|improve this question
3  
You'll find a lot of real world examples on our sister site Code Review. This search would be a good place to start. If you build your project, you should post the full code there for review. –  Yannis Rizos Feb 20 '13 at 17:58
    
@YannisRizos Thanks! Would Code Review be able to tell me if my understanding is correct? –  Django Reinhardt Feb 20 '13 at 18:41
1  
Code Review is strictly for reviews of working code, so don't post there unless your code is actually working. Questions on design choices are more suitable for Programmers in general. This one has a few problems, we generally frown upon questions asking for lists of things, so we might need to rephrase the request for real world examples a bit. I'll take a closer look when I'm off work. –  Yannis Rizos Feb 20 '13 at 18:45
    
I don't know PHP but I could give you that in Java. –  user61852 Feb 20 '13 at 20:29

2 Answers 2

up vote 3 down vote accepted

The problem with Object Oriented Programming is exactly that, the shape and vehicle examples. What I'm going to type below is not the actual truth, it is an opinion. An opinion shared by more people than just me though :)

Object oriented vs "Class oriented"

Your example where there would be a catalog and an episode is perfectly well. The problem is the functions you propose these Objects should get. That is where you go from Object Oriented Programming to Class Oriented Programming. Just fitting a lot of methods concerning the same concept in an Object doesn't make programming object oriented. All you do is make some sort of container for methods.

The Episode Object should be just an Object that "models" the Episode. It has a title, content, author, that kind of stuff. In no way should this Episode have access to the database. It is not supposed to save itself or be able to load more instances of other episodes. The same goes for Catalog, it should not be able to retrieve its newest Episode itself. A catalog is a model, it has a title and some other stuff.

Splitting up responsibilities

Getting stuff from and saving stuff to a DataBase is not a models responsibility. So someone else has to do the job. A good start might be to create a CatalogRepository which could look like so:

CatalogRepository
{
    /**
     * @param int $id
     * @return Catalog
     */
    public function getCatalogById($id)
    {
        //Do a query, populate a new Catalog and return it. 
        //The constructor of Catalog should not be the one quering! 
        //It should receive data, nothing more
    }

    /**
     * @param Catalog $Catalog
     */    
    public function saveCatalog(Catalog $Catalog)
    {
        //stuff....
    }

    /**
     * @param string $name
     * @return Catalog[]
     */    
    public function searchCatalogsByName($name)
    {
        //do a full text search or something?
    }
}

The Episode would have something along the same lines where you could get all Episodes for a specific Catalog but also the five most popular Episodes:

class EpisodeRepository
{
    /**
     * @param Catalog $Catalog
     * @return Episode[]
     */
    public function getEpisodesByCatalog(Catalog $Catalog)
    {

    }

    /**
     * @param int $amount
     * @return Episode[]
     */
    public function getMostPopularEpisodes($amount)
    {

    }
}

There are some really good guidelines for writing good object oriented code, take a look at SOLID for instance

share|improve this answer
    
While the SOLID principles are excellent, I still advise people new to OOP to try to understand cohesion and coupling (which underly SOLID, or rather, SOLID answers the question "how do we achieve the desired levels of cohesion and coupling"). It took me a longer time than I like to admit to really understand those two, but it was a "lights on" moment when it finally came. Although I've linked the Wikipedia article here, I'd recommend reading several different viewpoints to try to grasp it intuitively. –  Daniel B Feb 21 '13 at 11:39

Is this right, or have I made an absolute hash of what OOP is for?

It's not right, but also not completely wrong.

The main point of OOP is that classes aren't just collections of methods, but also contain the data those methods operate on - you wouldn't call editEpisode($episodeID), but instead $episode->edit(). This has two advantages:

  • Less passing around of data, which leads to less cluttered function signatures and less potential for errors.
  • By making the data (fields) private, it's possible to control access to it and allow only those operations on it that make sense.

For a real-world useful example, look at mysqli and compare its procedural and its OOP API. The procedural one requires you to pass a link, statement or result handle to almost every method, while the OOP API doesn't need that because you call the methods on an object. Additionally, the OOP method names don't need the mysqli prefix.

It's not a big difference, but still leads to nicer code, and of course that's just the beginning.

share|improve this answer
    
... not that mysqli was a good piece of OO design (me being a maintainer) a "true" OO interface might be much more advanced, but mysqli was created in the early days of PHP 5 development by C developers taking their first steps –  johannes Feb 21 '13 at 0:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.