Refactoring explained to an absolute beginner

Tags:

Recently while on a drive with a non-programmer friend, I talked with him about code complexity and manageability, how very complicated code is detrimental to productivity and stuff like that.

Later on, I decided to explain it to him with actual code examples, although the most he has ever done was some HTML back in elementary school.

Here’s what I told him…

A simple example with HTML, PHP and SQL

I used HTML, PHP and SQL to create a very simple example: A simple webpage which displays a list of things loaded from a database.

The reason I chose these three is because they allowed me to present a very simple example, but still would allow me to create a scenario where it would be easy to show how code can become complex, and how you would change it to improve.

Stage 1: HTML/PHP/SQL-soup

The first stage is the most straightforward way you could do this:

<html>
 <head>
  <title>Listing</title>
 </head>
 <body>
  <h1>List</h1>
  <?php
  $db = mysql_connect('localhost', 'username', 'password');
  mysql_select_db('database', $db);
 
  $sql = 'SELECT * FROM lista ORDER BY id DESC';
  $result = mysql_query($sql, $db);
  ?>
  <ul>
    <?php
    while($row = mysql_fetch_assoc($result)) {
      echo '<li>' . $row['name'] . '</li>';
    }
    ?>
  </ul>  
 </body>
</html>
<?php
mysql_close($db);
?>

So in this example, we have a page that is very typical for a PHP beginner: It mixes everything together in one file.

Stage 2: Split output and data processing

To improve from stage 1, we can split the processing of data and output. We do this to achieve separation of concerns.

This time, we have two files: index.php and a template file index.phtml

index.php

<?php
$db = mysql_connect('localhost', 'username', 'password');
mysql_select_db('database', $db);
 
$sql = 'SELECT * FROM lista ORDER BY id DESC';
$result = mysql_query($sql, $db);
 
$list = array();
while($row = mysql_fetch_assoc($result)) {
  $list[] = $row;
}
 
mysql_close($db);
 
require 'index.phtml';

index.phtml

<html>
 <head>
  <title>Listing</title>
 </head>
 <body>
  <h1>List</h1>
  <ul>
   <?php foreach($list as $item): ?>
    <li><?= $item['name']; ?></li>
   <?php endforeach; ?>
  </ul>  
 </body>
</html>

As you can see, now our data processing code is in index.php and the HTML markup is in the index.phtml template file. It’s now much more clear what the structure of our HTML markup is (and we could now reuse it etc.)

Stage 3: Reusable functions

We can still perform some improvements to the code. Let’s extract the data processing code into separate functions. By doing this, we will improve the readability of the index.php file and if needed, we could easily reuse the data processing code.

We will create a new file, called database.php, which will include our functions:

database.php

<?php
function connect_db($user, $pass, $host, $dbname) {
  $db = mysql_connect($user, $pass, $host);
  mysql_select_db($dbname, $db);
  return $db;
}
 
function get_list($db) {
  $sql = 'SELECT * FROM lista ORDER BY id DESC';
  $result = mysql_query($sql, $db);
 
  $list = array();
  while($row = mysql_fetch_assoc($result)) {
    $list[] = $row;
  }
 
  return $list;
}

We will also change index.php to reflect the extraction of the code:

index.php

<?php
require 'database.php';
 
$db = connect_db('user', 'pass', 'address', 'database');
$list = get_list($db);
 
require 'index.phtml';

As you can now see, the code is much easier to understand as we can clearly see from the function naming what it does and the index.php file is also much shorter.

Conclusion

By splitting code into their separate places, you can easily improve your code. You don’t need to be a rocket scientist to understand the basic points.

I did omit some things here, though: in reality I did give a brief introduction of HTML, PHP and SQL to my friend, and gave him an example of how the resulting page would look and stuff like that. Oh, we used Google Wave for it, and it worked pretty well, so maybe it isn’t as useless as it sometimes seems :D