Thursday, June 16, 2011

GET or POST method

A very old topic. But always remember the guiding rules:

1. No matter how many times a http request is submitted anew, if the http request will not result in a state-changing action, use GET.
For example, searching repeatedly will not change the database's contents(Well, you may want to record the statistic of keywords being searched which may cause change in database, but when i say the db's content won't get changed, you know what i mean: the request should not have detrimental effect if submitted repeatedly), so the search form could be a good candidate for GET method.

2. If a http request will cause state-changing action, use POST. For instance, charging a credit card.

Now let's explain why these rules. First of all, we have to know the distinction between GET and POST.

The first and very obvious difference is using GET, the data is submitted via the URL. And you may also know that the maximum URL length depends on the browser.

Another distinction is if a request had been submitted using POST method, and the user tries to reload the page, the browser will warn the user if he wants to submit the data again so it can prevent the request from being executed again accidently.

Now, let's assume we just submit our credit card data and get charged. If the method is GET, and we accidently reload the page, the browser will not warn us anything and we may get charged twice. So we better use POST in this case.

Anyway, they are just guiding rules. It doesn't mean you have to follow every time. Come to the end, it all depends on the requirements. For example, if you are developing a bunch of APIs and decide that all requests must be submitted using POST method, then just do it.

Wednesday, June 15, 2011

javascript prefer literal notation than constructor function

In javascript, we can create an object using object literal:
var obj = {};

We can also create an object using constructor function:
var obj = new Object();

I think most people from other OOP background will feel more comfortable with using constructor function. That was exactly what i did until i learned that it is not encouraged in javascript.

So, why do we say we should favor literal notation over constructor function?
1. literal notation is obviously shorter to type. Although for me, that is not a big deal. If constructor function can make things easier to understand and help reduce confusion, i don't mind typing a bit more.
2. It emphasizes that javascript objects are simply mutable hashes and not something that needs to be baked from a “recipe” (from a class). Well, this reason sounds more decent to me.
3. the Object() constructor accepts a parameter and, depending on the value passed, it may decide to delegate the object creation to another built-in constructor and return a different object than you expect.


// an empty object
var o = new Object();
console.log(o.constructor === Object); // true

// a string object
var o = new Object("I am a string");
console.log(o.constructor === String); // true

// normal objects don't have a substring() method,
// but string objects do
console.log(typeof o.substring); // "function"


This behavior of the Object() constructor can lead to unexpected results when the value you pass to it is dynamic and not known until runtime.

Let's have a look at Array literal. To declare an array, we can simply do:
var a = []
or
var a = new Array();

There is one obvious reason we should definitely avoid using Array constructor. Let's check through it in details. Say we create arrays with elements 1,2,3
//using literal

var a = [1,2,3];
//using constructor
var b = new Array(1,2,3);
//so far so good
for(var i=0; i<3; i++){
    console.log(a[i],b[i]);
}

Everything looks fine. Now, we simply want to create an array with element 1;
//using literal
var a = [1];

//using constructor
var b = new Array(1);
//now see the funny part
console.log(a[0]) //no problem, we get 1
console.log(b[0])//big problem! we get 'undefined'!!!

How come this happen? It turns out that when we pass a single number to the Array() constructor, it doesn’t become the value of the first array element. It sets the length of the array instead! So, new Array(1) creates an array with length of 1, but no actual elements! How awful it is!

What if we do var b = new Array(3.14)? Well, you will simply get "RangeError: invalid array length"

Thursday, June 9, 2011

a book about server side javascript

More specifically, it is a book about Node.js: "Node: Up and Running: Scalable Server-Side Code with JavaScrip".

The book will be available at September 22, 2011 and I'm really looking forward to it.

is server side javascript going to replace PHP?

Today, i read this news, it is from twitter: "Douglas Crockford says Yahoo is the biggest PHP factory in the world, and is looking to replace it with Node.js (Server-Side JavaScript)".

Wow, if that is true, that is really exciting. I don't want to compare javascript with PHP from language point of view. I just simply believe that if we can use one language on both frontend and backend, the world of web will become better. I express this feeling in one of my blog: http://hengrui-li.blogspot.com/2011/05/server-side-javascript-when-will-you.html

Although i don't think things can go quickly and easily, i would like to believe this can come true one day. Sometimes, what you need is just a simple belief and hold it.

Wednesday, June 8, 2011

javascript loop performance

javascript has several types of loops

1. for loop
Probably it is the most usual loop in javascript:
for (var i=0; i<items.length; i++) {
    handle(items[i]);
}

2. while loop
var i=0;
while(i < items.length) {
    handle(items[i]);
    i++;
}

3. do while loop
this loop ensures the loop body gets executed at least once.
var i=0;
do {
   handle(items[i]);
   i++;
} while (i < 10);

The above three loop types are quite common in other language as well. Here is another javascript specific loop:

4.for-in loop
for (var i in items) {
    handle(items[i]);
this loop enumerates the named properties of any object.

Performance:

Only one loop is significantly slower than the others: for-in loop. It is slower due to the fact that each iteration results in a property lookup either on the instance or a prototype. Each time the loop is executed, the 'i' is filled with the name of another property that exists on the object 'items' until all properties have been returned. The returned properties are either on the object instance or inherited through the prototype chain. So, unless you have to iterate over object properties, for-in loop should not be used.

Except for-in loops, other loop types are so close in performance that it doesn't worth trying to determine which is faster. The choice should be based on your requirement instead of performance.

So if loop type doesn't matter in performance, what does? Two issues:
1. Tasks that must be done in loop, the obvious one is the body of the loop: handle(items[i])
2. Number of iterations, very obviously.

When it comes to issue 1, it is not as that simple as it looks. Let's check through loop type 1 in details.

for (var i=0; i<items.length; i++) {handle(items[i]);}

1. The loop first initiate a variable i=0. Fortunately, this task only has to be done once.
2. items.length is a property lookup that has to be done every time in the loop
3. i < items.length is a comparison that has to be done every time
4. (i < items.length) == true is another comparison every time
5. one increment operation i++ every time
6. array lookup every time: items[i]
7. handle(items[i]) every time.

Such a simple loop actually contains a lot of operations. The performance of this loop largely depends on handle(items[i]) function. But, reducing the total number of operations can still help in performance.

1. we don't want to do property lookup, items.length, every time, due to the fact that it is quite unlikely that the length could be changed during the loop. So, we can just do it once:

for (var i=0, length=items.length; i<length; i++){handle(items[i]);}

2. i < items.length, (i < items.length) == true are comparisons every time. We can try to reduce the comparisons by reversing the loop order. Usually, the order in which item is handled is irrelevant to the task. So, we can start the loop from the last item to the first item:

for (var i=items.length; i--;){handle(items[i]);}

In this way, we now simply compare 'i' against zero. Control conditions are compared against the value true, and any nonzero number is treated as true automatically, while zero is equivalent of false. So two comparisons(Is i less than the total items.length? Is that equals to true?) has been reduced to one comparison(Is the value true)

Finally, function based iteration, forEach. It is introduced in 4th editon of ECMA-262. 
items.forEach(function(value, index, itemsArray){handle(value);});

You may already see some implemetations in popular js libraries. One example is Prototype's items.each().

Comparing function based iteration with basic loop types in performance is not that fair, at least that is what i think. Because in some situations function based iteration is very handy and convenient. But if we have to compare, then, as you may already expect, function based iteration is quite slower than basic loop types, due to the overhead that an extra method has to be called every time.

Saturday, June 4, 2011

design patterns - null object pattern

As we know, if conditional statement is one thing that hurts the program readability. NULL object is also one approach to reduce your application's if condition statements. We are all familiar with these kind of code:

$user = $userDao->getUserById($id);
//For objects, i personally like to use instanceof for type checking
//but more usually, other programmers simply check $user !== null.
if ($user instanceof UserObject) {
       //do some logic with $user here
       echo $user->getName();
} else {
       //do some other things if $user is null
      echo 'user not exists';
}


As we can see, we usually use if conditional statement to check if $user is null or not, and then behaves differently based on the checking result. This kind of if statement checking could be all over the whole application. NULL object is here to help, for simplicity, i will ignore the interface part, let's check the code:

class User implements iUser
{
       private $_name;
       public function getName() {
               return $this->_name;
       }
}

class NullUser implements iUser
{
       public function getName() {
               return 'not exists';
       }
} class UserDao {         public function getUserById($id) {                 //query the database or do what ever to get the user                 $user = $this->find($id);                 if ($user === null) {                        return new NullUser();                 }                 return $user;         } } //Now your domain logic will become quite straight forward and more readable: $user = $userDao->getUserById($id);
echo $user->getName();


Now you can see how NULL object pattern can help simplify your business logic, however, you must be very careful with using this pattern. Although it simplifies your domain logic and increases readability, it does complicate your design and maintenance. And if a programmer is not aware of a NULL object implementation, he may redundant the null test, or he may really want to do some different thing if the object is null. Null object may also bring you issues when it comes to CURD operation, for example:
if ($user !== null) {
    //db query:
    $posts= $articleDao->getUserPosts($user);
}
//if we use null object, we will do the db query anyway,
//which might not be necessary
$posts= $articleDao->getUserPosts($user);

Personally, i totally agree that we should try to reduce if conditional statement in our application, particularly in business domain. But when it comes to checking if an object is null or not, i feel that i can accept that, because usually, the logic is not complex when an object is null, or even there is no logic when an object is null, for example:

$user = $userDao->getUserById($id);
if ($user instanceof UserObject) {
       //do some logic with $user here
       echo $user->getName();
//that is it, we don't have to do anything when $user is null




Thursday, June 2, 2011

Design Patterns - Strategy

Strategy Pattern Definition: the Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

I know a lot of websites are quite simple and some web developers only know CURD and once the domain logic becomes complex, they start to struggle and start to create crap. But, anyway, complex conditional logic is one thing that makes program hard to read & understand. To improve readability, We can replace conditional logic with strategy pattern + factory pattern.

For example, we have logic below:
//some how we get a format value dynamically
$format  = $objOne->getFormat();
$context = $objTwo->getContext();

if ($format === 'xml') {
    //start to format $context into xml format
} elseif ($format === 'txt') {
    //format text
} elseif ($format === $somethingElse && $someotherConditionCheck) {
    //another format implementation
}

Let's see how to use Strategy and Factory Pattern to improve the code.

From the definition, we know that we should define an interface for a set of algorithms, for example:

interface FormatStrategy
{
    public function format($content);
}

Now, we can implement our algorithms. Each one is a separate class that implements FormatStrategy Interface:
class XmlFormat implements FormatStrategy
{
    public function format($content)
    {
        //do some xml format
        return $content . ' in xml';
    }
}

class TxtFormat implements FormatStrategy
{
    public function format($content)
    {
        //do some txt format
        return $content . ' in text';
    }
}
We defined two for algorithms and they both implement the same interface. Next, we must define some kind of strategy selector(Factory):

class FormatStrategySelector
{
    public static function getStrategy($strategy) 
    {
        switch($strategy) 
        {
            case 'xml':
                return new HtmlFormat();
                break;
            default:
                return new TxtFormat();
                break;
        } 
    }
}

To use strategy:

$format  = $objOne->getFormat();
$context = $objTwo->getContext();

$formattedContent = FormatStrategySelector::getStrategy($format)->format($context);