General: Time and programming

UTC: Universal time based on England.

GMT: Greenwich Mean Time. Sort of the same as UTC, based on a different region of the world.

Unix time: Number of seconds since epoch (1970). It is based on UTC. No timezones, there are leap seconds every now and then to adjust. They happen at the end of the day by just recounting the last second.

Computer systems should store Unix timestamps based on UTC.

Clients of those systems should do the adjustments to display them as local time to the users. At displaying time, a timeformat without offset is useless.

 

 

 

Design patterns: singletons

Singleton classes basically mean there is only one object class of a certain type running at all times. That could be used to store Global variables, for example.

The way to implement it on PHP:

class Preferences {
    private $props = array();
    private static $instance;

    private function __construct() { }  // By setting the class constructor to private, it can’t be instantiated from outside

    public static function getInstance() { // This static method will serve as instantiation, or to serve the only instance available
         if ( empty( self::$instance ) ) {
              self::$instance = new Preferences();
         }
         return self::$instance;
      }

      public function setProperty( $key, $val ) {
          $this->props[$key] = $val;
      }

      public function getProperty( $key ) {
          return $this->props[$key];
      }
}

Example of the driver class that is calling this:

$pref = Preferences::getInstance();
$pref->setProperty( “name”, “matt” );

unset( $pref ); // remove the reference

$pref2 = Preferences::getInstance();
print $pref2->getProperty( “name” ) .”n”; // demonstrate value is not lost

Design patterns: Composition and Inheritance (Strategy pattern)

Instead of creating child classes, you create a new tree of classes and move some of the functionality away from the main tree.

You connect the trees via object creation, meaning some of the classes in one tree contrain objects with the other classes type.

The advantage is that the trees are more specialized in what they do, so functionality in one tree is independent from the other tree, and it just complement it.

The disadvantages is that now you are creating more classes, so it may be difficult to maintain and keep track of it.

PHP interfaces

Interfaces are pure class templates that define functionality. It can contain properties and methods, but no method implementation. See the example below:

interface Chargeable {
    public function getPrice();
}

So any class that implements this interface, will look something like this:

class ShopProduct implements Chargeable {
    // …
    public function getPrice() {
    return ( $this->price – $this->discount );
    }
    // …

When a class implements an interface, it takes on the Type of the interface as well, effectively having more than two types if that same class is also extending other classes, or implementing other interfaces. This way you can join types that are otherwise unrelated when creating a new class.

In PHP you can only inherit from one parent, but you can have multiple interfaces:

class Consultancy extends TimedService implements Bookable, Chargeable {

    // ...
}

OOP Best Practices and architecture

  1. When creating classes, make a really general abstaction of the object you have in mind (usually an abstact class or interface), and then start working your way down to the specifics using inheritance, encapsulation and polymorphism. For example: to create a book object for an ecommerce site, create something like Product / Item / Books / Book.
    • Advantages: This way your architecture can accomodate other objects later (cars / clothes / other categories)
    • Inside your classes, you avoid using hard to maintain “If” flags and clauses to perform different tasks per type of class
    • At the same time, you maintain a hierarquical structure of your objects that help you control variables and methods per level.
    • Make sure your classes are not overloaded with responsibilities. Spread responsibilities around the hierarquical structure of classes, if you can’t define a class responsibility with 25 words, and without using “and” and “or” words, you may be overloading your class with tasks. This will be hard to maintain.
    • But always remember: OOP best practices are not set on stone. If you have a good reason to bend the rules (performance, etc), do it, but think hard before you go ahead.
  2. As a general safety rule, you can set all methods and variables to private, and start resetting them to protected or public as you go along.
  3. Add error handling to all places things can go wrong (unexpected input / output usually). See PHP Error Handling section for more details, but basically extend the provided Exception class with a new class for each kind of error, and at the catch part of your try catch statement, have several catches that will deal with the particular error the proper way based on Exception type detection.
  4. Here are four possible indications of design problems:
    1. Code duplication: if you get a deja vu feeling at code writing a class, think: if I change something fundamental in this routine, will the other simmilar routine need ammendments? If so, then you may have a dup class you can compress in one.
    2. If a class depends too much on Globals variables and its context, this class will be hard to maintain. Try to make each class its own environment.
    3. If a class is doing too much, think of ways to reduce responsibility and extend down to other classes.
    4. Testing for the same condition with “if” statements throughout diffent classes may call to review your polymorphism. Where you can do the “if” test once, and spawn different objects with no “if” conditions down that fork
  5. Inside your classes, seek for those lines of code that express variation and fork the behavior of the current class given different values or conditions, and try to encapsulate them in their own type class.
  6. The golden rules: “Do the simplest thing that work”, and “are you sure you are going to need this extra complexity?”
  7. Avoid global variables like the plague, they make your classes highly coupled with the system, can’t be reused easily, and it’s hard to encapsulate stuff when using those. If you are to use Globals (say, to avoid passing too many variables or objects around) use singletons instead.
  8. Use phpDocumentor to add documentation to your code, even the default, do nothing and just run it option is better than nothing: http://www.phpdoc.org/
  9. Make sure you include Unit testing with PHPUnit

PHP instanceof to determine what kind of object we are dealing with

Example:

class ShopProductWriter {
    public function write( $shopProduct ) {
        if ( ! ( $shopProduct instanceof CdProduct )  &&
             ! ( $shopProduct instanceof BookProduct ) ) {
            die( "wrong type supplied" );
        }
         $str  = "{$shopProduct->title}: " .
                $shopProduct->getProducer() .
                " ({$shopProduct->price})n";
        print $str;
    }
}

PHP Object type hinting

Introduced with PHP 5.1, it basically looks like this:

function setWriter( ObjectWriter $objwriter=null ) {
    $this->writer = $objwriter;
}

Where the $objwriter has to be either null or of the type ObjectWriter, or it will produce a runtime error. The =null part is optional.

Advantages:

Forces to pass the right kind of object to a method, saving us the trouble of testing before passing. It also makes the code clearer regarding method signature.

Disadvantage:

Since it only runs at runtime, if it is buried within conditional statements that only run on xmas, you may get a call on your holiday to get your budd to the office and fix it.

Not that you can’t use type hinting with primitives.

Array sorting

First an explanation about big O notation. If you have f(x) = 6x4 − 2x3 + 5. Then to simplify the equation, as x approaches infinity, the only number that seems to matter is x4 as all other parts of the equation become more and more insignificant as x grows.

This means we can say f(x) is almost equal to  x4 or f(x) = O(x4).

 In sorting, For typical sorting algorithms good behavior is mathcal{O}left( n log nright) and bad behavior is mathcal{O}left( n^2 right). The ideal is Ideal behavior for a sort is mathcal{O}left( n right), but since comparison is needed in programming algorithms, we have to settle for at least O(n log n).

 Popular sorting algoriths:

  • Bubble sort: Starts at the beginning of the data set, compares the first two elements and swaps (if neccesary) the lowest element first. Repeats the same comparison until the end of the list, and then starts again in element 2. Highly unefficient. A 100 elements array will need about 1ooo comparison tasks.  Bubble sort average case and worst case are both O(n²). Here’s an example:

    function myBubbleSort(arrayName,length) {
    for (var i=0; i<(length-1); i++){ for (var j=i+1; j
  • Insertion sort: Efficient in small lists, but expensive, because it creates a new array to accomodate all elements of the unsorted array there in order as the insertion happens.
  • Shell sort: one of the fastest algorithms to sort data, but very unefficient in large data sets. It arrange the data sequence in a two dimensional array, and then in the vertical columns of the array it uses intersion sort to the columns. The you decrease the number of columns and do it again.
  • Merge sort. Divides the data set into lists of two elements (1 and 2, 3 and 4, etc), sort the lists, and then create new lists of 4 with the resulting lists, sort them again and create lists of 8, etc, until all list is sorted. Scales well with large lists because its worse case scenario is O(n log n).
  • Heap sort. It puts the data set in a data structure called heap, which is a binary tree where the smallest (or largest) element is the root, and childen of each node are also smaller than their parent. When a node is removed, the heap updates itself again to reflect that rule.  Heaps run on O(n log n).
  •  Quicksort: Based on a mid number, partition the list and moves all elements lower than the number to one side of the list and the elements bigger than that number to the other part. Then recursively repeats the same algorithm until finish. One of the fastest sorting algorithms, but depends on choosing the right pivoting point as the median, if so we get O(n log n) performance, if not we may get closer to O(n²), yet we need to O(n) operation to determine the median, so that also adds up to the execution time.

MVC architecture

It is a design pattern that helps separate business logic from input and presentation, making it easier to maintain each one of those components independenly from each other.

Model: it is the representation of data according to the application’s function or domain. It includes data access but it is not exclusively the retrieval or records.

View: renders the model so it can interact with users. It is the UI. It can have several manifestations for a given Model.

Controller: receives input and coordinates actions between the Model and the View. In the case of web servers translates HTTP requests into calls to backend and ultimately HTML pages.