How to read a class diagram, and implement it using JavaScript

          

Read and implement a class diagram using JavaScript


Book Excerpt: Object-Oriented JavaScript

>What encapsulation, inheritance, and polymorphism mean
>How JavaScript functions work
>How to use anonymous functions and closures
>How to read a class diagram, and implement it using JavaScript
>How to work with JavaScript prototypes
>How the execution context and scope affect the output of JavaScript functions
>How to implement inheritance using closures and prototypes
>What JSON is, and what a JSON structure looks like
This chapter excerpt from Microsoft AJAX Library Essentials by Cristian Darie, Bogdan Brinzarea, is printed with permission from Packt Publishing, Copyright 2007.

JavaScript Classes

Not only can JavaScript functions contain other functions, but they can also be instantiated. This makes JavaScript functions a good candidate for implementing the concept of a class from traditional object-oriented programming. This is very helpful feature indeed, because JavaScript doesn't support the notion of a class in the classic sense of the word. Functions can be instantiated using the new operator, such as in this example:

var myHelloWorld = new ShowHelloWorld();

This line of code effectively creates an object named myHelloWorld, which represents an instance of the ShowHelloWorld() function. When the object is instantiated, the function code is executed, so creating the object has the same effect as calling ShowHelloWorld() as in the previous examples.

Here are a few facts that will help you port your C# OOP knowledge into the JavaScript world:  

  • When a function is used as a class, its body code is considered to be the constructor. In classic OOP, the constructor is a special method that doesn't return anything, and that is called automatically when the object is created. The same effect happens in JavaScript when creating an instance of the function: its code executes. A C# constructor is equivalent to the code in the JavaScript function—without including any inner functions (whose code doesn't execute automatically).
  • In C# constructors can receive parameters, and also in JavaScript. If the code in a function represents the "class constructor", the parameters received by that function play the role of constructor parameters.
  • Class fields in JavaScript are created and referenced with the this keyword. In a JavaScript function, this.myValue is a public member of the function (class), while myValue is a local variable that can't be accessed through function instances. Also, the local variable is destroyed after the function executes, while class fi elds persist their value for the entire object lifetime.
  • Class methods that need to be accessible from outside the class need to be referred to using this as well. Otherwise the inner function will be regarded as a local function variable, rather than a "class" member.

We'll demonstrate these concepts by transforming the ShowHelloWorld() function that you saw earlier into a "real" class. We will:

  • Change the name of the function from ShowHelloWorld() to HelloWorld().
  • Add a parameter named hour to the function's "constructor" so that we tell the class the hour for which we need a greeting message, when instantiating it. If this parameter is passed when creating objects of the class, we store it for future use as a class fi eld. If this parameter is not specifi ed, the current hour of the day should be stored instead.
  • The method DisplayGreeting() of the class should not support the hour parameter any longer. Instead, it should display the greeting message depending on the hour fi eld that was initialized by the constructor.

Once your new class is created, you use it just as you'd use a C# class. For example, this is how you'd create a new class instance, and call its DisplayGreeting() method:

 // create class instance
var myHello = new HelloWorld();
// call method
myHello.DisplayGreeting();

A possible implementation of the HelloWorld class is the following:

// "Hello, World" class
function HelloWorld(hour)
{
// class "constructor" initializes this.hour field
if (hour)
{
// if the hour parameter has a value, store it as a class field
this.hour = hour;
}
else
{
// if the hour parameter doesn't exist, save the current hour
var date = new Date();
this.hour = date.getHours();
}
// display greeting
this.DisplayGreeting = function()
{
if (this.hour >= 22 || this.hour <= 5)
document.write("Goodnight, world!");
else
document.write("Hello, world!");
}
}

This code can be tested online at http://www.cristiandarie.ro/asp-ajax/ JavaScriptClass.html. The HelloWorld class is formed of the constructor code that initializes the hour fi eld (this.hour), and of the DisplayGreeting() method—this.DisplayGreeting(). Fans of the ternary operator can rewrite the constructor using this shorter form, which also makes use of the object detection feature that was discussed in Chapter 2:

// define and initialize this.hour
this.hour = (hour) ? hour : (new Date()).getHours();

Class Diagrams

JavaScript classes, just like C# or VB.NET classes, can be described visually using class diagrams. There are standards such as UML (Unifi ed Modeling Language), that can be used to model classes and the relationships between them. In this book we'll show quite a few class diagrams using the notation used by Visual Studio 2005. Using this notation, the HelloWorld class shown earlier would be described as shown in Figure 3-2.

The diagrams to this book follow typical conventions for C# classes, which don't translate to JavaScript exactly. For example, the diagram in Figure 3-2 says that the HelloWorld class has an integer fi eld named hour. However, JavaScript doesn't support specifying data types for variables or class fi elds. The data type of the fi eld makes the diagram helpful in specifying the intended purpose and type of the fi eld, but that type isn't used in the actual implementation of the class.

The diagram also mentions the HelloWorld() constructor, which receives an integer parameter. As you know, JavaScript doesn't support "real" constructors. However, by reading the diagram you can tell that the HelloWorld() function receives a parameter named hour, which is supposed to be an integer value.

Appendix A contains more details about the conventions used in class diagrams throughout this book.

C# and JavaScript Classes

For the purpose of demonstrating a few more OOP-related concepts, we'll use another class. Our new class is named Table, and it has two public fi elds (rows, columns), and one method, getCellCount(). The getCellCount() method should return the number of rows multiplied by the number of columns. The class constructor should receive two parameters, used to initialize the rows and columns fields. This class could be represented by the class diagram in Figure 3-3.

The C# version of this class would look like this:
public class Table
{
// public members
public int rows = 0;
public int columns = 0;
// constructor
public Table(int rows, int columns)
{
this.rows = rows;
this.columns = columns;
}
// method returns the number of cells
public int getCellCount()
{
return rows * columns;
}
}

Y ou'd instantiate and use the class like this:

Table t = new Table(3,5);
int cellCount = t.getCellCount();

The Table class can be easily implemented in JavaScript as shown in the following code snippet, and it would resemble very much its C# version:

function Table (rows, columns)
{
// "constructor"
this.rows = rows;
this.columns = columns;
// getCellCount "method"
this.getCellCount = function()
{
return this.rows * this.columns;
};
}

After having declared the object, we can instantiate it by using the new operator and use its properties and methods:

var t = new Table(3,5);
var cellCount = t.getCellCount();

There are a few subtle points you need to notice regarding the JavaScript implementation of Table:

  • You don't declare public members explicitly. You simply need to reference them using this, and assign some value to them; from that point on, they're both declared and defi ned.
  • JavaScript allows you to implement most of the design specifi cations defi ned in class diagrams, but the implementation can't refl ect the specifi cation as accurately as a C# implementation can. For example, the line Table (int rows, int columns) in the diagram in Figure 3-3 refers to the constructor of the class. In JavaScript, as you know, classes as implemented using functions neither have real constructors, nor support specifying data types for their parameters.
  • When objects are created, each object has its own set of data—to maintain its own state. However, C# and JavaScript are different in that in JavaScript functions are fi rst-class objects. In C#, the "state" is made of the object's fi elds. The object functionality, as defi ned by its methods, is the same for all objects of the same type. For example, if you create many objects of the type Table in C#, each object will have its own set of rows and columns, but internally they all use the same copy of the getCellCount() method. In JavaScript, however, functions are treated like any other variable. In other words, creating a new Table object in JavaScript will result not only in creating a new set of rows and columns values, but also in a new copy of the getCellCount() method. Usually, you don't need (or want) this behavior.
  • The last mentioned problem is commonly referred to as a "memory leak", although technically it's just ineffi cient JavaScript object design. When we design our JavaScript "classes" as we do in typical OOP languages, we don't need each class to create its own set of methods. It's only state (fi elds) that need to be individual, and not methods' code. The good news is that JavaScript has a neat trick that we can use to avoid replicating the inner function code for each object we create: referencing external functions.

Referencing External Functions

Instead of defi ning member functions ("methods") inside the main function ("class") as shown earlier, you can make references to functions defi ned outside your main function, like this:

function Table (rows, columns)
{
// "constructor"
this.rows = rows;
this.columns = columns;
// getCellCount "method"
this.getCellCount = getCellCount;
}
// returns the number of rows multiplied by the number of columns
function getCellCount()
{
return this.rows * this.columns;
}

Now, all your Table objects will share the same instance of getCellCount(), which is what you will usually want.

Thinking of Objects as Associative Arrays

 

A key element in understanding JavaScript objects is understanding the notion of associative arrays, which are nothing more than collections of (key, value) pairs. As a .NET developer you have worked with associative arrays represented by classes such as NameValueCollection, Hashtable, dictionaries, and others. Unlike with normal arrays, where the key is numeric (as in bookNames[5]), the key of an associative array is usually a string, or even other kinds of objects that can represent themselves as strings. For example, take a look at the following code snippet, where we retrieve the name of the book by specifying a unique string value that identifi es that book:

// retrieve the name of the book
bookName = bookNames["ASP_AJAX"];

The concept is simple indeed. In this case, the key and the value of the bookNames associative array are both strings. This associative array could then be represented by a table like this:

Key                                    Value
ASP_AJAX                        Microsoft AJAX Library Essentials
AJAX_PHP                       AJAX and PHP: Building Responsive Web Applications 
SEO_ASP                        Professional Search Engine Optimization with ASP.NET 

The table above can be represented in JavaScript, as an associative array, like this:

// define a simple associative array
var bookNames =
{ "ASP_AJAX" : "Microsoft AJAX Library Essentials",
"AJAX_PHP" : "AJAX and PHP: Building Responsive Web Applications",
"SEO_ASP" : "Professional Search Engine Optimization with ASP.NET"
};

The key of an element doesn't have to be literal; it can even be specifi ed through a variable: 

// store the book ID in a variable
var bookId = "ASP_AJAX";
// display the name of the book
document.write("The name of " + bookId +
" is " + bookNames[bookId] + "<br />");

In JavaScript, however, the implementation of the associative array is more powerful, in that it makes no restriction on the type of the value of the (key, value) pair. The value can be a number, a string, a date, or even a function! This fl exibility allows us to represent JavaScript objects as associative arrays. For example, an instance of the Table class that we discussed earlier can be represented like this:

// create Table object
var t =
{ rows : 3,
columns : 5,
getCellCount : function () { return this.rows * this.columns; }
};

// display object field values
document.writeln("Your table has " + t.rows + " rows" +
" and " + t.columns + " columns<br />");

// call object function
document.writeln("The table has " + t.getCellCount() +
" cells<br />");

This example, and the one presented earlier with book names, can be tested online at http://www.cristiandarie.ro/asp-ajax/Associative.html, and the result is presented in Figure 3-4.


Related Links
>Object Oriented Programming Interview Questions

Concurrency with AOP

Concurrency is the system's ability to act with several requests simultaneously, such a way that threads don't corrupt the state of objects when they gain access at the same time............

Transparent caching with AOP 

To get better results in terms of speed and resources used, it's suggested to use a cache. We can store in it the results corresponding to the methods' invocations as key-value pairs: method and arguments as key and return object as value..............

Security with AOP

Security is one of the most important elements of an application. The word "security" covers two concepts: Authentication is the verifi cation's process of a principal's identity; a principal is typically a user. A principal in order to be authenticated provides a credential that is the password. Authorization, on the other hand, is the process of granting authorities, which are usually roles, to an authenticated user...........

OOPS in .NET

What is the relation between Classes and Objects? Explain different properties of Object Oriented Systems. What is difference between Association, Aggregation and Inheritance relationships? Explain the features of an abstract class in NET. Difference between abstract classes and interfaces Similarities and difference between Class and structure in .NET Features of Static/Shared classes. What is Operator Overloading in .NET?............. 

What are the advantages of OOP?

It presents a simple, clear and easy to maintain structure. It enhances program modularity since each object exists independently............

What encapsulation, inheritance, and polymorphism mean

In OOP's world everything revolves around objects and classes, and OOP languages usually offer three specifi c features for manipulating them—encapsulation, inheritance, and polymorphism........



Write your comment - Share Knowledge and Experience


Latest placement tests
Latest links
 
Latest MCQs
» General awareness - Banking » ASP.NET » PL/SQL » Mechanical Engineering
» IAS Prelims GS » Java » Programming Language » Electrical Engineering
» English » C++ » Software Engineering » Electronic Engineering
» Quantitative Aptitude » Oracle » English » Finance
Home | About us | Sitemap | Contact us | We are hiring