Overview
Prerequisites
Background
Why OO can work with PHP
The Task
- Step 1: Define the classes
- Step 2: Define attributes and methods for the classes
- Step 3: Implementation issues
- Step 4: Create a class diagram
Some OO Tips and Commandments
Next Time
About the Author
Intended Audience
This tutorial is intended for readers interested in Object Oriented Design. Knowledge of PHP concepts is not necessary, but knowledge of PHP's OO syntax, and of working with PHP's mysql functions and objects, is assumed.Overview
This tutorial is the second in a series dealing with using objects to create an application -- building the application up from smaller parts -- and teaching important software engineering and design concepts that will be useful writing not only in PHP, but in other languages as well.The specific project assigned is creating an online posting system. This article concentrates on the design stage of the project.
Prerequisites
Knowledge of OO concepts, and a limited understanding of software design.Last time we showed a small example of the benefits of using objects to abstract details that the application programmer would like to avoid dealing with, and also to abstract out business logic.
This time we will actually see the power of using objects as components of an application. Objects are connected together, with each object serving a particular functionality of the program.
Background
OO programming is one of the greatest innovations in programming since the invention of the compiler. Objects allow a programmer to break details into smaller parts, to encapsulate data, and (when written in correct OO) to allow objects in the program to model objects in real life!It gets even better. As you will see here and in the next article, OO greatly helps in the design phase of project development. It is possible to model the flow of execution, and the entire composition of an application, using diagrams like class diagrams and sequence diagrams.
Breaking an application down into objects -- physical parts -- is far superior to breaking it down into processes, (called "functional decomposition").
Another big benefit of classes is the creation of class libraries. Class libraries have all the trimmings of function libraries, and so much more! Imagine going to a library and “pulling off the shelf” a class called
Member,
that would handle storage and retrieval for you without you having to worry
about database details at all. That will soon be a reality, as I am currently
coding a library called PHPZeus, (and another library called JavaZeus, for Java),
which works like a message board system. When building an application, you can
literally go to the Messaging package, pull out a message class, then a Thread
class, and put your message board together! Why OO can work with PHP
Despite the fact that PHP OO pales in comparison to that of Java, and the PHP runtime system's handling of objects of woefully inefficient, objects can and have been used to build applications. (Just check out my site http://www.enetexperience.com where almost all of the dynamic and interactive content is provided by OO PHPZeus.) You can use OO abstraction to abstract out business logic. Furthermore, according to the Zend2 pdf forecast many object problems will be corrected by the new runtime (with the exception of multiple inheritance, which I believe complicates coding and design). Instead of multiple inheritance, aggregations and composition should be used, delegating the functionality of an object into another object. The main benefit that the Zend Engine 2 will bring is that PHP object variables will be handles, not physical objects, similar to the way that a Java object variable is a pointer to the location on the heap where the object is stored. Finally, private fields will make PHP's OO system more complete.The Task
Our assigned task was to create an online posting system. Of course the actual requirements of the assignment were left out last time (in Part One). Now we have some concrete specifications that we need to follow.- We must maintain an account system of members. There will be two types of members, normal users and administrators. Members will contain information such as email, username, UID, and password. Admins, in addition to all the features of a member will contain a position and employee number.
- Administrators must be able to add new news topics to the website.
- Administrator must be able to edit or remove topics, edit or remove other members, add new members, and award admin powers to another user.
- Users must be able to post comments to a news article posted by an admin.
- Each member will have a list of members or buddies.
- Members must be able to send messages to one another.
- Messages will consist of a subject, a message body, a date, and a posting member.
- News messages will be messages that also contain a list of comments to that item.
- The message list must be able to store messages in order, by the date on which they were posted.
This article focuses on the design stage of the project. No code this time. Since there is no code you could theoretically take the design we make here and write it in any other language (such as my favorite, Java). However, since we are designing a PHP application our design must take into account both the limitations and the features of PHP.
Step 1: Define the classes
First we want to define our objects: the objects we are actually going to use in our program. Then we should break our classes into categories. These categories describe the functionality of our classes. There are two category systems that we can use. OO level categories, that give description of our classes from an object perspective. And application level, that describe what role our classes will play in the application.Here are the OO categories:
Actor Classes
Classes that represent people. Actor classes have their own attributes as well as the ability to perform actions.Data Classes
Classes that represent data. They have attributes, but usually do not have the ability to perform actions.Action Classes
Classes that perform actions. Can perform computation as well as act on other objects. More likely than not these classes won't have specific attributes. Lots of business logic can be contained here.Collection Classes
Objects that hold other objects.So now that we defined the categories of classes, we need to define exactly what classes we need to use. The simplest way to go about doing this, in my opinion, is to step through our criteria one by one, determine what classes we need, and add them to the list. We could group our classes into the four categories while we step through the criteria or we could do it after. I choose to do it after.
Let's examine our criteria.
- We must maintain an account system of members. There will be two types
of members, normal users and administrators.
Right here we potentially have two classes. We will definitely have a Member class (we coded this last time). And we might have an Administrator class that extends member.
- Administrators must be able to new news topics to the website.
This requires that we have some method of posting messages to the website. We could either have our form processing script handle this, or have a method in our Admin class. Regardless of which way we choose to implement posting, we requires a Message class.
- Administrator must be able to edit or remove topics, edit or remove other
members, add new members, and award admin powers to another user.
No new classes here.
- Users must be able to post comments to a news article posted by an admin.
More posting. A post processing class seems to be in order since we've seen posting in three different elements of the criteria. Also, since there is a difference between user posted messages and news articles, we should have two different classes to represent them. We could create a generic Message class, and have admin posted article extend from that.
- Each member will have a list of members or buddies.
We need a data structure to hold member objects.
- Members must be able to send messages to one another.
Take your pick. Form a processing class, or method into the message or member class. Previously messages were posted to the public, but now we want to enable messages to be sent by one person to one other person. The sender attribute is still present, but now we must also specify a recipient Differing attributes exist, so the creation of a subclass of Message is warranted here.
- Messages will consist of a subject, a message body, a date, and a posting
member.
Nothing new here.
- News messages will be messages that also contain a list of comments to
that item.
We need a data structure to store messages.
- The message list must be able to store messages in order by the date in which they were posted.
For now all we’re doing is defining classes. The methods for defining them do not concern us.
So now we have stepped through our criteria, and defined some classes we need to define. So now lets put them into our four categories.
Actor Classes:
MemberAdministrator
Data Classes:
MessageNews Item
Private Message
Action Classes:
Form ProcessorUser Manager
Admin Manager
Message Manager
Collection Classes:
Buddy ListComment List
Notice that simply by going through our criteria we were able to come up with a list of 11 possible classes. We may end up adding more classes, or subtracting some classes from this list, but at least we now we have a rough estimate of the classes we need.
Step 2: Define attributes and methods for the classes
Our next step is to define what attributes and methods we need for our classes. At this point in our design we will still not take into account that this is a PHP application, so this next section is still language independent.Member:
UIDUsername
Password
Buddy List (instance of Buddylist)
Retrieve() for retrieving data from our data store
Update() for storing data in our data store
Get/Set methods
Administrator
Extends Member
Position
Employee Number
Retrieve() for retrieving data from our data store, must override here since this class has more data that we have to store
Update() for storing data in our data store
Get/Set methods only for new attributes
Message
Subject
Message Body
Date
Posting Member (instance of Member)
Get/Set methods
Send();
News Message extends Message
Comment List
Get/Set Poster
Send()
Private Message extends Message
Sender (instance of Member)
Recipient (instance of Member)
Get/Set Methods
Form Processor, User Manager, Admin Manager, and Message Manager.
We shall worry about the details of these classes later.
Buddy List
Buddies[]
Add()
Get()
Remove();
Comment List
Comments[]
Add()
Get()
Remove()
Through examining our criteria we have created our classes and have brainstormed some essential methods that our classes must have.
Step 3: Implementation issues
We now need to consider actual implementation, The we will create a class diagram representing the relationships between our classes. This is still largely language independent, but as you will see we will begin to take into account that this is a PHP program.We know that Member and its children, and Message and its children, each have update() and retrieve() methods for retrieving data from our data store. Since this is a PHP application we can assume for now that the data store is a mysql database, but the data store could be anything, even a flat file storage mechanism. (Since there are different types of data store we should really have a processor class so that our objects don't care what the data store is, but that would make this project overly complex so we wont worry about that here. If we were concerned about this, we would pass our queries to the processor to handle the details.)
One thing we do need to be concerned with is the login info about the database. This is accomplished by the settings class (dealt with in Part One of this series). That way, if the login and access data were to suddenly change all we would have to do is modify the settings file, rather than modify all our classes.
The next implementation issue that we have to deal with is the presentation of the lists (buddylist, comment list.) Here the fact that this is a PHP application will greatly effect the implementation of this feature. If this were a Java program, one would either implement a linked list class, or return an enumeration or vector of elements, presumably wrapping that Enumeration or Vector in a wrapper class, to handle business logic on the elements. The simplest method to get this to work in PHP is to return an array of member objects (or message objects), but in my personal opinion returning a plain old array isn't good OO abstraction. So I would create a class called BuddyList, which encapsulates an array. When you call add() it adds a new buddy to the array, and remove() removes a member from the list. The same will be done with Comment List.
Finally the processor. We need at least one processor to serve as the bridge between the static HTML interface and the actual system. This class will instantiate the objects necessary to complete the task. You may want to use abstraction, abstracting out specific functionality like data store manipulation into another processor class, an instance of which is created by the main processor class.
Step 4: Create a class diagram
Now all we need to do before finishing our object design is describe the relationship between our classes, and then draw a simple class diagram, which will provide a visual representation of our classes and the relationships between them. Class diagrams are just one of the design mechanisms used in industry to model the objects that make up an application.
This is a standard UML class diagram. I modeled the objects in our system. The arrows indicate inheritance while the lines with diamonds indicate aggregations.
Some OO Tips and Commandments
If two classes implement largely the same functionality, and have largely the same attributes, make one class a subclass of the other.Do not think of objects as function libraries. Sure some classes implement static methods, but those are classes, not objects. Objects are supposed to represent physical things. Objects are people, things, or processors that operate on other objects, but not just collections of functions.
Keep instantiable classes simple. Use abstract classes to contain all methods that your class hierarchy will contain, and have the classes that you will instantiate extend off from the abstract class. PHP doesn't have an abstract construct, but you could easily implement one by making a call to die ("Attempting to instantiate abstract class") inside your constructor.
To keep things simple, don't include too much functionality inside a single class. Instead use compositions. Objects, just like the application as a whole, should be comprised of smaller parts. Each object should have specific functionality. Place dissimilar functionality into other classes, and instantiate those classes from your class. Classes can instantiate classes, something that professional OO programmers know and utilize.
Develop class libraries, so that you may reuse such classes in later projects. Your projects can either use these classes directly, or your project can have subclasses that extend from classes in the library. This is the way the Java API is set up. My PHPZeus project is also a class library that programmers will be able to use in their projects.
Consider a class hierarchy, having all classes descend from a common super class. This technique really applies to languages like PHP, Perl, or C++. PHPZeus has all classes extend from class ZeusMethods, but JavaZeus obviously doesn't because all classes in Java already extend from a common super class, java.lang.Object.

Comments
Thanks