SitePoint Sponsor

User Tag List

Results 1 to 23 of 23

Thread: OOP Advantages?

  1. #1
    SitePoint Guru augathra's Avatar
    Join Date
    Jul 2004
    Location
    united states
    Posts
    826
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question OOP Advantages?

    Hello, I was reading up on OOP and how it's useful. The examples they gave didn't seem logical, and I am hoping someone could give me a real life example. Maybe producing a large script like a forum, how could you use OOP to make it more readable?

    Thank you

  2. #2
    SitePoint Wizard silver trophy someonewhois's Avatar
    Join Date
    Jan 2002
    Location
    Canada
    Posts
    6,364
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's just another way of controlling flow. Excuse my anology (no offense intended at you, just the only way I can explain it), but it's the same as saying why use if/elseif/else isntead of just if/exit. (Or going back to C, why use if/elesif/else instead of goto).

    It's personal preference in PHP (at least, I would, I would say). There's little labour overhead in OOP, so it really doesn't take much more time to actually write it. You can reuse classes (ie. abstraction classes) over and over, you can eliminate globals all together, and it really is just an organizational thing... one of the few scope layers that PHP has.

  3. #3
    SitePoint Guru
    Join Date
    Jul 2004
    Location
    Raleigh, NC
    Posts
    783
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i'm a newbie at the subject but here's how i understand it: programming without OOP is having sets of variables, loops, statements, conditionals, etc, all interacting in a way that makes sense in the scope of the entire program. OOP breaks that down further and makes parts relate to each other in the way that they are supposed to.

    before OOP, you'll have a handful of variables and functions that you the programmer understand to relate to each other: $a is the height of $b. $c can be added to $d but not $e. these are all things you understand so it works in small doses. in large doses though, wouldn't it be nice if these pieces inherently did relate to each other in these ways?
    enter OOP. now $a is not a random variable that the programmer alone understands to be the height of $b. $b is an Object. $b->a is it's height. and if you look at the class that $b is an instantiation of, you can see exactly how they relate. if height will always equal the square root of area/width, you can look in the class and know exactly what each part is and how they relate to each other. when you later realize that height is actually equal to the square root of area/(width-squared). you know to return to that class, change that one thing, then every other rectangle object in the program will also become correct. trivial example, but this will be true with any object from that class and you will fix them all with a few keystrokes

    WHY NOT FUNCTIONS THAT DO THE SAME THING? this was my biggest question. because you can do ANYTHING that oop can do with procedures... eventually. you can also write your program in binary or assembly code instead of php. php isn't just easier. it maturely organizes the data in ways that relate to each other in the most logical and complete fashion. 01110001 is the same as "q" but "q" actually means many things that 01110001 doesn't. it is inherent in the Object of "q" that it is in the category of 'consonants' and that it must be followed by u except for in a certain number of rare cases. 0110100001100101011011000110110001101111 is the same as hello but again, "hello" has deep syntactical meaning and rules that it abides by. could you imagine someone reading a book to you one letter at a time without it being in the context of words, sentences, and paragraphs?

    as your code evolves to higher levels, it is important for each smaller piece to be self-reliant. naming conventions won't carry you forever. here's a simple one out of control so imagine a real world problem:
    $rabbit_one, $rabbit_one_fur_color, $rabbit_one_eye_color -or-
    $rabbit_one, $rabbit_one['fur_color']
    $rabbit_two, $rabbit_two['fur_color']
    (crap, i forgot the eye_color for #1. they used to all have black eyes until i got an albino...)
    $rabbit_three['eye_color'] (did i remember to set the fur_color for 3?)
    etc, etc, etc

    i'm going to stop rambling now and let the real masters have the floor

  4. #4
    SitePoint Wizard silver trophy someonewhois's Avatar
    Join Date
    Jan 2002
    Location
    Canada
    Posts
    6,364
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    $this->rabit['one']['fur_color'] is really how it should be done...

    Re: " WHY NOT FUNCTIONS THAT DO THE SAME THING? this was my biggest question. because you can do ANYTHING"

    As I said (though I take it you were typing while I posted mine), it's more of a scope thing. If you want to global all your variables, or you want to pass variables to each and every function, then use functions - if you want proper organization, you'll use class-scoped variables.

    I think PHP 4's OOP capabilities are so limited it really doesn't matter.. but it's a good technique to have.

    Another point I just remembered: Multiple instances. One of the biggest things of OOP is being able to carry multiple instances. Ie NOT:
    PHP Code:
     // Include file
     
    require('lib/db.php');
     
    $db = new Database('localhost''root''''whatever');
     
    //5 files later:
     
    $db->query('SELECT b FROM a');
     
    $r $db->fetch_row();
     echo 
    $r->b
    No. That's the last thing you want to do. If you do that, you're better off using functions.
    PHP Code:
      // Include file
      
    require('lib/db.php');
     
    // Standard connect here, doesn't really matter how you do it
      //5 files later:
     
    $q = new Query('SELECT b FROM a');
      
    $r $q->fetch_row();
      echo 
    $r->b
    Now you can have more than 1 query going at the same time, and you can stagger calls:
    PHP Code:
     $q = new Query('SELECT b FROM a');
     
    $s = new Query('SELECT b FROM s'); // Yeah, ignore the fact that these should probably be selected together..
     
    if ($q->rows() > 0)
     {
         
    $r $s->fetch();
     }
     else
     {
         
    $r $q->fetch_row();
     } 
    Using the old global $db method you have:
    PHP Code:
      $q $db->query('SELECT b FROM a');
      
    $s $db->query('SELECT b FROM s'); // Yeah, ignore the fact that these should probably be selected together..
      
    if ($db->rows($q) > 0)
      {
          
    $r $db->fetch($s);
      }
      else
      {
          
    $r $db->fetch_row($q);
      } 
    It's just a lot of remembering where everything is. OOP everything's inside the class, you don't have to be passing variables left right and center, and you don't have to worry about returning anything. 95% of my functions (other than SetVar and GetVar functions) don't return values, and don't have anything passed to them.

    Classes can be 1 function long if that's all you need - remember, functions should be precise (do 1 function), and classes should be the same on a greater level (that made a lot of sense, eh?). Don't have a global class that handles a bunch of misc functions - that defeats the purpose of OOP. Idealistically, each class should have a couple of parameters passed to it on initilization, and maybe a few things returned on termination. Everything else should be done within the class.

    Really, it comes down to one thing: Organization of code. All there is to it.

  5. #5
    SitePoint Guru augathra's Avatar
    Join Date
    Jul 2004
    Location
    united states
    Posts
    826
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Both your replies made sense. Someonewhois, your last 2 examples made a lot of sense, although *IM Personal Preference* I would find it easier for myself, even going back 2 weeks later and revamping code, to just write out the code w/o classes or functions. This is how *i* like it, but I don't always get what I want... =(

    So this brings me to my next question: If I am designing a script and plan to sell it, and no OOP was used, but it is very well commented, would this be considered a poor script? *gasp* long sentance, lol

    I still plan to learn OOP very well, as I find it neccessary to know everything I can to manage other developer's applications. Perhaps I don't completely still understand the benefits of OOP, dont actually grasp it with my small mind.

  6. #6
    SitePoint Wizard Chris82's Avatar
    Join Date
    Mar 2002
    Location
    Osnabrück
    Posts
    1,003
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The problem I see with the given examples is that they do not suggest how OOP is really better than normal procedural programming. The DB example is just a wrapper for the mysql_query functions. It offers a bit of abstraction as there are no specific calls to the db-dependent functions inside the code. But this could have also been done with procedural code.

    I can't come up with a better example, though.

  7. #7
    SitePoint Guru augathra's Avatar
    Join Date
    Jul 2004
    Location
    united states
    Posts
    826
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmm, forgot to mention, someonewhois, in your example :

    // Include file
    require('lib/db.php');
    // Standard connect here, doesn't really matter how you do it
    //5 files later:
    $q = new Query('SELECT b FROM a');
    $r = $q->fetch_row();
    echo $r->b;


    Why not just use a normal function like so:

    QueryThis($input);

  8. #8
    SitePoint Guru
    Join Date
    Jul 2004
    Location
    Raleigh, NC
    Posts
    783
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by someonewhois
    $this->rabit['one']['fur_color'] is really how it should be done...
    i was attempting to present a counter-example of a list of non OOP related vars. sorry for not being very clear

    Quote Originally Posted by augathra
    Why not just use a normal function like so:

    QueryThis($input);
    db abstraction classes are often used for everything else you can build in. ex: error handling, adding slashes, etc. personally, i think this reduces them to new procedural functions and not OOP but i may be missing the finer points of them. someone please correct me if they can explain why OOP db abstraction is better than procedural

  9. #9
    SitePoint Guru augathra's Avatar
    Join Date
    Jul 2004
    Location
    united states
    Posts
    826
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For me, it seems everything I can think of could either be done through a function or just normal code. I read the PHP Manual section about classes, and theirs too seemed like I could integrate functions to give the same readability, to me, and the same versatility.

    If anyone is using a class, and a fairly simple one that really cuts back on reproducing code, please post it. Im desparate to see a usable class.

  10. #10
    SitePoint Guru
    Join Date
    Jul 2004
    Location
    Raleigh, NC
    Posts
    783
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by augathra
    If anyone is using a class, and a fairly simple one that really cuts back on reproducing code, please post it. Im desparate to see a usable class.
    imho, it's difficult to unequivicably prove the benefits of classes in a small/simple script in a case where you couldn't do the exact same thing procedurally. the only exception i can think of is OOP esp in php5 has special methods/internal-functions that can execute upon certain activity: when the object is created, destroyed, copied, etc

  11. #11
    $this->toCD-R(LP); vinyl-junkie's Avatar
    Join Date
    Dec 2003
    Location
    Federal Way, Washington (USA)
    Posts
    1,524
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I still consider myself fairly new to OO PHP, but the biggest difference that I can see between OO and procedural PHP is that procedural code passes around variables, while OO PHP passes around both variables and objects.

    As has already been pointed out, properly written procedural code can be reusable just as OO code is. However, reuse of objects is where the edge lies, in my opinion.

    To use a real-life example, I have an application that formats output from my music collection trade list to a web page. I have a second application that creates an RSS feed from the same data. Both applications use the same db connection script and the same data collection script. However, each takes the same result object and uses it in a different class - one for output to my web page, the other for the RSS feed.

    Can you do almost the same thing with procedural code? Yes. These two applications were originally written that way, using functions. I rewrote them as OO code, not necessarily to make better code though, but to teach myself the OO way of doing it.

    I don't know that I've necessarily made a case for declaring OO coding to be the better way of doing these, but having had a taste of both, I prefer the OO approach.
    Music Around The World - Collecting tips, trade
    and want lists, album reviews, & more
    Showcase your music collection on the Web

  12. #12
    SitePoint Guru augathra's Avatar
    Join Date
    Jul 2004
    Location
    united states
    Posts
    826
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If I didn't make my scripts out of OOP, and they were quite large projects, would other developers see my scripts as bad though?

    One more question, this is off the subject, but you are all smart programmers, so... how secure is $_SESSION? Maybe that is a poorly defined question, maybe not. A webpage that explains the security of it would be quite nice.

    Thanks

  13. #13
    $this->toCD-R(LP); vinyl-junkie's Avatar
    Join Date
    Dec 2003
    Location
    Federal Way, Washington (USA)
    Posts
    1,524
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by augathra
    If I didn't make my scripts out of OOP, and they were quite large projects, would other developers see my scripts as bad though?
    The better question to ask, in my opinion, is what your shop standards are. Code would be considered bad if it didn't follow standards, never mind whether it was procedural or OOP.

    One more question, this is off the subject, but you are all smart programmers, so... how secure is $_SESSION? Maybe that is a poorly defined question, maybe not. A webpage that explains the security of it would be quite nice.

    Thanks
    You might want to start a new thread for this.
    Music Around The World - Collecting tips, trade
    and want lists, album reviews, & more
    Showcase your music collection on the Web

  14. #14
    SitePoint Guru augathra's Avatar
    Join Date
    Jul 2004
    Location
    united states
    Posts
    826
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Has anyone made a collection of all the PHP standards? Lol

  15. #15
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have a reasonable small, but complicated enough to show the merits of OOP, example in a project I wrote as a demonstration for a presentation at a conference:
    http://phpdatacache.sourceforge.net/

    This code allows you to cache PHP data and retrieve it at a later date. OOP magic starts happening when you realize there are two completly different back ends available for this code: the file system and Postgresql. This is pretty seamlessly hidden from the end used of the code by using several OOP patterns: strategy and factory. Each "back end adapter" is coded to support an identical API (Strategy) and the controlling object has a Factory method to instanciate the appropriate back end adapter and stores it as an attribute of the cache object to delegate to later for storing or retrieving data.

    More magic come from OOP becuase you can create more than one instance of a cache object, and these can each be running different back ends! All in the same script.

    Now all of this probably could be simulated by having a seriees of procedural functions that lookup data from a global hash table of what cache "instance" needs to talk to which back end, but overall the OOP makes maintaining and extending this code significantly easier than a proceedural model.

    My $0.02
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  16. #16
    SitePoint Wizard silver trophy someonewhois's Avatar
    Join Date
    Jan 2002
    Location
    Canada
    Posts
    6,364
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Darchangel
    i was attempting to present a counter-example of a list of non OOP related vars. sorry for not being very clear


    db abstraction classes are often used for everything else you can build in. ex: error handling, adding slashes, etc. personally, i think this reduces them to new procedural functions and not OOP but i may be missing the finer points of them. someone please correct me if they can explain why OOP db abstraction is better than procedural
    Yeah, my fault - I was too tired to fully read it.

    Chris - Yeah, I know, again, was the only example that came to mind.

    db abstraction classes are often used for everything else you can build in. ex: error handling, adding slashes, etc. personally, i think this reduces them to new procedural functions and not OOP but i may be missing the finer points of them. someone please correct me if they can explain why OOP db abstraction is better than procedural
    Though idealy database access should be done with a DAO, abstraction classes are the next best thing (long gap, but still). It handles errors, and handles variables.
    $q = mysql_query('SELECT name FROM a') or die(mysql_error());
    $r = mysql_fetch_object($q);

    Or:
    $q = new Query('SELECT name FROM a');
    $r = $q->fetch();

    Less code, handles errors (and the errors look nice.. I know few people that do an "or die()" and add nice fancy HTML in there) Doesn't make sense to copy and paste. Again, an organizational thing.

  17. #17
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by augathra
    Why not just use a normal function like so
    Can you write OO code without classes?

    I'm tempted to think that you can. An object can be represented by more than one class, so it seems perfecctly possible that an object could be represented with no classes too. It would probably get harder to manage an object if you didn't have a class to put it in, but I see no reason why it couldn't be done. Prefix each function with the object's name, data used by objects could be stored in associative arrays instead of encapsulated in a class. The only difference would be that you wouldn't be able to enforce the divisions between objects as easily as you can with classes, and it would take more code to do "inheritance". Interfaces would exist only in the documentation, but they could still be defined.

    The point that I'm getting at, is that just because you use functions in place of methods doesn't automagically mean you are coding procedurally. The same as using classes doesn't automagically mean you are coding in OO.

    So converting a class into a set of functions could produce code that still behaves in an OO manner even though the class is gone. You just have to do everything by hand (like passing around references) instead of letting PHP do the work for you.

    Douglas
    Hello World

  18. #18
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by DougBTX
    So converting a class into a set of functions could produce code that still behaves in an OO manner even though the class is gone. You just have to do everything by hand (like passing around references) instead of letting PHP do the work for you.
    I used to write C code this way (the jump to C++ was too much in one go for most shops). You do run into problems though. Going step by step you can decompose this...
    PHP Code:
    class Person {
        function 
    Person($email) { ... }

        function 
    sendEmail($message) {
            
    mail($this->_address$message);
        }
    }

    $person = new Person('me@there')
    $person->sendEmail('Hello'); 
    ...into this...
    PHP Code:
    function person_send_email(&$person$message) {
        
    mail($person['address'], $message);
    }

    $person = array('address' => 'me@there');
    person_send_email(&$person'Hello'); 
    Things get funky with polymorphism...
    PHP Code:
    class EmailContact {
        function 
    EmailContact($address) { ... }
        function 
    send($message) { ... }
    }

    class 
    SmsContact {
        function 
    EmailContact($phone) { ... }
        function 
    send($message) { ... }
    }

    class 
    Person {
        function 
    setPreferredContact(&$contact) { ... }

        function 
    sendMessage($message) {
            
    $this->_contact->send($message);
        }
    }

    $person = new Person();
    $person->setPreferredContact(new SmsContact('911')); 
    Trying to map this is tricky...
    PHP Code:
    function &contact_create_sms($phone) {
        
    $contact['sender'] = 'contact_send_sms';
        
    $contact['target'] = $phone;
    }

    function 
    contact_send_sms_contact($phone$message) { ... }

    function &
    contact_create_email_contact($address) {
        
    $contact['sender'] = 'contact_send_sms';
        
    $contact['target'] = $address;
    }

    function 
    contact_send_email($address$message) { ... }

    function 
    person_send_message(&$person$message) {
        
    $sender $person['contact']['sender'];
        
    $target $person['contact']['target'];
        
    $sender($target$message);
    }

    $person = array('contact' => create_sms_contact('911'));
    person_send_message($person'Hello'); 
    Things only get worse after this. Not that you would go this length in real life of course.

    As for the original post, the biggest advantage of OO is that it is very expressive for problems in the business domain. Contact and Person can be thought of as real world concepts. This makes it easier (although still hard) to get the code right in the first place and it also makes it easier to change things when you get the bahaviour of one of them slightly wrong.

    Also, because the fault lines of the code map the fault lines of the problem, changes usually involve only one chunk of code instead of an interconnected swathe. It is also easier to factor out common behaviour (such as Contact above) and so write less code.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  19. #19
    SitePoint Zealot
    Join Date
    Jul 2003
    Location
    Los Angeles
    Posts
    199
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by someonewhois
    Yeah, my fault - I was too tired to fully read it.

    Chris - Yeah, I know, again, was the only example that came to mind.

    Though idealy database access should be done with a DAO, abstraction classes are the next best thing (long gap, but still). It handles errors, and handles variables.
    $q = mysql_query('SELECT name FROM a') or die(mysql_error());
    $r = mysql_fetch_object($q);

    Or:
    $q = new Query('SELECT name FROM a');
    $r = $q->fetch();

    Less code, handles errors (and the errors look nice.. I know few people that do an "or die()" and add nice fancy HTML in there) Doesn't make sense to copy and paste. Again, an organizational thing.
    Error handling is really sweet in PHP5 with exceptions:

    PHP Code:
    $con Creole::getConnection(.....);

    try
    {
        
    // delete all the posts in this topic and the topic itself.
        
    $con->setAutoCommit(false); // start a transaction
        
    $con->executeUpdate("DELETE FROM posts WHERE posts.topic_id=$topic_id");
        
    $con->executeUpdate("DELETE FROM topics WHERE topic_id=$topic_id");
        
    $con->commit(); // commit the transaction
    } catch (Exception $e
    {
        
    $con->rollback(); 
        
    // inform moderator/admin of the error via $e->getMessage();


  20. #20
    SitePoint Zealot
    Join Date
    Jul 2003
    Location
    Los Angeles
    Posts
    199
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's an OOP example that should help you out. This is a collection of classes that are part of a custom session handler using (1) DataMapper pattern (2) interfaces and inheritence (3) class aggregation and composition. Few comments are required here once you read a bit more.

    PHP Code:

    abstract class DomainObject
    {
        public function 
    __construct()
        {
            
    // Code removed
        
    }
    }

    interface 
    Persistent
    {
        function 
    insert(DomainObject $obj);
        function 
    update(DomainObject $obj);
        function 
    delete(DomainObject $obj);
    }

    abstract class 
    DataMapper implements Persistent
    {
        protected 
    $db;

        function 
    __construct($db)
        {
            
    $this->db $db;
        }
    }

    class 
    Session extends DomainObject
    {
        private 
    $session_id;
        private 
    $session_data;
        
    // typically might also store the ip address, browser, current page, etc.

        // Leaving out gettors and settors for brevity

        
    function __construct($session_id$session_data "")
        {
            
    $this->setSessionId($session_id);
            
    $this->setSessionData($session_data);
        }

    Let's stop for a second and look what we have which can be described completely in a vocabulary of nouns and verbs.

    I'm using the DataMapper pattern described by Fowler here: http://www.martinfowler.com/eaaCatalog/dataMapper.html DataMappers encapsulate all the SQL logic for storing and retrieving domain objects. They are constructed with a database connection which is an example of an aggregated object -- we are passed it once and use it throughout our methods. DataMappers promise to implement the insert, update and deletion of domain objects via the Persistent interface. Query methods return one or more domain objects.

    Domain objects represent a row in the database table without implementing any SQL logic. A Session is a domain object that represents a row in our session table and inherits from the base DomainObject and defines the gettor and settor methods specific to the session database table.

    Ok, now let's procede to the SessionHandler and SessionMapper classes.
    PHP Code:
    class SessionHandler
    {   
        private 
    $sessionMapper;
        private 
    $session;
        private 
    $cookie_lifetime;
        private 
    $request;
      
        function 
    __construct($session_mapper)
        {
            
    $this->sessionMapper $session_mapper;
            
    $this->session NULL;
            
    $this->cookie_lifetime ini_get('session.cookie_lifetime');
            
    $this->request = new HttpRequest();
        
            
    session_set_save_handler
            
    (
                array(&
    $this'open'),
                array(&
    $this'close'),
                array(&
    $this'read'),
                array(&
    $this'write'),
                array(&
    $this'destroy'),
                array(&
    $this'garbage_collector')
            );
        }

        
    // Just showing the read and destroy methods to cut down on code
        
    public function read($session_id)
        {
            
    $session $this->sessionMapper->findSessionById($session_id);

            if( 
    $session ) {
                
    // Save session object for later use in the write method.
                // Just remember to resave session_data in the write method!
                
    $this->session $session;

                return 
    $session->getSessionData();
            }
            else{
                return 
    '';
            }
        }

        public function 
    destroy($session_id)
        {
            
    $session = new Session($session_id);

            return 
    $this->sessionMapper->delete($session);
        }

    PHP Code:
    class SessionMapper extends DataMapper
    {
        
    // Just showing findSessionById and delete for brevity
        
    public function findSessionById($session_id)
        {
            try {
                
    $sql "SELECT * FROM sessions WHERE session_id='$session_id'";
                
    $result $this->db->executeQuery($sql);

                if( 
    $result->next() ) {
                    
    $row $result->getRow();
                    
    $session = new Session($session_id);
                    
    $this->setAll($session$row);
                    return 
    $session;
                }
                else {
                    return 
    NULL;
                }
            }
            catch( 
    SQLException $e ) {
                return 
    NULL;
            }
        }

        public function 
    delete(DomainObject $session)
        {
            
    $sql 'DELETE FROM sessions WHERE session_id=' $session->getSessionId();

            try {
                
    $numrows $this->db->executeUpdate($sql);

                if( 
    $numrows == ) {
                    return 
    true;
                }
                return 
    false;
            }
            catch( 
    SQLException $e ) {
                return 
    false;
            }
        }

    In this example the SessionHandler is passed a SessionMapper which is responsible for all the database logic of retrieving and saving session objects. The session mapper helps the handler perform duties that hide the actual implementation from the handler. If somone wanted to take this code and tweak it for their particular database they can change the SQL in one place. In our SessionHandler constructor we create an HttpRequest object to help us parse the ip address and anything else you want to stuff into the session. This is an example of class composition -- the session handler creates the request class and uses it in one or more methods.

    In just about any example of a custom session handler people will tend to throw all the sql into it including creating the connection, even worse they won't use a database layer but use pure mysql calls. I've been there myself so I know the learning process you go through With aggregation we (1) create our db connection and pass it to the session mapper (2) pass the session mapper to the session handler. It would look like this:
    PHP Code:
    $db Creole::getConnection($dsn);
    $session_mapper = new SessionMapper($db);
    $session_handler = new SessionHandler($session_mapper);
    session_start(); 
    I should mention that using a data mapper for this is a bit overkill, an ActiveRecord is a better candidate when you consider the session table has about 7 columns and there are no joins involved when querying.

    Hope that long-winded post helped.
    Last edited by kuato; Nov 10, 2004 at 09:01.

  21. #21
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Hi...



    I used to write C code this way (the jump to C++ was too much in one go for most shops). You do run into problems though. Going step by step you can decompose this...
    PHP Code:
    class Person {
        function 
    Person($email) { ... }

        function 
    sendEmail($message) {
            
    mail($this->_address$message);
        }
    }

    $person = new Person('me@there')
    $person->sendEmail('Hello'); 
    ...into this...
    PHP Code:
    function person_send_email(&$person$message) {
        
    mail($person['address'], $message);
    }

    $person = array('address' => 'me@there');
    person_send_email(&$person'Hello'); 
    Things get funky with polymorphism...
    PHP Code:
    class EmailContact {
        function 
    EmailContact($address) { ... }
        function 
    send($message) { ... }
    }

    class 
    SmsContact {
        function 
    EmailContact($phone) { ... }
        function 
    send($message) { ... }
    }

    class 
    Person {
        function 
    setPreferredContact(&$contact) { ... }

        function 
    sendMessage($message) {
            
    $this->_contact->send($message);
        }
    }

    $person = new Person();
    $person->setPreferredContact(new SmsContact('911')); 
    Trying to map this is tricky...
    PHP Code:
    function &contact_create_sms($phone) {
        
    $contact['sender'] = 'contact_send_sms';
        
    $contact['target'] = $phone;
    }

    function 
    contact_send_sms_contact($phone$message) { ... }

    function &
    contact_create_email_contact($address) {
        
    $contact['sender'] = 'contact_send_sms';
        
    $contact['target'] = $address;
    }

    function 
    contact_send_email($address$message) { ... }

    function 
    person_send_message(&$person$message) {
        
    $sender $person['contact']['sender'];
        
    $target $person['contact']['target'];
        
    $sender($target$message);
    }

    $person = array('contact' => create_sms_contact('911'));
    person_send_message($person'Hello'); 
    Things only get worse after this. Not that you would go this length in real life of course.

    As for the original post, the biggest advantage of OO is that it is very expressive for problems in the business domain. Contact and Person can be thought of as real world concepts. This makes it easier (although still hard) to get the code right in the first place and it also makes it easier to change things when you get the bahaviour of one of them slightly wrong.

    Also, because the fault lines of the code map the fault lines of the problem, changes usually involve only one chunk of code instead of an interconnected swathe. It is also easier to factor out common behaviour (such as Contact above) and so write less code.

    yours, Marcus
    As your example points out, this is much like when a lot of C++ books say that an object method is nothing more than a normal function except there is a hidden parameter called 'this' (unles the method is static, where you are telling the compile not to pass 'this'). That C example explictly illustrates that quite well. As you say, OO is a natural way to organise / model things as in real life nearly everything has methods (verbs that act on the somethng), and attributes, and OO programming to me is a way of binding associated data and behaviours, and therefore work closer to the problem domain (and thus save some time).

    As Marcus said, polymorphism gets a bit tricky! It always gets me when you get all these ignorant fools who say windows would be so much faster if it was made with just ASM. I'd like to see these uneducated people try doing something as big without OOP. (Not to mention C/C++ compilers on average can make more optimisations that your average coder when translating C or C++ to ASM/Machine Code). At the end of the day the way the human mind works makes it more less impossible to work on a project as big a a feature rich modern OS in ASM. We need abstractions in order to make things manageable.

  22. #22
    Foozle Reducer ServerStorm's Avatar
    Join Date
    Feb 2005
    Location
    Burlington, Canada
    Posts
    2,699
    Mentioned
    89 Post(s)
    Tagged
    6 Thread(s)
    A real Jem demonstrating clearly advantages to using OOP - i.e. things that can not be done using procedural code. Don't get me wrong there is a time and a place for OOP - sometimes it just doesn't make sense to write it; however for me this is becoming less and less the case as I become more experienced using classes. The re-use, instantiation, aggregation & composition, and polymorphizm used together are very, very powerful.

    Here is the link and please take the time to read it as it does a fantastic job seperating the strenghts and weaknesses of OOP and Procedural:

    What's so good about OOP?

    ServerStorm


  23. #23
    throw me a bone ... now bonefry's Avatar
    Join Date
    Nov 2004
    Location
    Romania
    Posts
    848
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by MiiJaySung
    As Marcus said, polymorphism gets a bit tricky! It always gets me when you get all these ignorant fools who say windows would be so much faster if it was made with just ASM.
    To clear some confusions the standard Windows API is made of simple functions (with a lot of garbage from the old days). The MFC library is just a wrapper for the windows API. Anyway, important things like events and event queues are not implemented in the standard functions, they are very low level. You have to be trully nuts to make a windows application using the standard API.

    When I first read an introduction about OOP about 5 years ago the author said it's all about the code size. Whenever a new phylosophy appeared in programming (asm, procedural, structured, OOP, AOP,...), it appeared to handle more complex tasks easilly. It all translates into lines of code posible and how quick you can get to have a task done.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •