Tuesday, April 2, 2013

JavaScript: A Love-Hate Relationship

I’ve been programming in Java for a greater part of my professional career. As web development got more powerful and demanding (and complex), I ended up dealing with client-side JavaScript more often than I wanted. In most of these cases, I’ve come to hate it. To avoid it, I considered alternatives like Adobe’s Flex and GWT.

Until about five (5) years ago, when I sat down and really started learning JavaScript, I started to love it. It felt like one of those new year’s resolutions that I failed to complete. Good thing, I faced projects that relied heavily on jQuery and Google Maps JavaScript API. With that, I was forced encouraged to dive in and learn JavaScript. So far, I’m glad I did.

Variables and Primitive Data Types

How many primitive data types does JavaScript have? Three: string, numeric, and boolean. It only has three primitive data types compared to the eight of Java. Wow! How simpler could it get?!

As it turns out, there are two more primitive data types: null and undefined are also considered primitive data types. Undefined is the values of a variable with no value. Variables can be emptied by setting the value to null.

Note that primitive data types are automatically wrapped as objects (e.g. a string literal is automatically wrapped as a String object). This makes them possess properties and methods.

var text = 'hello'; // or text = new String('hello');
var len = text.length; // returns a number
text.charAt(1); // returns 'e'

Native Objects

The JavaScript language provides some native objects: Array, Function, Date, Error, and Math. Objects can have properties and methods. Objects are key-value pairs. The code snippet below shows an object with five properties. Two of which are functions.

var myObject = {
  prop1: 'hello',
  prop2: false,
  prop3: new Date(),
  function1: function(param1, param2) {. . .},
  function2: function() {. . .}
};

// the above is equivalent to this:
var myObject2 = {
  'prop1': 'hello',
  'prop2': false,
  'prop3': new Date(),
  'function1': function(param1, param2) {. . .},
  'function2': function() {. . .}
};

// accessing the properties is like indexing a map
alert(myObject['prop1'] == myObject.prop1); // true

No Classes, Just Objects

As I dug deeper, I found it confusing that there are no classes, just objects. Coming from a Java background, I wanted to learn how to apply OOP. With that, I looked for creating private member variables and functions. JavaScript is a class-free, prototypal language. Instead of defining classes, and creating objects based on classes, it simply creates objects that inherit from (parent) objects that act as classes.

JavaScript is a prototype-based language.

Prototype-based programming is a style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is accomplished through a process of decorating existing objects which serve as prototypes. This model is also known as class-less, prototype-oriented, or instance-based programming.

JavaScript MDN

This is the part I found confusing. But after a while, it’s becoming clear. Declaring a class in JavaScript is as easy as defining a function.

function Student(name) {
  // This is the constructor
  // We can add properties (instance variables) to "this"
  this.name = name;
}

Since functions are objects in JavaScript, we can add properties and methods. In this case, we use the prototype property of a Function object to add methods.

Student.prototype.greet = function(greeting) {
  alert(greeting + ', my name is '
      + this.name);
};

Student.prototype.anotherMethod = function() {
};

We can create Student objects by calling the constructor with the new keyword.

var student1 = new Student('John Smith');
student1.greet('Hi'); // will display 'Hi, my name is John Smith'
alert(student1.name); // the name property is public

So, how can we provide private members to classes? In JavaScript, functions are used to provide scope and hide variables. For this, let’s change the public name property of the Student class to become private. We also add a public getter method to access the private name property.

function Student(name) {
  // This is the constructor
  // We can add public properties (instance variables) to "this"
  // this.name = name;
  var _name = name;
  this.getName = function() { return _name; };
}

This also changes the public member method in its reference to the private name property.

Student.prototype.greet = function(greeting) {
  alert(greeting + ', my name is '
      + this.getName());
};

Student.prototype.anotherMethod = function() {. . .};

Now that the name property is made private, the usage of Student class will also change.

var student1 = new Student('John Smith');
student1.greet('Hi'); // will display 'Hi, my name is John Smith'
alert(student1.name); // will return undefined
alert(student1.getName()); // will return 'John Smith'

Closures

JavaScript uses closures to provide access to variables that continue to exist even after the variables are out of scope. Let's take the following example from one of Douglas Crockford's talks.

var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var digit_name = function(n) {
  return names[n];
};

In the above example, the names array is declared at the global scope. We can move names as a variable inside the function (and avoid name clashes with other functions). The result looks something like this:

// var names = [];
var digit_name = function(n) {
  var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
  return names[n];
};

But the above is slower, since the names array would have to be (re-)initialized every time the function is called. Here's where we can use a closure to allow the function to continue to have access to the names array variable even after it is out of scope.

var digit_name = (function() {
  var names = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];

  // return a function
  return function(n) {
    // var names = [];
    return names[n];
  };
})();

Notice that the variable digit_name is assigned the result of a function call. To make it clearer, let’s try re-formatting the code. Hopefully, this makes it clearer.

var digit_name = (function() {...})();

The open-and-close parenthesis immediately calls the function. And that function returns a function.

var digit_name = (function() {... return function(n) {}; })();

Closures are also used to declare private members. In the Student class example, notice how the getName method still had access to the _name variable?

Understanding the Misunderstood

JavaScript is the world’s most misunderstood language largely because people aren’t taking the time to learn it. I hope that developers continue to take programming seriously.

It is the language that most people use without bothering to learn it first.

Programming is a complicated business. It should never be taken in ignorance.

Douglas Crockford - Senior JavaScript Architect, PayPal


Monday, January 28, 2013

The Problem is Fixed-Scope, Not Fixed-Price

The problem with fixed-price software projects (and contracts) is not really fixed-price; the problem is fixed-scope.

In this article, when I say fixed-price, I also mean fixed-budget. It is perfectly normal for an organization to provide a budget (maximum allowed monetary expense) for the creation of software to solve their problems. It is good that the organization determines how much they can afford to spend for the software, and put a cap on it; and anything beyond that is something they couldn’t afford.

So, if fixed-price is not the problem, then why is fixed-scope the problem?

People in the I.T. world often hear fixed-bid or fixed-price projects. We rarely hear fixed-scope projects. But underneath it all, any fixed-price project that has a lengthy detailed requirements document (more popularly known as RFP or request for proposal, or RFI or request for information) has a big chance of having fixed-scope. Instead of focusing on requirements, the lengthy RFP document goes on to specify a solution design. This solution design causes fixed-scope! This fixed-scope could be dangerous. Was the solution design tested? Was it verified to successfully satisfy the requirement and solve problems? If not, this fixed-scope becomes the problem.

Good business analysts can readily distinguish requirements from design. A good requirement should be design free. It should also be verifiable with acceptance tests. If the contractor has difficulty writing design-free requirements, it’s probably better to just write user stories.

With the detailed requirements document, the contractor (the organization looking for a vendor to develop its software) is already assuming that the solution (albeit incomplete and untested) is solving the problem, and is just looking for a vendor to supply the developers who’ll build the system (according to spec).

Detailed requirements are "actually" solution design

I watched Mary Poppendieck on her talk about Agile Under Contract. She points out the following lessons learned:

  1. Detailed requirements are "actually" solution design.
  2. Development is a learning process.
  3. Start with a clear understanding of the critical business results that must be delivered.
  4. Mitigate development risk with frequent delivery/assessment.

I won’t go through all four (4) lessons. I’ll focus on the first one, as it is most relevant here. Detailed requirements are "actually" solution design. Mary goes on to say that,

The responsibility of success lies with the solution designer.

Responsibility of success lies with the organization that specifies the detailed "requirements".

The problem is that the so-called detailed "requirements" in the RFP are "actually" solution design. Unfortunately, the solution design are done by amateurs who didn’t care enough to test and verify their solution. What if the solution design in the RFP was incorrect or incomplete? What if it conflicts with another section of the lengthy RFP? Who should be the one to fix/change it? The vendor that was hired to build the software, or the organization that approved and sent out the RFP?

For me, it should be the organization that approved the RFP in the first place. Since they’re the ones who "designed" the solution, they should be the one to correct it, and pay accordingly for the changes. Instead of coming up with a "pieced" together solution, they should go through the solution design (cut out a single flow from start to finish with some meaningful end, with limited options along the way) and have tests to prove that it works.

I often encounter RFPs that go into detail and even provide UI wireframes and screenshots. This level of detail gives them the false impression that the requirements/solution have been detailed. But they fall short of not having a domain model (or even a data model). It’s as if they copied portions of solutions that they liked (only God knows where they got them), and compiled them together. Any good business analyst would see that the solution does not "come together".

I hope to see more fixed-price projects that go through a more collaborative initial phase to flesh out the requirements, and develop a solution design that can be proven to work and solve stated problems. But be careful! I don’t want to go back to doing big design up front (BDUF). I prefer to see a time-boxed (two weeks or less) envisioning iteration (called iteration 0 in agile modeling) where the requirements are understood, and just enough modeling is done. This should allow for a better (understood) detailed "requirements" or solution design. And the development can start to build a small portion of the whole solution and have users (and other stakeholders) providing feedback. This feedback builds trust between contractor and vendor. Ideally, if the solution design is well done, it can be contracted to a another vendor (and not the vendor that helped design the solution).

What if the contractor does provide a good complete tested solution design (not the half-baked detailed requirements), can a vendor go fixed-price? The answer is definitely, yes! An experienced vendor (who has done something similar) can develop the system (based on the provided solution design) with great accuracy with the effort and its cost.

In fixed-price and fixed-scope projects, the only variable left is quality. Do we really want the quality of our software suffer? Can any contractor really live with fixed-price and fixed-scope projects knowing that quality is going to suffer?

References:

Saturday, December 22, 2012

Plain-vanilla Java Servlets and Pretty URLs

I'm writing this because I was recently asked about the growing complexity of Java-based web MVC frameworks. It made me think about the kinds of web applications a Java developer can build with just the plain-vanilla Java Servlets.

As I was pondering on the thought, I could not help ask myself about the following:

  • What happens to pretty URLs?
  • How can we add page templates like those provided by SiteMesh and Apache Tiles?

Pretty URLs and Mapping Conventions

It's common nowadays to consider question mark (?) and ampersand (&) characters in the URL as being ugly. But are they really that bad? Do they really affect SEO in a negative way? The truth is... it is just a myth. Why would Google (and other search engines) put so much weight on the URL? Fact is... Google will (and should) do a good job by looking into the contents the URL is pointing to. It should not just be looking at the URL. If it did put so much weight on URLs, then we'll all be filled with spammed links by those who just want to be on top of SERPs.

If so, how do we now map URLs to Java servlets? Below show the typical URL mapping.

MethodURLAction
GET/magazinesindex (default)
GET/magazines/{id}show
GET/magazines/{id}/editeditRender HTML form for editing magazine with given {id}
PUT/magazines/{id}updateUpdates magazine with given {id}. Redirect to GET /magazines.
GET/magazines/newnewRender HTML form for new magazine.
POST/magazinessaveSave magazine ad and generate new unique ID. Redirect to GET /magazines.
DELETE/magazines/{id}deleteRemove magazine with given {id}

Given the above URL mappings, it's impossible to implement using a web.xml. So, are we really forced to use the above conventions? Are we really forced to use a single servlet, mapped to /app/*, and have it apply a regular expression to determine which controller should handle the incoming request?

IMO, we should not be forced to do so. Assuming you'd allow URLs that contain question marks (?) and ampersands (&), we can have the following mappings.

MethodURLAction
GET/magazinesindex (default)
GET/magazines?id={id}show
GET/magazines?id={id}&editeditRender HTML form for editing magazine with given {id}
PUT/magazines?id={id}updateUpdates magazine with given {id}. Redirect to GET /magazines.
GET/magazines?newnewRender HTML form for new magazine.
POST/magazinessaveSave magazine and generate new unique ID. Redirect to GET /magazines.
DELETE/magazines?id={id}deleteRemove magazine with given {id}

The above mappings are definitely possible to implement in a web.xml. It just needs a servlet mapped to /magazines/*. It will also need a filter to support the translation of PUT and DELETE methods (as most browsers only support GET and POST). As for nested resources/namespaces, a similar approach applies. It will need another servlet mapped to /magazines/ads/*.

MethodURLAction
GET/magazines/ads?m_id={magazine_id}index (default)List ads under the magazine with the given {magazine_id}.
GET/magazines/ads?m_id={magazine_id}&id={id}showShow magazine ad with given {id}.
GET/magazines/ads?m_id={magazine_id}&id={id}&editeditRender HTML form for editing magazine ad with given {id}
PUT/magazines/ads?m_id={magazine_id}&id={id}updateUpdates magazine ad with given {id}. Redirect to GET /magazines/ads.
GET/magazines/ads?m_id={magazine_id}&newnewRender HTML form for new magazine ad.
POST/magazines/ads?m_id={magazine_id}saveSave magazine ad and generate new unique ID. Redirect to GET /magazines/ads?m_id={magazine_id}.
DELETE/magazines/ads?m_id={magazine_id}&id={id}deleteRemove magazine ad with given {id}

To extend the conventions further, each servlet acting as controller (in MVC) should forward to a view (typically implemented as a JSP). These JSPs can be located under /WEB-INF/views/magazines and /WEB-INF/views/magazines/ads to match their servlet URL mappings.

Templating Frameworks

I find it more and more common to use SiteMesh or Tiles in developing Java-based web applications. In fact, it would be uncommon to see a Java web application that does not use SiteMesh or Tiles.

After doing some research, I found a lesser known feature of Java Server Pages (JSPs) 2.0: <include-prelude> and <include-coda>. These allow developers to have templates included in the beginning and end of all JSPs that matched the URL.

An example configuration in web.xml looks like this:

  <jsp-config>
    <jsp-property-group>
      <url-pattern>*.jsp</url-pattern>
      <include-prelude>/WEB-INF/includes/prelude.jspf</include-prelude>
      <include-coda>/WEB-INF/includes/coda.jspf</include-coda>
    </jsp-property-group>
  </jsp-config>
The *.jspf is just a common filename extension for JSP fragments.

If the page layout is simple enough to allow a header and footer implemented as a prelude and coda, then using this JSP 2.0 feature should do the trick.

Conclusion

So, is it really that bad? What do you think?

IMO, it's not that bad. There's definitely more to building web apps using just plain Java Servlets and JSPs. But these alone are quite powerful. And the MVC frameworks enhance it further.

That's all for now. Happy holidays!

2019 September Update

If you'd like to know more, checkout how a Java Servlet works. It even contains a cool trivia about the people who created the Java Servlet 1.0 specification! Happy reading!