Object Oriented Programming Primer

8¾ minutes to read

Swift, like most modern languages, makes heavy use of a programming model called Object Oriented Programming.  Objects are best thought of as somewhat generic, empty containers of code that can be reused throughout your site. Objects are defined by blocks of code called Classes. Classes provide a clean and simple way to work with data within your application in a way that can be easily extended, modified, and maintained. Though you define a Class once, you can create as many Objects in your code as you wish, each one acting as an independent entity within your application.

For example, if you were creating a blogging application, you might create individual Classes for blog entries, categories, comments, and users. Each of these classes would have unique attributes and methods that were relevant for the type of data they contained.

Attributes and Methods

Objects have descriptive attributes and often contain methods. 

Attributes are another name for variables that are specific to the object you are creating.  They are localized containers for information about the specific object you have created. Using the example above, let's say we wanted to create an object for users.  We would want to create an object called User, and define the following attributes:

  • Name
  • Username
  • Email address
  • Password
  • Internal user id
  • Twitter handle
  • Website URL

In PHP, this might look something like the following:

[php]
class User {
  public $name;
  public $username;
  public $emailaddress;
  public $password;
  public $userid;
  public $twittername;
  public $siteurl;
}
[/php]

When you wanted to actually make use of the object in your PHP application, it would look something like this:

[php]
$user = new User();
$user->name = "Darren";
$user->email = "someone@domain.com";
print($user->name); // Prints Darren
print($user->email); // Prints someone@domain.com
[/php]

Methods are functions, or procedures, that are specific to the object being created.  For example, you might want functions for your users that:

  • Add a new user
  • Delete a user
  • Search for a user

You could create a number of functions in your code to deal with user data, and come up with function names like AddUserToDatabase, DeleteUserFromDatabase, etc. Or, you can create a User object, and attach add(), delete(), and search() functions to it. In PHP, this looks like the following:

[php]
class User() {
  public $name;
  public $username;
  public $emailaddress;
  public $password;
  public $userid;
  public $twittername;
  public $siteurl;
  function add() {
    // code that adds your user to a database or other data store
  }
  function delete() {
    //code that deletes your user from a database or other data store
  }
}
[/php]

And to use the object in your application, you would write the following:

[php]
// Create a new user object
$user = new User();
// Set the attributes for the new user
$user->name = "Darren";
$user->username = "swiftyguy";
$user->password = md5('password');
// Add a new user with the above details to the database or data store
$user->add();
[/php]

In Swift, the syntax is remarkably similar.  Here's the same object class as above, written in Swift:

[swift]
class User {
  var name = String()
  var username = String()
  var emailaddress = String()
  var password = String()
  var userid = Int()
  var twittername = String()
  var siteurl = String()
  func add() -> Boolean() {
    // code to add user record to your data store
  }
  func delete() -> Boolean() {
    // code to delete user record from your data store
  }
  ...etc
}
[/swift]

When you want to make use of the object in Swift, it will look like the following:

[swift]
var user = User();
user.name = "Darren"
user.email = "someone@domain.com"
user.password = "password"
println(user.name) // Prints Darren
user.add() // Adds the user Darren to the data store
[/swift]

As you can see, the syntax is very much the same as PHP, with some notable differences. First is, of course, the data typing required as part of naming the method, or function. PHP doesn't much care about what or whether your function returns data.  Swift, however, like Objective C before it, does require you specify what type of data your method will return (See "The Basics" for a more in-depth explanation).

The second difference is in how you access an object's attributes and methods.  In PHP, you do this through ->. For example, [php]$myname = $user->name;[/php]. In Swift, you do this through dot notation.  For example, [swift]let myname = user.name[/swift].

OK, so what's the benefit?

There's a number of benefits to using objects in your code:

  • Less coding for repetitive operations, and cleaner code that's easier to read and understand
  • Easier maintenance
  • Abstraction
  • Backwards compatibility

Let's work through each of these, using the example of the User object above.

Less coding & Cleaner code

Objects make it easier to reuse existing code within your application.  Because you can create an object and inherit all of the code around it through attributes and methods, this saves you having to rewrite your code every time you want to do something in your application.  Consider this development pattern, which might be used by an inexperienced or junior developer when adding three users to a database:

[php]
$database_host = "domain.com";
$database_username = "root";
$database_password = "password";
$database_name = "myapplication";
$link = mysql_connect($database_host, $database_user, $database_password);
mysql_select_db($database_name, $link);
$i = 1;
$name = "Darren";
$username = "swiftyguy";
$password = "password";
$email = "someone@domain.com";
$userid = $i;
mysql_query("INSERT INTO users set name='" . $name . "', username = '" . $username . "', password='" . $password . "', email='" . $email . "', userid=" . $userid);
$i = 2;
$name = "Kirsten";
$username = "awesomegal";
$password = "password";
$email = "someone2@domain.com";
$userid = $i;
mysql_query("INSERT INTO users set name='" . $name . "', username = '" . $username . "', password='" . $password . "', email='" . $email . "', userid=" . $userid);
$i = 3;
$name = "Chance";
$username = "littleguy";
$password = "password";
$email = "someone3@domain.com";
$userid = $i;
mysql_query("INSERT INTO users set name='" . $name . "', username = '" . $username . "', password='" . $password . "', email='" . $email . "', userid=" . $userid);
[/php]

Compare this to the same code that makes use of objects and a for loop:

[php]
$users = array(
  '1' => array(
    'username' => 'swiftyguy',
    'name' => 'Darren',
    'email' => 'someone@domain.com',
    'password' => 'password',
  ),
  '2' => array(
    'username' => 'awesomegal',
    'name' => 'Kirsten',
    'email' => 'someone1@domain.com',
    'password' => 'password',
  ),
  '3' => array(
    'username' => 'littleguy',
    'name' => 'Chance',
    'email' => 'someone3@domain.com',
    'password' => 'password',
  ),
);
foreach ($users as $key=>user) {
  $newuser = new User();
  $newuser->name = $user['name'];
  $newuser->username = $user['username'];
  $newuser->userid = $key;
  $newuser->email = $user['email'];
  $newuser->add();
}
[/php]

As you can see, it's much more compact and readable code.

Easier Maintenance

Because all of the code related to a certain type of data, or object, within your application is defined within an object class, it's much easier to find all attributes and methods associated with it.  This is a godsend when you are tracking down a bug in your code, or need to make a fix to your application.  You simply update the code in your class definition, and it's automatically updated throughout your application, regardless of where the object is used.

Abstraction

There are times when you will want to write a method that is a bit abstract.  This is commonly used within a Model-View-Controller (MVC) design pattern, where you don't want functions that exist at the presentation layer to know about the structure of the data at the "model" level. In MVC, there is a separation between Views—pieces of code that deal with presenting information to the user—and Models—pieces of code that deal with the structure of the data itself (I'll go deeper into MVC in a future post). An abstract function will then exist at the Controller level that acts as a bridge between the two, taking the View's request for data and passing it to the Model to retrieve.

For example, say you wanted to display a video file that had two sources for a particular piece of data: a local database, and a web-accessible API.  You might write a controller function in PHP that looks like this:

[php] class Video() {   public $id;   function getVideo() {     if (!$video_details = getVideoFromDB($this->id)) {       $video_details = getVideoFromAPI($this->id);       addVideoToDB($video_details);     }     return $video_details;   }   function getVideoFromDB() {     // code to query database for $this->id     return $record;   }   function getVideoFromAPI() {     // code to contact API and request details   } [/php]

In your application, you would simply call the getVideo() function like this:

[php]
$video = new Video();
$video->id = 1850;
$video->getVideo();
[/php]

When called, the object method would first look to see if the video exists in the database through the getVideoFromDB() function.  If it does, it will return the details back to that part of your application. If it can't find it in the database, the getVideo() function will fall back to calling the getVideoFromAPI() function, then add the video's details to the database before returning the details.  This saves time next time the video ID is requested, because it will now be in the database.

When you initially call the getVideo() method, you don't really care where the data lives.  All you know is that you want details about a video whose ID is 1850. 

Backwards Compatibility

It's a relatively common occurence in software development that you have to rewrite or improve upon your application's code. Sometimes this requires big rewrites of your logic that can break when other parts of your code rely on the old functionality, or renaming methods to better suit your application.  By using objects, you can leave the "old" method and attributes around and add new, updated code.

For example, say you needed to change the way getVideo worked above to make use of multiple API sources.  Instead of rewriting all your code to specify which API you want to use, you can simply rewrite the object method:

[php]
class Video() {
  public $id;
  public $apisource = NULL;

  function getVideo() {
    if (!$video_details = getVideoFromDB($this->id)) {
      $video_details = getVideoFromAPI($this->id);
      addVideoToDB($video_details);
    }
    return $video_details;
  }

  function getVideoFromDB() {
    // code to query database for $this->id
    return $record;
  }
  
  function getVideoFromAPI() {
    switch ($this->apisource) {
      case 'youtube':
        // code to pull video details from YouTube
      break;
      case 'vimeo':
        // code to pull video details from Vimeo
      break;
      default:
        // code to contact API and request details
      break;
    }
  }
}
[/php]

Existing calls to $video->getVideo() will continue to work as they did before, but you now have the ability to specify the video source by adding a new attribute:

[php]
$video = new Video();
$video->id = 1850;
$video->apisource = "youtube";
$video->getVideo();
[/php]

Hopefully, you have a better understanding of what object oriented programming is, and how it can be beneficial to your own applications.

As always, if you have questions or comments, don't hesitate to drop me a line on Twitter.