SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Zealot sanka69's Avatar
    Join Date
    Apr 2003
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Am I getting this "right" - (Yet more OO design)

    A user can recieve messages, the messages can be stored in folders.

    A user can reply to messages.

    A user can send messages.


    To me, this means I have a User class, a Messages class, a Message class and a folders class.

    Obviously, the user class has a lot more functionality - such as login and logout. So to avoid overloading this class, I would create a message system - (a controller class?)

    PHP Code:

    class MessageSystem {
       var 
    $owner;
       var 
    $db;
       var 
    $user_id;

       function 
    MessageSystem(&$owner) {
          
    $this->db $owner->getDatabase();
          
    $this->user_id $owner->getUserId();
       }

       function 
    getMessages($folder_id) {
          return new 
    Folders($this$folder_id);
       }
       
       function &
    getDatabase() {
         return 
    $this->db;
       }   
    // MessageSystem


    class Folders {
       var 
    $owner;  
       var 
    $folder_id;
       var 
    $messages;

       function 
    Folders(&$owner$folder_id) {
          
    $this->owner $owner;
          
    $this->folder_id $folder_id;

          
    $db $this->owner->getDatabase();
          
    $sql 'select......';
          
    $query =& new QueryIterator($this->db->query($sql));
          for (
    $query->reset(); $query->isValid(); $query->next())
          {
             
    $record =& $query->getCurrent();
             
    $this->messages[] = $record;
          }
       }       

       function &
    getMextMessage() {
          
    $record each($this->messages);
          if (
    count($record) > 1) {
             return new 
    Message($record['value']);
          }    
       }
    }
    // Folders class


    class Message {
       function 
    Message($data)
       {
            
    // Here, data is the array of a specific message
       
    }

    Three questions here;

    1) where would be a good place to put the "Reply" or "Send" message functions?

    2) Does any of my code above resemble something other than a mess? IE: the "Folders" class- am I correct in thinking that is a Folders 'Model'?

    2a) Because in order to display the list of messages, I'm thinking I would need a class ie: "MessageView" which would then render the various bits of HTML.

    Your help would be appreciated!

    -R

  2. #2
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    1. why does your $owner have a method
    '$owner->getDatabase()' ? What does it do? If it creates a databse access object, this is bad form to say the user class acts as a factory for a db access object.

    2. Do you need a message class ? If it just holds parameters, just use a hash table (ie an array in php). Eg.
    $message = array();
    $message['text'] = 'some text';
    $message['from_user'] = $some_user_object;

    $print $message['text'].' '.$message['from_user'];

    3. I think chanage the folder class to another name such as 'class message' which can both retrieve and store messages in a $folder where $folder is passed in from the $users 'folder' attribute which is the users folder path

    4. I think maybe the reply and send should be in the $user class since the $user does it.
    So your controller would pass a message to the user and the user would handle the message.

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

    OK, you are off to a good start and seem to have spotted some early problems. Simply splitting a job into nouns and verbs doesn't seem to work in my experience. If I am drinking a beer, do I have this...
    PHP Code:
    class Person {
        ...
        function 
    drink(&$beer) { ... }
    }
    class 
    Beer { ... } 
    ...or this...
    PHP Code:
    class Person { ... }
    class 
    Beer {
        ...
        function 
    drink(&$person) { ... }

    ...or this...
    PHP Code:
    class Person { ... }
    class 
    Beer { ... }
    class 
    Ingestion {
        ...
        function 
    drink(&$person, &$beer) { ... }

    Which noun has the verb?

    Quote Originally Posted by sanka69
    To me, this means I have a User class, a Messages class, a Message class and a folders class.
    I am suspicious of the plurals. I am also suspicious of any class called "User" as the name does not carry any obvious responsibilities.

    Quote Originally Posted by sanka69
    Obviously, the user class has a lot more functionality - such as login and logout. So to avoid overloading this class, I would create a message system - (a controller class?)
    Let's suppose we have a Message class (a think this is a good idea). You don't necessarily send a message to a user of the system so an address is not synonymous with a user. Also a user may have multiple addresses. How about this...?
    PHP Code:
    class PointOfContact {
        ...
        function 
    send($message) { ... }
    }
    class 
    Mailbox {
        ...
        function 
    receiveMessage($message) { ... }
        function 
    findMessages($criteria) { ... }
    }
    class 
    Message {
        ...
        function &
    getReplyContact() { ... }
        function 
    doesMatch($criteria) { ... }
        function 
    getContent() { ... }
    }
    class 
    Party {
        ...
        function &
    getPreferredContact() { ... }
        function &
    getInbox() { ... }
    }
    class 
    Login {
        ...
        function &
    getOwner() [ ... }

    Like you, at this stage I am guessing somewhat.

    I have replaced the user and folders with a Mailbox. The Mailbox may have folders internally or this may just be a figment of the presentation. As I don't know at this stage I have hidden it all behind the receiveMessage() and findMessages() methods.

    You don't say whether this is an e-mail system or some kind of unified messaging app., so I have avoided naming anything e-mail specific.

    You could move the Party functionality into the Login class for simplicity. You did say there would be a lot of other functionality however.

    The scenarios I am thinking of include later adding an address book (the Mailbox can read any incoming PointOfContacts) and filters that act like folders (virtual folders).

    Quote Originally Posted by sanka69
    1) where would be a good place to put the "Reply" or "Send" message functions?
    This is a collaboration with the incoming message so as to get a target for the reply message. The concept is higher level than this object I think. I would put it in the Mailbox as it will likely have to keep track of outgoing messages, apply quoting styles, etc.
    PHP Code:
    class Mailbox {
        ...
        function 
    reply(&$incoming$content) {
            
    $reply = &$this->createMessage($content);
            
    $sender = &$this->getOwner();
            
    $reply->addReplyContact(
                    
    $sender->getPreferredContact());
            
    $target = &$incoming->getReplyContact();
            return 
    $target->send($reply);
        }

    Quote Originally Posted by sanka69
    2) Does any of my code above resemble something other than a mess? IE: the "Folders" class- am I correct in thinking that is a Folders 'Model'?
    What you have described are all model objects, possibly except the Folder. This has more to do with the presentation layer. It may never appear as an explicit object in the system except as a way of visually navigating messages.

    Quote Originally Posted by sanka69
    2a) Because in order to display the list of messages, I'm thinking I would need a class ie: "MessageView" which would then render the various bits of HTML.
    I think that this is very likely.

    Quote Originally Posted by sanka69
    Your help would be appreciated!
    I hope anything I have said is in anyway useful. As I say, I am guessing somewhat. No design ever survives the first refactoring .

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

  4. #4
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think a users folder(ie address) can be stored as a field in the User table (and hence in teh User class) since each user has at most one folder - ie, 1-to-1 relationship in this case.

    A user class can allow adding users,removing users, updating a users info, retrieving a users info. So it has responsibilities.

  5. #5
    SitePoint Zealot sanka69's Avatar
    Join Date
    Apr 2003
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Lastcraft,
    Thanks for the reply, there's a fair bit to take on board!

    What I'm trying to put together is a very basic messaging system within a website.

    I like the idea you have about a mailbox class. As I understand it, the retrieveMessages arguments would contain the virtual folder id.

    I've thought about taking a more heirachal approach in the classes. The users class is purely a representation of the logged in user. From there I could stem various details, such as their preferences, profile, mailbox, and so on.

    Users -> Mailbox -> Message
    -> Preferences
    -> Projects

    where preferences is another dataclass to represent user's settings ie:

    PHP Code:
    echo "Hello, " $user->Preferences->getDisplayName(); 
    or, say they had a preferred starting page when logging into the system, something like:

    example login.php
    PHP Code:
    if ($user->checkSession()) { // user logged in, session ok
       
    header('Location: '$user->Preferences->startPage());


    Quote Originally Posted by lastcraft
    I hope anything I have said is in anyway useful. As I say, I am guessing somewhat. No design ever survives the first refactoring .

    yours, Marcus
    Certainly has, thanks again.

    -R

  6. #6
    SitePoint Zealot sanka69's Avatar
    Join Date
    Apr 2003
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lazy_yogi
    I think a users folder(ie address) can be stored as a field in the User table (and hence in teh User class) since each user has at most one folder - ie, 1-to-1 relationship in this case.

    A user class can allow adding users,removing users, updating a users info, retrieving a users info. So it has responsibilities.
    Hi,
    Thanks again for the reply. In your first point you commented about the getDatabase() function. The parent class has a database class instantiated stored and getDatabase simply retrns a reference.

    With regards to the users folder, something that I'm unsure of is the way to store this data. You say have the folder in the users table, but that would only mean the user could have one folder? At the least there are to be two folders, Inbox and Sent Items.

    (users..)

    Users(username, password ....)

    (the messages table)
    Messages(sender_id, recipient_id, sent_date, read_date, folder_id, content);

    I could store a folders table, something like

    folders(folder_id, username, folder_text)

    however, that would mean a "Inbox" "Sent Item" default folder created for each user. I don't have a problem with that personally, but would that constitute a bad design?


    -R

  7. #7
    ********* 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 lazy_yogi
    A user class can allow adding users,removing users, updating a users info, retrieving a users info.
    I don't think that this is true. Should a user be able to add another user? It is common to add such functionality as static methods to a class, but I find that this has problems when it comes to testing. Being purist for a moment (this doesn't happen very often ) it is strictly the job of the UserManager.

    Quote Originally Posted by lazy_yogi
    So it has responsibilities.
    I find the problem with a User class is not that it doesn't have responsibilities, but that it doesn't have clear responsibilities. As a result it gathers stuff like fly paper. You may simplfy a system down to a single User class if things aren't too complicated, but even this would make me nervous. At the design level I find the concept is way too cloudy, but your mileage may vary.

    I personally split it up into a Person that has a Login. Person is usually a subclass of Party (something of a data modelling tradition). If you are dealing with billing of multiple accounts then I would have...

    Party(1)--->(*)Account(1)<---(*)Login

    Because all of these have identity, this system can be a little complicated. However, it is pretty obvious in practice which one is the owner of any new features.

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

  8. #8
    ********* 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 sanka69
    As I understand it, the retrieveMessages arguments would contain the virtual folder id.
    I am not sure the folders concept will be too easy to navigate on the web. I think you should have a variety of systems.

    I was thinking of a single argument that would be a Criteria/Query object or a list of them. One type of constraint could be the folder path, but a full text search would be just the same.

    The most immediate role is finding messages. If you have a class that manages the messages on the database, called say a MessageFinder, then the criteria would be set by the mailbox view. It doesn't matter whether this came from a search panel, or you are just opening a folder. The mailbox would add it's own criteria and then pass it to the MessageFinder::findByCriteria() method.

    The other role is to filter messages. This could be to assign folders based on mailbox filters...
    PHP Code:
    class Mailbox {
        ...
        function 
    setFilter($criteria$folder) { ... }
        function 
    receive(&$message) {
            foreach (
    $this->getFilters() as $criteria => $folder) {
                if (
    $message->doesMatch($criteria)) {
                    
    $message->addFolder($folder);
                }
            }
        }

    Folder is just a string such as "inbox/Marcus/from Fred". The split role makes the Criteria class quite passive.

    Quote Originally Posted by sanka69
    Users -> Mailbox -> Message
    -> Preferences
    -> Projects

    where preferences is another dataclass to represent user's settings ie:
    I wouldn't start with a preferences class, but rather distribute the options throughout the system until you see commonality. Preferenecs are rather tricky as the are more an aspect than a class. If you make this decision too early I think you will have trouble. An example is the Java 1.4 properties system, where you attach extra information to classes in a config file. The Java designers have kept the meta data completely separate from the class hiearchy.

    Quote Originally Posted by sanka69
    Certainly has, thanks again.
    No probs. I think you should get the bare bones up now. This is certainly as far as I could go on the design front without starting to write some code, even if it was just a few mocks.

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


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
  •