Thursday, March 31, 2011

javascript object oriented programming 3 - inheritance

inheritance - more details

Let's review the simple inheritance example in my last  blog:

//constructor method
function Person(name, sex) {
       this.name = name;
       this.sex = sex;
   }
//define Person prototype 
Person.prototype = {
       getName: function() {
           return this.name;
       },
       getSex: function() {
           return this.sex;
       }
}
//define an Employee constructor method
function Employee(name, sex, employeeID) {
    this.name = name;
    this.sex = sex;
    this.employeeID = employeeID;
}

Employee.prototype = new Person();
Employee.prototype.getEmployeeID = function() {
    return this.employeeID;
};
As we said, there are some problems in this inheritance. Let's address these problems one by one.
1. When we create the Employee constructor method and protoype, we also have to create a Person instance. It is not reasonable and not efficient.
To fix this issue, we should try to inherit the prototype only. We should put reusable properties and methods into prototype. Let's change our code:
Employee.prototype = Person.prototype;

In this way, every time we create a new Employee object, it can access any methods and properties in Person's prototype too. And we don't need to instance a Person object.

2. Another problem is Employee's prototype is completely re defined, this will cause Employee's constructor is referencing to the wrong object. Try the code below:


var e = new Employee('henry', 'm', 25);
console.log(e.constructor == Employee); //false
The constructor is not pointing to itself. To fix this issue, we simply change our code to this:
Employee.prototype = Person.prototype;
Employee.prototype.constructor = Employee.
3. Directly copying Person's prototype to Employee's prototype is easy and efficient. But it does bring some side effects. Employee's prototype is pointing to the same object, the Person's prototype, Employee's prototype properties and methods will complete override its parent object's prototype's same name properties and methods.
For example, if we also define a getName method in Employee's prototype:
Employee.prototype.getName = function(){return 'henry'};
var p = new Person('Jack', 'm');
p.getName(); //henry

To fix this issue, we must break the chain. We need to introduce an intermediary. We create an empty functoin F(){} first. Then we set its prototype to Person's prototype: F.prototype = Person.prototype. Now, let's see how we should do the inheritance:
function F(){};
F.prototype = Person.prototype;
Employee.prototype = new F();
Employee.prototype.constructor = Employee;

4. How to call parent object's method in child object? Javascript doesn't have someting like PHP's 'parent::' feature. There are several implementations for this. I just use a simple and traditional way: uber property. Finally the inheritance mechanism is:
var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;

What is the uber? Let's change our Person's getName method:
getName: function() {
var parentName = '';
if (this.constructor.uber) {
if (this.constructor.uber.getName) {
         parentName = this.getName();
}
   }
   return this.name + "'s parent is " + parentName;
}

Monday, March 28, 2011

javascript object oriented programming 2: inheritance

Inheritance - simple way

First, we need to know prototype. We can think prototype as a template. In javascript, everything is an object, every object has its own prototype.

A simple inheritance in javascript:
//constructor method
function Person(name, sex) {
       this.name = name;
       this.sex = sex;
   }
//define Person prototype 
Person.prototype = {
       getName: function() {
           return this.name;
       },
       getSex: function() {
           return this.sex;
       }
}
//define an Employee constructor method
function Employee(name, sex, employeeID) {
    this.name = name;
    this.sex = sex;
    this.employeeID = employeeID;
}
// Make Employee.prototype link to an instance of Person
// The Person instance can call the methods in Person prototype, so Employee's instances can access methods and properties of Person prototype as well.
Employee.prototype = new Person();
Employee.prototype.getEmployeeID = function() {
    return this.employeeID;
};
However, there are some problems with such a simple inheritance.
1. When we create the Employee constructor method and protoype, we also create a Person instance. That is not reasonable.
2. Employee's constructor method cannot access its parent/super class Person's constructor method.
3. Employee's constructor is pointing to the wrong place.
We will see how to address all these problems in my next blog.

Pass parameters to a function/expression called within setTimeout

javascript's setTimeout(aFunction,  timeout); Sometimes we need to pass parameters to aFunction. To do this, we must use 'closure': setTimeout(funciton(){aFunction(parameter)}, timeout);

Saturday, March 26, 2011

javascript object oriented programming 1:create objects

how to create objects One way to create an object:
var ship = {
     wings: 'wings',
     body: 'body',
     jet: 'jet',
     guns: 'guns'
};
Now, we have a ship object. This object has 4 properties:wings,body,jet,guns. An object property can contain a function, we call it a method.
var ship = {
     wings: 'wings',
     body: 'body',
     jet: 'jet',
     guns: 'guns',
     fire = function () {
         return 'start to fire';
     }
};
Now our ship object has a method fire. Accessing Object's properties We can access an object's properties by using either square bracket notation or dot notation. For example: ship.wings or ship['wings']. Dot notation is easier to read and write. Accessing a non-existing property returns 'undefined': ship.tail. Calling Object's methods ship.fire() invokes the fire function and returns the value 'start to fire'. Calling a non-existing method causes error: ship.move(). Using keyword 'this' Let 's add a method to our ship.
var ship = {
     wings: 'wings',
     body: 'body',
     jet: 'jet',
     guns: 'guns',
     fire = function () {
         return 'start to fire';
     }
     getGuns = function() {
         return this.guns;
     }
};
'this' actually refers to this object or current object. Another way to create objects is to use constructor function. This way is actually more familiar to people with java or php5 background.
function Ship(model) {
 this.model = model;
 this.wings = 'the wings';
 this.body  = 'the body';
 this.jet   = 'the jet';
 this.guns  = 'the guns';
 this.fire  = function() {
  return this.guns + ' start to fire';
 };
 this.getModel = function(){return this.model};
}
var shipOne = new Ship(1);
var shipTwo = new Ship(2);
We can also create a new object in this way, although it looks a little wierd:
var shipOne = new Ship(1);
var shipTwo = new shipOne.constructor(2);
This works because constructor property refers to a function and we can call this function to return a new object. We use instanceof to tell an object's type: if (shipTwo instanceof Ship){}; In javascript, object is passed by reference, same to most of other OOP langauges. Global Object In javascript, the host environment provides a global object and all global variables are actually properties of the global object. If your host environment is the web browser, the global object is called window.

Wednesday, March 23, 2011

PHP singleton inheritance

Prior to PHP 5.3, here is how we implement singleton:
class Service
{
private static $_instance = null;
private function __construct(){};
private function __clone(){};

public static function getInstance()
{
if (self::$_instance === null) {
self::$_instance = new self;
}
return self::$_instance;
}
}

However, we all know that it is very tricky if we want to extend/inherit this singleton class.
PHP 5.3 introduces LSB, which stands for Late Static Binding. It solves our problem of inheriting a singleton class. In PHP 5.3, we implement singleton in this way
class Service
{
private static $_instance = null;
private function __construct(){};
private function __clone(){};

public static function getInstance()
{
if (static::$_instance === null) {
static::$_instance = new static;
}
return static::$_instance;
}
}

Simply replace the 'self' keyword with 'static', we can inherit a singleton just like usual inheritance.

The difference is self keyword is bound to the referenced property or method at compile time. The self keyword points to the containing class and is unaware of subclasses. The static keyword forces PHP to bind to the code implementation at the latest possible moment.

how to use left join in mysql

Let's setup two tables for our experiment.

create table student(id int primary key auto_increment, name varchar(255));

insert into student (name) values('henry'),('jack'),('alice');

create table class_a(id int primary key auto_increment, student_id int, registered_datetime datetime);

insert into class_a(student_id, registered_datetime) values(1,now());


We use a simple left join to see the result:


select s.*,c.id as class_id from student s left join class_a c on s.id = c.student_id;
+----+-------+----------+
| id | name | class_id |
+----+-------+----------+
| 1 | henry | 1 |
| 2 | jack | NULL |
| 3 | alice | NULL |
+----+-------+----------+


We can see that left join returns all rows from the left table(student) even the student may not have a match in the right table(class_a). In this case, any c

So thing are quite obvious now. If we only want to get the students that are not registered in class_a, we can simply add a filter for left join:

select s.*,c.id as class_id from student s left join class_a c on s.id = c.student_id where c.id is null;
+----+-------+----------+
| id | name | class_id |
+----+-------+----------+
| 2 | jack | NULL |
| 3 | alice | NULL |
+----+-------+----------+

Tuesday, March 22, 2011

phpundercontrol build success even with php codesniffer violation error

This issue had been confusing me for a while, cause it seems phpundercontrol will build fail only when phpunit failed.

Later i check the difference in the build.xml between PHPUnit target and CodeSniffer target. I found PHPUnit is setup like this '' while codesniffer doesn't have 'failonerror="on"', after i add it to codesniffer target, phpundercontrol will build fail if there is any codesniffer violation.