Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, July 4, 2023

Using a site map for generating dynamic menus in web applications

In the last few weeks, I have been playing around with a couple of old and obsolete web applications that I have developed in the past with my own web framework. Much of the functionality that these custom web applications offer are facilitated by my framework, but sometimes these web applications also contain significant chunks of custom code.

One of the more interesting features provided by custom code is folding menus (also known as dropdown and dropright menus etc.), that provide a similar experience to the Windows start menu. My guess is that because the start menu experience is so familiar to many users, it remains a frequently used feature by many web applications as of today.

When I still used to actively develop my web framework and many custom web applications (over ten years ago), implementing such a feature heavily relied on JavaScript code. For example, I used the onmouseover attribute on a hyperlink to invoke a JavaScript function that unfolds a panel and the onmouseout attribute to fold a panel again. The onmouseover event handler injects a menu section into the DOM using CSS absolute positioning to put it in the right position on the screen.

I could not use the standard menu rendering functionality of my layout framework, because it deliberately does not rely on the usage of JavaScript. As a consequence, I had to write a custom menu renderer for a web application that requires dynamic menu functionality.

Despite the fact that folding menus are popular and I have implemented them as custom code, I never made it a feature of my layout framework for the following two reasons:

  • I want web applications built around my framework to be as declarative as possible -- this means that I want to concisely express as much as possible what I want to render (a paragraph, an image, a button etc. -- this is something HTML mostly does), rather than specifying in detail how to do it (in JavaScript code). As a result, the usage of JavaScript code in my framework is minimized and non-essential.

    All functionality of the web applications that I developed with my framework must be accessible without JavaScript as much possible.
  • Another property that I appreciate of web technology is the ability to degrade gracefully: the most basic and primary purpose of web applications is to provide information as text.

    Because this property is so important, many non-textual elements, such as an image (img element), provide fallbacks (such as an alt attribute) that simply renders alternative text when graphics capabilities are absent. As a result, it is possible to use more primitive browsers (such as text-oriented browsers) or alternative applications to consume information, such as a text-to-speech system.

    When essential functionality is only exposed as JavaScript code (which more primitive browsers cannot interpret), this property is lost.

Recently, I have discovered that there is a way to implement folding menus that does not rely on the usage of JavaScript.

Moreover, there is also another kind of dynamic menu that has become universally accepted -- the mobile navigation menu (or hamburger menu) making navigation convenient on smaller screens, such as mobile devices.

Because these two types of dynamic menus have become so common, I want to facilitate the implementation of such dynamic menus in my layout framework.

I have found an interesting way to make such use cases possible while retaining the ability to render text and degrade gracefully -- we can use an HTML representation of a site map consisting of a root hyperlink and a nested unordered list as a basis ingredient.

In this blog post, I will explain how implementing these use cases are possible.

The site map feature


As already explained, the basis for implementing these dynamic menus is a textual representation of a site map. Generating site maps is a feature that is already supported by the layout framework:


The above screenshot shows an example page that renders a site map of the entire example web application. In HTML, the site map portion has the following structure:

<a href="/examples/simple/index.php">Home</a>

<ul>
    <li>
        <a href="/examples/simple/index.php/home">Home</a>
    </li>
    <li>
        <a href="/examples/simple/index.php/page1">Page 1</a>
        <ul>
            <li>
                <a href="/examples/simple/index.php/page1/page11">Subpage 1.1</a>
            </li>
            <li>
                <a href="/examples/simple/index.php/page1/page12">Subpage 1.2</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="/examples/simple/index.php/page2">Page 2</a>
        ...
    </li>
    ...
</ul>

The site map, shown in the screenshot and code fragment above, consists of three kinds of links:

  • On top, the root link is displayed that brings the user to the entry page of the web application.
  • The unordered list displays links to all the pages visible in the main menu section that are reachable from the entry page.
  • The nested unordered list displays links to all the pages visible in the sub menu section that are reachable from the selected sub page in the main menu.

With a few simple modifications to my layout framework, I can use a site map as an alternative type of menu section:

  • I have extended the site map generator with the ability to mark selected sub pages and as active, similar to links in menu sections. By adding the active CSS class as an attribute to a hyperlink, a link gets marked as active.
  • I have introduced a SiteMapSection to the layout framework that can be used as a replacement for a MenuSection. A MenuSection displays reachable pages as hyperlinks from a selected page on one level in the page hierarchy, whereas a SiteMap section renders the selected page as a root link and all its visible sub pages and transitive sub pages.

With the following model of a layout:

$application = new Application(
    /* Title */
    "Site map menu website",

    /* CSS stylesheets */
    array("default.css"),

    /* Sections */
    array(
        "header" => new StaticSection("header.php"),
        "menu" => new SiteMapSection(0),
        "contents" => new ContentsSection(true)
    ),

    ...
);

We may render an application with pages that have the following look:


As can be seen in the above screenshot and code fragment, the application layout defines three kinds of sections: a header (a static section displaying a logo), a menu (displaying links to sub pages) and a contents section that displays the content based on the sub page that was selected by the user (in the menu or by opening a URL).

The menu section is displayed as a site map. This site map will be used as the basis for the implementation of the dynamic menus that I have described earlier in this blog post.

Implementing a folding menu


Turning a site map into a folding menu, by using only HTML and CSS, is a relatively straight forward process. To explain the concepts, I can use the following trivial HTML page as a template:


The above page only contains a root link and nested unordered list representing a site map.

In CSS, we can hide the root link and the nested unordered lists by default with the following rules:

/* This rule hides the root link */
body > a
{
    display: none;
}

/* This rule hides nested unordered lists */
ul li ul
{
    display: none;
}

resulting in the following page:


With the following rule, we can make a nested unordered list visible when a user hovers over the surrounding list item:

ul li:hover ul
{
    display: block;
}

Resulting in a web page that behaves as follows:


As can be seen, the unordered list that is placed under the Page 2 link became visible because the user hovers over the surrounding list item.

I can make the menu a bit more fancy if I want to. For example, I can remove the bullet points with the following CSS rule:

ul
{
    list-style-type: none;
    margin: 0;
    padding: 0;
}

I can add borders around the list items to make them appear as buttons:

ul li
{
    border-style: solid;
    border-width: 1px;
    padding: 0.5em;
}

I can horizontally align the buttons by adopting a flexbox layout using the row direction property:

ul
{
    display: flex;
    flex-direction: row;
}

I can position the sub menus right under the buttons of the main menu by using a combination of relative and absolute positioning:

ul li
{
    position: relative;
}

ul li ul
{
    position: absolute;
    top: 2.5em;
    left: 0;
}

Resulting in a menu with the following behaviour:


As can be seen, the trivial example application provides a usable folding menu thanks to the CSS rules that I have described.

In my example application bundled with the layout framework, I have applied all the rules shown above and combined them with the already existing CSS rules, resulting in a web application that behaves as follows:


Displaying a mobile navigation menu


As explained in the introduction, another type of dynamic menu that has been universally accepted is the mobile navigation menu (also known as a hamburger menu). Implementing such a menu, despite its popularity, is challenging IMHO.

Although there seem to be ways to implement such a menu without JavaScript (such as this example using a checkbox) the only proper way to do it IMO is still to use JavaScript. Some browsers have trouble accepting such HTML+CSS-only implementations and it requires the use of an HTML element (an input element) that is not designed for that purpose.

In my example web application, I have implemented a custom JavaScript module, that dynamically transforms a site map (that may have already been displayed as a folding menu) into a mobile navigation menu by performing the following steps:

  • We query the root link of the site map and transform it into a mobile navigation menu button by replacing the text of the root link by an icon image. Clicking on the menu button makes the navigation menu visible or invisible.
  • The first level sub menu becomes visible by adding the CSS class: navmenu_active to the unordered list.
  • The menu button becomes active by adding the CSS class: navmenu_icon_active to the image of the root link.
  • Nested menus can be unfolded or folded. The JavaScript code adds fold icons to each list item of the unordered lists that embed a nested unordered list.
  • Clicking on the fold icon makes the nested unordered list visible or invisible.
  • A nested unordered list becomes visible by adding the CSS class: navsubmenu_active to the unordered list
  • A fold button becomes active by adding the CSS class: navmenu_unfold_active to the fold icon image

It was quite a challenge to implement this JavaScript module, but it does the trick. Moreover, the basis remains a simple HTML-rendered site map that can still be used in text-oriented browsers.

The result of using this JavaScript module is the following navigation menu that has unfoldable sub menus:


Concluding remarks


In this blog post, I have explained a new feature addition to my layout framework: the SiteMapSection that can be used to render menu sections as site maps. Site maps can be used as a basis to implement dynamic menus, such as folding menus and mobile navigation menus.

The benefit of using a site map as a basis ingredient is that a web page still remains useful in its most primitive form: text. As a result, I retain two important requirements of my web framework: declarativity (because a nested unordered list describes concisely what I want) and the ability to degrade gracefully (because it stays useful when it is rendered as text).

Developing folding/navigation menus in the way I described is not something new. There are plenty of examples on the web that show how such features can be developed, such as these W3Schools dropdown menu and mobile navigation menu examples.

Compared to many existing solutions, my approach is somewhat puristic -- I do not abuse HTML elements (such as a check box), I do not rely on using helper elements (such as divs and spans) or helper CSS classes/ids. The only exception is to support dynamic features that are not part of HTML, such as "active links" and the folding/unfolding buttons of the mobile navigation menu.

Although it has become possible to use my framework to implement mobile navigation menus, I still find it sad that I have to rely on JavaScript code to do it properly.

Folding menus, despite their popularity, are nice but the basic one-level menus (that only display a collection of links/buttons of sub pages) are in my opinion fine too and much simpler -- the same implementation is usable on desktops, mobile devices and text-oriented browsers.

With folding menus, I have to test multiple resolutions and devices to check whether they provide the right user experience. Folding menus are useless on mobile devices --- you cannot separately trigger a hover event without generating a click event, making it impossible to unfold a sub menu and peek what is inside.

When it is also desired to provide an optimal mobile device experience, you also need to implement an alternative menu. This requirement makes the implementation of a web application significantly more complex.

Availability


The SiteMapSection has become a new feature of the Java, PHP and JavaScript implementations of my layout framework and can be obtained from my GitHub page.

In addition, I have added a sitemapmenu example web application that displays a site map section in multiple ways:

  • In text mode, it is just displayed as a (textual) site map
  • In graphics mode, when the screen width is 1024 pixels or greater, it displays a horizontal folding menu.
  • In graphics mode, when the screen width is smaller than 1024 pixels and JavaScript is disabled, it displays a vertical folding menu.
  • In graphics mode, when the screen width is smaller than 1024 pixels and JavaScript is enabled, it displays a mobile navigation menu.

Friday, December 30, 2022

A summary of my layout framework improvements

It has been quiet for a while on my blog. In the last couple of months, I have been improving my personal web application framework, after several years of inactivity.

The reason why I became motivated to work on it again, is because I wanted to improve the website of the musical society that I am a member of. This website is still one of the few consumers of my personal web framework.

One of the areas for improvement is the user experience on mobile devices, such as phones and tablets.

To make these improvements possible, I wanted to get rid of complex legacy functionality, such as the "One True Layout" method, that heavily relies on all kinds of interesting hacks that are no longer required in modern browsers. Instead, I wanted to use a flexbox layout that is much more suitable for implementing the layout aspects that I need.

As I have already explained in previous blog posts, my web application framework is not monolithic -- it consists of multiple components each addressing a specific concern. These components can be used and deployed independently.

The most well-explored component is the layout framework that addresses the layout concern. It generates pages from a high-level application model that defines common layout aspects of an application and the pages of which an application consists including their unique content parts.

I have created multiple implementations of this framework in three different programming languages: Java, PHP, and JavaScript.

In this blog post, I will give a summary of all the recent improvements that I made to the layout framework.

Background


As I have already explained in previous blog posts, the layout framework is very straight forward to use. As a developer, you need to specify a high-level application model and invoke a view function to render a sub page belonging to the application. The layout framework uses the path components in a URL to determine which sub page has been selected.

The following code fragment shows an application model for a trivial test web application:

use SBLayout\Model\Application;
use SBLayout\Model\Page\StaticContentPage;
use SBLayout\Model\Page\Content\Contents;
use SBLayout\Model\Section\ContentsSection;
use SBLayout\Model\Section\MenuSection;
use SBLayout\Model\Section\StaticSection;

$application = new Application(
    /* Title */
    "Simple test website",

    /* CSS stylesheets */
    array("default.css"),

    /* Sections */
    array(
        "header" => new StaticSection("header.php"),
        "menu" => new MenuSection(0),
        "contents" => new ContentsSection(true),
    ),

    /* Pages */
    new StaticContentPage("Home", new Contents("home.php"), array(
        "page1" => new StaticContentPage("Page 1", new Contents("page1.php")),
        "page2" => new StaticContentPage("Page 2", new Contents("page2.php")),
        "page3" => new StaticContentPage("Page 3", new Contents("page3.php"))
    ))
);

The above application model captures the following application layout properties:

  • The title of the web application is: "Simple test website" and displayed as part of the title of any sub page.
  • Every page references the same external CSS stylesheet file: default.css that is responsible for styling all pages.
  • Every page in the web application consists of the same kinds of sections:
    • The header element refers to a static header section whose purpose is to display a logo. This section is the same for every sub page.
    • The menu element refers to a MenuSection whose purpose is to display menu links to sub pages that can be reached from the entry page.
    • The contents element refers to a ContentsSection whose purpose is to display contents (text, images, tables, itemized lists etc.). The content is different for each selected page.
  • The application consists of a number of pages:
    • The entry page is a page called: 'Home' and can be reached by opening the root URL of the web application: http://localhost
    • The entry page refers to three sub pages: page1, page2 and page3 that can be reached from the entry page.

      The array keys refer to the path component in the URL that can be used as a selector to open the sub page. For example, http://localhost/page1 will open the page1 sub page and http://localhost/page2 will open the page2 sub page.

The currently selected page can be rendered with the following function invocation:

\SBLayout\View\HTML\displayRequestedPage($application);

By default, the above function generates a simple HTML page in which each section gets translated to an HTML div element:


The above screenshot shows what a page in the application could look like. The grey panel on top is the header that displays the logo, the blue bar is menu section (that displays links to sub pages that are reachable from the entry page), and the black area is the content section that displays the selected content.

One link in the menu section is marked as active to show the user which page in the page hierarchy (page1) has been selected.

Compound sections


Although the framework's functionality works quite well for most of my old use cases, I learned that in order to support flexbox layouts, I need to nest divs, which is something the default HTML code generator: displayRequestedPage() cannot do (as a sidenote: it is possible to create nestings by developing a custom generator).

For example, I may want to introduce another level of pages and add a submenu section to the layout, that is displayed on the left side of the screen.

To make it possible to position the menu bar on the left, I need to horizontally position the submenu and contents sections, while the remaining sections: header and menu must be vertically positioned. To make this possible with flexbox layouts, I need to nest the submenu and contents in a container div.

Since flexbox layouts have become so common nowadays, I have introduced a CompoundSection object, that acts as a generic container element.

With a CompoundSection, I can nest divs:

/* Sections */
array(
    "header" => new StaticSection("header.php"),
    "menu" => new MenuSection(0),
    "container" => new CompoundSection(array(
        "submenu" => new MenuSection(1),
        "contents" => new ContentsSection(true)
    ))
),

In the above code fragment, the container section will be rendered as a container div element containing two sub div elements: submenu and contents. I can use the nested divs structure to vertically and horizontally position the sections in the way that I described earlier.


The above screenshot shows the result of introducing a secondary page hierarchy and a submenu section (that has a red background).

By introducing a container element (through a CompoundSection) it has become possible to horizontally position the submenu next to the contents section.

Easier error handling


Another recurring issue is that most of my applications have to validate user input. When user input is incorrect, a page needs to be shown that displays an error message.

Previously, error handling and error page redirection was entirely the responsibility of the programmer -- it had to be implemented in every controller, which is quite a repetitive process.

In one of my test applications of the layout framework, I have created a page with a form that asks for the user's first and last name:


I wanted to change the example application to return an error message when any of these mandatory attributes were not provided.

To ease that burden, I have made framework's error handling mechanism more generic. Previously, the layout manager only took care of two kinds of errors: when an invalid sub page is requested, a PageNotFoundException is thrown redirecting the user to the 404 error page. When the accessibility criteria have not been met (e.g. a user is not authenticated) a PageForbiddenException is thrown directing the user to the 403 error page.

In the revised version of the layout framework, the PageNotFoundException and PageForbiddenException classes have become sub classes of the generic PageException class. This generic error class makes it possible for the error handler to redirect users to error pages for any HTTP status code.

Error pages should be added as sub pages to the entry page. The numeric keys should match the corresponding HTTP status codes:

/* Pages */
new StaticContentPage("Home", new Contents("home.php"), array(
    "400" => new HiddenStaticContentPage("Bad request", new Contents("error/400.php")),
    "403" => new HiddenStaticContentPage("Forbidden", new Contents("error/403.php")),
    "404" => new HiddenStaticContentPage("Page not found", new Contents("error/404.php"))
    ...
))
I have also introduced a BadRequestException class (that is also a sub class of PageException) that can be used for handling input validation errors.

PageExceptions can be thrown from controllers with a custom error message as a parameter. I can use the following controller implementation to check whether the first and last names were provided:

use SBLayout\Model\BadRequestException;

if($_SERVER["REQUEST_METHOD"] == "POST") // This is a POST request
{
    if(array_key_exists("firstname", $_POST) && $_POST["firstname"] != ""
        && array_key_exists("lastname", $_POST) && $_POST["lastname"] != "")
        $GLOBALS["fullname"] = $_POST["firstname"]." ".$_POST["lastname"];
    else
        throw new BadRequestException("This page requires a firstname and lastname parameter!");
}

The side effect is that if the user forgets to specify any of these mandatory attributes, he gets automatically redirected to the bad request error page:


This improved error handling mechanism significantly reduces the amount of boilerplate code that I need to write in applications that use my layout framework.

Using the iterator protocol for sub pages


As can be seen in the application model examples, some pages in the example applications have sub pages, such as the entry page.

In the layout framework, there are three kinds of pages that may provide sub pages:

  • A StaticContentPage object is a page that may refer to a fixed/static number of sub pages (as an array object).
  • A PageAlias object, that redirects the user to another sub page in the application, also offers the ability to refer users to a fixed/static number of sub pages (as an array object).
  • There is also a DynamicContentPage object in which a sub page can interpret the path component as a dynamic value. That dynamic value can, for example, be used as a parameter for a query that retrieves a record from a database.

In the old implementation of my framework, the code that renders the menu sections always has to treat these objects in a special way to render links to their available sub pages. As a result, I had to use the instanceof operator a lot, which is in a bad code smell.

I have changed the framework to use a different mechanism for stepping over sub pages: iterators or iterables (depending on the implementation language).

The generic Page class (that is the parent class of all page objects) provides a method called: subPageIterator() that returns an iterator/iterable that yields no elements. The StaticContentPage and PageAlias classes override this method to return an interator/iterable that steps over the elements in the array of sub pages.

Using iterators/iterables has a number of nice consequences -- I have eliminated two special cases and a bad code smell (the intensive use of instanceof), significantly improving the quality and readability of my code.

Another nice property is that it is also possible to override this method with a custom iterator, that for example, fetches sub page configurations from a database.

The pagemanager framework (another component in my web framework) offers a content management system giving end-users the ability to change the page structure and page contents. The configuration of the pages is stored in a database.

Although the pagemanager framework uses the layout framework for the construction of pages, it used to rely on custom code to render the menu sections.

By using the iterator protocol, it has become possible to re-use the menu section functionality from the layout framework eliminating the need for custom code. Moreover, it has also become much easier to integrate the pagemanager framework into an application because no additional configuration work is required.

I have also created a gallery application that makes it possible to expose the albums as items in the menu sections. Rendering the menu sections also used to rely on custom code, but thanks to using the iterator protocol that custom code was completely eliminated.

Flexible presentation of menu items


As I have already explained, an application layout can be divided into three kinds of sections. A StaticSection remains the same for any requested sub page, and a ContentSection is filled with content that is unique for the selected page.

In most of my use-cases, it is only required to have a single dynamic content section.

However, the framework is flexible enough to support multiple content sections as well. For example, the following screenshot shows the advanced example application (included with the web framework) in which both the header and the content sections change for each sub page:


The presentation of the third kind of section: MenuSection still used to remain pretty static -- they are rendered as div elements containing hyperlinks. The page that is currently selected is marked as active by using the active class property.

For most of my use-cases, just rendering hyperlinks suffices -- with CSS you can still present them in all kinds of interesting ways, e.g. by changing their colors, adding borders, and changing some its aspects when the user hovers with the mouse cursor over it.

In some rare cases, it may also be desired to present links to sub pages in a completely different way. For example, you may want to display an icon or add extra styling properties to an individual button.

To allow custom presentations of hyperlinks, I have added a new parameter: menuItem to the constructors of page objects. The menuItem parameter refers to a code snippet that decides how to render the link in a menu section:

new StaticContentPage("Icon", new Contents("icon.php"), "icon.php")

In the above example, the last parameter to the constructor, refers to an external file: menuitem/icon.php:

<span>
	<?php
	if($active)
	{
		?>
		<a class="active" href="<?= $url ?>">
			<img src="<?= $GLOBALS["baseURL"] ?>/image/menu/go-home.png" alt="Home icon">
			<strong><?= $subPage->title ?></strong>
		</a>
		<?php
	}
	else
	{
		?>
		<a href="<?= $url ?>">
			<img src="<?= $GLOBALS["baseURL"] ?>/image/menu/go-home.png" alt="Home icon">
			<?= $subPage->title ?>
		</a>
		<?php
	}
	?>
</span>

The above code fragment specifies how a link in the menu section should be displayed when the page is active or not active. We use the custom rendering code to display a home icon before showing the hyperlink.

In the advanced test application, I have added an example page in which every sub menu item is rendered in a custom way:


In the above screenshot, we should see two custom presented menu items in the submenu section on the left. The first has the home icon added and the second uses a custom style that deviates from the normal page style.

If no menuItem parameter was provided, the framework just renders a menu item as a normal hyperlink.

Other functionality


In addition to the new functionality explained earlier, I also made a number of nice small feature additions:


  • A function that displays bread crumbs (the route from the entry page to the currently opened page). The route is derived automatically from the requested URL and application model.
  • A function that displays a site map that shows the hierarchy of pages.
  • A function that makes it possible to embed a menu section in arbitrary sections of a page.

Conclusion


I am quite happy with the recent feature changes that I made to the layout framework. Although I have not done any web front-end development for quite some time, I had quite a bit of fun doing it.

In addition to the fact that useful new features were added, I have also simplified the codebase and improved its quality.

Availability


The Java, PHP and JavaScript implementations of my layout framework can be obtained from my GitHub page. Use them at your own risk!

Sunday, March 16, 2014

Implementing consistent layouts for websites

Recently, I have wiped the dust off an old dormant project and I have decided to put it on GitHub, since I have found some use for it again. It is a personal project I started a long time ago.

Background


I got the inspiration for this project while working on my bachelor thesis project internship at IBM in 2005. I was developing an application usage analyzer system which included a web front-end implementing their intranet layout. I observed that it was a bit tedious to get it implemented properly. Moreover, I noticed that I had to repeat the same patterns over and over again for each page.

I saw some "tricks" that other people did to cope with these issues, but I considered all of them workarounds -- they were basically a bunch of includes in combination with a bit of iteration to make it work, but looked overly complicated and had all kinds of issues.

Some time before my internship, I learned about the Model-view-controller architectural pattern and I was looking into applying this pattern to the web front-end I was developing.

After some searching on the web using the MVC and Java Enterprise Edition (which was the underlying technology used to implement the system) keywords, I stumbled upon the following JavaWorld article titled: 'Understanding JavaServer Pages Model 2 architecture'. Although the article was specifically about the Model 2 architecture, I considered the Model 1 variant -- also described in the same article -- good enough for what I needed.

I observed that every page of an intranet application looks quite similar to others. For example, they had the same kinds of sections, same style, same colors etc. The only major differences were the selected menu item in the menu section and the contents (such as text) that is being displayed.

I created a model of the intranet layout that basically encodes the structure of the menu section that is being displayed on all pages of the web application. Each item in the menu redirects the user to the same page which -- based on the selected menu option -- displays different contents and a different "active" link. To cite my bachelor's thesis (which was written in Dutch):

De menu instantie bevat dus de structuur van het menu en de JSP zorgt ervoor dat het menu in de juiste opmaak wordt weergegeven. Deze aanpak is gebaseerd is op het Model 1 [model1] architectuur:

which I could translate into something like:

Hence, the menu instance contains the structure of the menu and the JSP is responsible for properly displaying the menu structure. This approach is based on the Model 1 [model1] architecture.

(As a sidenote: The website I am referring to calls "JSP Model 1" an architecture, which I blindly adopted in my thesis. These days, MVC is not something I would call an architecture, but rather an architectural pattern!)

I was quite satisfied with my implementation of the web front-end and some of my coworkers liked the fact that I was capable of implementing the intranet layout completely on my own and to be able to create and modify pages so easily.

Creating a library


After my internship, I was not too satisfied with the web development work I did prior to it. I had developed several websites and web applications that I still maintained, but all of them were implemented in an ad-hoc way -- one web application had a specific aspect implemented in a better way than others. Moreover, I kept reimplementing similar patterns over and over again including layout elements. I also did not reuse code effectively apart from a bit of copying and pasting.

From that moment on, I wanted everything that I had to develop to have the same (and the best possible) quality and to reuse as much code as possible so that every project would benefit from it.

I started a new library project from scratch. In fact, it were two library projects for two different programming languages. Initially I started implementing a Java Servlet/JSP version, since I became familiar with it during my internships at IBM and I considered it to be good and interesting technology to use.

However, all my past projects were implemented in PHP and also most of the web applications I maintained were hosted at shared webhosting providers only supporting PHP. As a result, I also developed a PHP version which became the version that I actually used for most of the time.

I could not use any code from my internship. Apart from the fact that it was IBM's property, it was also too specific for IBM intranet layouts. Moreover, I needed something that was even more general and more flexible so that I could encode all the layouts that I had implemented myself in the past. However, I kept the idea of the Model-1 and Model-2 architectural patterns that I discovered in mind.

Moreover, I also studied some usability heuristics (provided by the Nielsen-Norman Group) which I tried to implement in the library:

  • Visibility of system status. I tried supporting this aspect, by ensuring that the selected links in the menu section were explicitly marked as such so that users always know where they are in the navigation structure.
  • The "Consistency and standards" aspect was supported by the fact that every page has the same kinds of sections with the same purposes. For example, the menu sections have the same behavior as well as the result of clicking on a link.
  • I tried support "Error prevention" by automatically hiding menu links that were not accessible.

I kept evolving and improving the libraries until early 2009. The last thing I did with it was implementing my own personal homepage, which is still up and running today.

Usage


So how can these libraries be used? First, a model has to be created which captures common layout properties and the sub pages of which the application consists. In PHP, a simple application model could be defined as follows:

<?php
$application = new Application(
    /* Title */
    "Simple test website",

    /* CSS stylesheets */
    array("default.css"),

    /* Sections */
    array(
        "header" => new StaticSection("header.inc.php"),
        "menu" => new MenuSection(0),
        "submenu" => new MenuSection(1),
        "contents" => new ContentsSection(true)
    ),

    /* Pages */
    new StaticContentPage("Home", new Contents("home.inc.php"), array(
        "page1" => new StaticContentPage("Page 1", new Contents("page1.inc.php"), array(
            "page11" => new StaticContentPage("Subpage 1.1",
                new Contents("page1/subpage11.inc.php")),
            "page12" => new StaticContentPage("Subpage 1.2",
                new Contents("page1/subpage12.inc.php")),
            "page13" => new StaticContentPage("Subpage 1.3",
                new Contents("page1/subpage13.inc.php")))),
            ...
    )))
);

The above code fragment specifies the following:

  • The title of the entire web application is: "Simple test website", which will be visible in the title bar of the browser window for every sub page.
  • Every sub page of the application uses a common stylesheet: default.css
  • Every sub page has the same kinds of sections:
    • The header section always displays the same (static) content which code resides in a separate PHP include (header.inc.php)
    • The menu section displays a menu navigation section displaying links reachable from the entry page.
    • The submenu section displays a menu navigation section displaying links reachable from the pages in the previous menu section.
    • The contents section displays the actual dynamic contents (usually text) that makes the page unique based on the link that has been selected in one of the menu sections.
  • The remainder of the code defines the sub pages of which the web application consists. Sub pages are organised in a tree-like structure. The first object is entry page, the entry page has zero or more sub pages. Each sub page may have sub pages of their own, and so on.

    Every sub page provides their own contents to be displayed in contents section that has been defined earlier. Moreover, the menu sections automatically display links to the reachable sub pages from the current page that is being displayed.

By calling the following view function, with the application model as parameter we can display any of its sub pages:
displayRequestedPage($application);
?>

The above function generates a basic HTML page. The title of the page is composed of the application's title and the selected page title. Moreover, the sections are translated to div elements having an id attribute set to their corresponding array key. Each of these divs contains the contents of the include operations. The sub page selection is done by taking the last few path components of the URL that come after the script component.

If I create a "fancy" stylesheet, a bit of basic artwork and some actual contents for each include, something like this could appear on your screen:


Although the generated HTML by displayRequestedPage() is usually sufficient, I could also implement a custom one if I want to do more advanced stuff. I decomposed most if its aspects in sub functions that can be easily invoked from a custom function that does something different.

I have also created a Java version of the same concepts, which predates the PHP version. In the Java version, the model would look like this:

package test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import io.github.svanderburg.layout.model.*;
import io.github.svanderburg.layout.model.page.*;
import io.github.svanderburg.layout.model.page.content.*;
import io.github.svanderburg.layout.model.section.*;

public class IndexServlet extends io.github.svanderburg.layout.view.IndexServlet
{
    private static final long serialVersionUID = 6641153504105482668L;

    private static final Application application = new Application(
        /* Title */
        "Test website",

        /* CSS stylesheets */
        new String[] { "default.css" },

        /* Pages */
        new StaticContentPage("Home", new Contents("home.jsp"))
            .addSubPage("page1", new StaticContentPage("Page 1", new Contents("page1.jsp"))
                .addSubPage("subpage11", new StaticContentPage("Subpage 1.1",
                    new Contents("page1/subpage11.jsp")))
                .addSubPage("subpage12", new StaticContentPage("Subpage 1.2",
                    new Contents("page1/subpage12.jsp")))
                .addSubPage("subpage13", new StaticContentPage("Subpage 1.3",
                    new Contents("page1/subpage13.jsp"))))
        ...
    )
    /* Sections */
    .addSection("header", new StaticSection("header.jsp"))
    .addSection("menu", new MenuSection(0))
    .addSection("submenu", new MenuSection(1))
    .addSection("contents", new ContentsSection(true));

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        dispatchLayoutView(application, req, resp);
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        dispatchLayoutView(application, req, resp);
    }
}

As may be observed, since Java is statically typed language, more code is needed to express the same thing. Furthermore, Java has no associative arrays in its language, so I decided to use fluent interfaces instead.

Moreover, the model is also embedded in a Java Servlet, that dispatches the requests to a JSP page (WEB-INF/index.jsp) that represents the view. This JSP page could be implemented as follows:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="io.github.svanderburg.layout.model.*"
    import="io.github.svanderburg.layout.model.page.*,test.*"%>
<%
Application app = (Application)request.getAttribute("app");
Page currentPage = (Page)request.getAttribute("currentPage");
%>
<%@ taglib uri="http://svanderburg.github.io" prefix="layout" %>
<layout:index app="<%= app %>" currentPage="<%= currentPage %>" />

The above page takes the application model and the current page (determined by the URL to call it) as requests parameters. It invokes the index taglib (instead of a function in PHP) to compose an HTML page from it. Moreover, I have also encoded sub parts of the index page as reusable taglibs.

Other features


Besides the simple usage scenario shows earlier, the libraries support a collection of other interesting features, such as:

  • Multiple content section support
  • Per-page style and script includes
  • Error pages
  • Security handling
  • Controller sections to handle GET or POST parameters. In Java, you can invoke Java Servlets to do this, making the new library technically compliant with the JSP Model-2 architectural pattern.
  • Using path components as parameters
  • Internationalised sub pages

Conclusion


In this blog post, I have described an old dormant project that I revived and released. I always had the intention to release it as free/open-source software in the past, but never actually did it until now.

These days, some people do not really consider me a "web guy". I was very active in this domain a long time ago, but I (sort of) put that interest into the background, although I am still very much involved with web application development today (in addition to software deployment techniques and several other interests).

This interesting oatmeal comic clearly illustrates one of the major reasons why I have put my web technology interests into the background. This talk about web technology from Zed Shaw has an overlap with my other major reason.

Today, I am not so interested anymore in making web sites for people or to make this library a killer feature, but I don't mind sharing code. The only thing I care about at this moment is to use it to please myself.

Availability


The Java (java-sblayout) as well as the PHP (php-sblayout) versions of the libraries can be obtained from my GitHub page and used under the terms and conditions of the Apache Software License version 2.0.

Thursday, February 28, 2013

Yet another blog post about Object Oriented Programming and JavaScript

As mentioned in my previous blog post, I'm doing some extensive JavaScript programming lately. It almost looks like I have become a religious JavaScript fanatical these days, but I can ensure you that I'm not. :-)

Moreover, I used to be a teaching assistant for TU Delft's concepts of programming languages course a few years ago. In that course, we taught several programming languages that are conceptually different from the first programming language students have to learn, which is Java. Java was mainly used to give students some basic programming knowledge and to teach them the basics of structured programming and object oriented programming with classes.

One of the programming languages covered in the 'concepts of programming languages' course was JavaScript. We wanted to show students that it's also possible to do object-oriented programming in a language without classes, but with prototypes. Prototypes can be used to simulate classes and class inheritance.

When I was still a student I had to do a similar exercise, in which I had to implement an example case with prototypes to simulate the behaviour of classes. It was an easy exercise, and the explanation that was given to me looked easy. I also did the exercise quite well.

Today, I have to embarrassingly admit that there are a few bits (a.k.a. nasty details) that I did not completely understand and it was driving me nuts. These are the bits that almost nobody tells you and are omitted in most explanations that you will find on the web or given by teachers. Because the "trick" that allows you to simulate class inheritance by means of prototypes is often already given, we don't really think about what truly happens. One day you may have to think about all the details and then you will probably run into the same frustrating moments as I did, because the way prototypes are used in JavaScript is not logical.

Furthermore, because this subject is not as trivial as people may think, there are dozens of articles and blog posts on the web, in which authors are trying the clarify the concepts. However, I have seen that a lot of these explanations are very poor, do not cover all the relevant details (and are sometimes even confusing) and implement solutions that are suboptimal. Many blog posts also copy the same "mistakes" from each other.

Therefore, I'm writing yet another blog post in which I will explain what I think about this and what I did to solve this problem. Another benefit is that this blog article is going to prevent me to keep telling others the same stuff over and over again. Moreover, considering my past career, I feel that it's my duty to do this.

Object Oriented programming


The title of this blog post contains: 'Object Oriented' (which we can abbreviate with OO). But what is OO anyway? Interestingly enough, there is no single (formal) definition of OO and not everyone shares the same view on this.

A possible (somewhat idealized) explanation is that OO programs can be considered a collection of objects that interact with each other. Objects encapsulate state (or data) and behaviour. Furthermore, they often have an analogy to objects that exist in the real world, such as a car, a desk, a person, or a shape, but this is not always the case.

For example, a person can have a first name and last name (data) and can walk and talk (behaviour). Shapes could have the following properties (state): a color, a width, height or a radius (depending on the type of shape, if they are rectangular or a circle). From these properties, we can calculate the area and the perimeter (behaviour).

When designing OO programs, we can often derive the kind of objects that we need from the nouns and the way they behave and interact from the verbs from a specification that describes what a program should do.

For example, consider the following specification:
We have four shapes. The first one is a red colored rectangle that has a width of 2 and an height of 4. The second shape is a green square having a width and height of 2. The third shape is a blue circle with a radius of 3. The fourth shape is a yellow colored circle with a radius of 4. Calculate the areas and perimeters of the shapes.

This specification may result in a design that looks as follows:



The figure above shows a UML object diagram, containing four rectangled shapes. Each of these shapes represent an object. The top section in a shape contains the name of the object, the middle section contains their properties (called attributes in UML) and state, and the bottom section contains its behaviour (called operations in UML).

To implement an OO program we can use an OO programming language, such as C++, Java, C#, JavaScript, Objective C, Smalltalk and many others, which is what most developers often do. However, it's not required to use an OO programming language to be Object Oriented. You can also keep track of the representation of the objects yourself. In C for example (which is not an OO language), you can use structs and pointers to functions to achieve roughly the same thing, although the compiler is not able to statically check whether you're doing the right thing.

Class based Object Oriented programming


In our example case, we have designed only four objects, but in larger programs we may have many circles, rectangles and squares. As we may observe from the object diagram shown earlier, our objects have much in common. We have designed multiple circles (we have two of them) and they have exactly the same attributes (a color and a radius) and behaviour. The only difference between each circle object is their state, e.g. they have a different color and radius value, but the way we calculate the area and perimeter remains the same.

From that observation, we could say that every circle object belongs to the same class. The same thing holds for the rectangles and squares. As it's very common to have multiple objects that have the same properties and behaviour, most OO programming languages require developers to define classes that capture these common properties. Objects in class based OO languages are (almost) never created directly, but by instantiation of a particular class.

For example, consider the following example implemented in the Java programming language that defines Person class (every person has a first and a last name from which a full name can be generated):

public class Person
{
    public String firstName, lastName;
    
    public Person(String firstName, String lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    public String generateFullName()
    {
        return firstName + " " + lastName;
    }
}

Basically, the above class definition consists of three blocks. The upper block defines the attributes (first and last name), the middle block defines a constructor that is used to create a person object -- Every person is supposed to have a first and a last name. The bottom block is an operation (called method in Java) that generates the person's full name from its first and last name.

By using the new operator in Java in combination with the constructor, we can create objects that are instances of a Person class, for example:
Person sander = new Person("Sander", "van der Burg");
Person john = new Person("John", "Doe");
And we can use the generateFullName() method to display the full names of the persons. The way this is done is common for all persons:

System.out.println(sander.generateFullName()); /* Sander van der Burg */
System.out.println(john.generateFullName()); /* John Doe */

Instantiating classes have a number of advantages over directly creating objects with their state and behaviour:

  • The class definition ensures that every object instance have their required properties and behaviour.
  • The class definition often serves the role as a contract. We cannot give an object a property or method that is not defined in a class. Furthermore, the constructor function forces users to provide a first and last name. As a result, we cannot create person object with no first and last name.
  • As objects are always instances of a class, we can easily determine whether an object belongs to a particular class. In Java this can be done using the instanceof operator:
    sander instanceof Person; /* true */
    sander instanceof Rectangle; /* false */
    
  • The behaviour, i.e. the methods can be shared over all object instances, as they are the same for every object. For example, we don't have to implement the function that generates the full name for every person object that we create.

Returning to our previous example with the shapes: Apart from defining classes that capture commonalities of every object instance (i.e. we could define classes for Rectangles, Squares and Circles), we can also observe that each of these shape classes have commonalities. For example, every shape (regardless of whether it's a rectangle, square or circle) has a color, and for each shape we can calculate an area and perimeter (although the way that's done differs for each type).

We can capture common properties and behaviour of classes in so called super classes, allowing us to treat all shapes the same way. By adapting the earlier design of the shapes using classes and super classes, we could end-up with a new design that will look something like this:



In the above figure a UML class diagram is shown:
  • The class diagram looks similar to the previous UML object diagram. The main difference is that the rectangled shapes are classes (not objects). Their sections still have the same meaning.
  • The arrows denote extends (or inheritance) relationships between classes. Inheriting from a super class (parent) creates a sub class (child) that extends the parent's attributes and behaviour.
  • On top, we can see the Shape class capturing common properties (color) and behaviour (calculate area and perimeter operations) of all shapes.
  • A Rectangle is a Shape extended to have a width and height. A Circle is a shape having a radius. Moreover, both use different formulas to calculate their areas and perimeters. Therefore, the calculateArea() and calculatePerimeter() operations from the Shape class are overridden. In fact: they are abstract in the Shape class (because there is no general way to do it for all shapes) enforcing us to do so.
  • The Square class is a child class of Rectangle, because we can define a squares as rectangles with equal widths and heights.

When we invoke a method of an object, first its class is consulted. If it's not provided by the class and the class has a parent class, then the parent class is consulted, then its parent's parent and so on. For example, if we run the following Java code fragment:

Square square = new Square(2);
System.out.println(square.calculateArea()); /* 4 */

The calculateArea() method call is delegated to the calculateArea() method provided by the Rectangle class (since the Square class does not provide one), which calculates the square object's area.

The instanceof() operator in Java also takes inheritance into account. For example, the following statements all yield true:

square instanceof Rectangle; /* true, Square class inherits from Rectangle */
square instanceof Shape; /* true, Square class indirectly inherits from Shape */

However the following statement yields false (since the square object is not an instance of Circle or any of its sub classes):

square instanceof Circle; /* false */

Prototype based Object Oriented programming


Apart from the length, the attractive parts described in this blog post about OO programming is that OO programs often (ideally?) draw a good analogy to what happens in the real world. Class based OO languages enable reuse and sharing. Moreover, they offer some means of enforcing that objects constructed the right way, i.e. that they have their required properties and intended behaviour.

Most books and articles explaining OO programming immediately use the term classes. This is probably due to the fact that most commonly used OO languages are class based. I have intentionally omitted the term classes for a while. Moreover, not everyone thinks that classes are needed in OO programming.

Some people don't like classes -- because they often serve as contracts, they can also be too strict sometimes. To deviate from a contract, either inheritance must be used that extends (or restricts?) a class or wrapper classes must be created around them (e.g. through the adapter design pattern). This could result in many layers of glue code, significantly complicating programs and growing them unnecessarily big, which is not uncommon for large systems implemented in Java.

There is also a different (and perhaps a much simpler) way to look at OO programming. In OO languages such as JavaScript (and Self, which greatly influenced JavaScript) there are no classes. Instead, we create objects, their properties and behaviour directly.

In JavaScript, most language constructs are significantly simpler than Java:

  • Objects are associative arrays in which each member refers to other objects.
  • Arrays are objects with numerical indexes.
  • Functions are also objects and can be assigned to variables and object members. This his how behaviour can be implemented in JavaScript. Functions also have attributes and methods. For example, toString() returns the function's implementation code and length() returns the number of parameters the function requires.

"Simpler" languages such as JavaScript have a number of benefits. It's easier to learn as fewer concepts have to be understood/remembered and easier to implement by language implementers. However, as we create objects, their state and behaviour directly, you may wonder how we can share common properties and behaviour among objects or how we can determine whether an object belongs to a particular class? There is a different mechanism to achieve such goals: delegation to prototypes.

In prototype based OO languages, such as Self and JavaScript, every object has a prototype. Prototypes are also objects (having their own prototype). The only exception in JavaScript is the null object, which prototype is a null reference. When requesting an attribute or invoking a method of an object, first the object itself is consulted. If the object does not implement it, it consults its prototype, then the prototype's prototype and so on.

Although prototype based OO languages do not provide classes, we can simulate class behaviour (including inheritance) through prototypes. For example, we can simulate the two particular person objects that are an instance of a Person class (as shown earlier) as follows:



The above figure shows an UML object diagram (not a Class diagram, since we don't have classes ;) ) in which we simulate class instantation:
  • As explained earlier in this blog post, objects belonging to a particular class have common behaviour, but their state differs. Therefore, the attributes and their state have to be defined and stored in every object instance (as can be observed from the object diagram from the fact that every person has its own first and last name property).
  • We can capture common behaviour among persons in a common object, that will serve as the prototype of every person. This object serves the equivalent role of a class. Moreover, since each person instance can refer to exactly the same prototype object, we also have sharing and reuse.
  • When we invoke a method on a person object, such as generateFullName() then the method invocation is delegated to the Person prototype object, which will give us the person's full name. This exactly offers us the same behaviour as we have in a class based OO language.

By using multiple layers of indirection through prototypes we can simulate class inheritance. For example, to define a super class of a class, we set the prototype's prototype to an object capturing the behaviour of the super class. The following UML object diagram shows how we can simulate our earlier example with shapes:



As can be observed from the picture: if we would invoke the calculateArea() method on the square object (shown at the bottom), then the invocation is delegated to the square prototype's prototype (which is an object representing the Rectangle class). That method will calculate the area of the square for us.

We can also use prototypes to determine whether a particular object is an instance of a (simulated) class. In JavaScript this is done by checking the prototype chain to see whether there is an object that has exactly the same properties as the simulated class.

Simulating classes in JavaScript


So far I think the concepts of simulating classes and class inheritance through prototypes are clear. In short, there are three things we must remember:

  • A class can be simulated by creating a singleton object capturing its behaviour (and state that is common to all object instances).
  • Instantiation of a class can be simulated by creating an object having a prototype that refers to the simulated class object and by calling the constructor that sets its state.
  • Class inheritance can be simulated by setting a simulated class object's prototype to the simulated parent class object.

The remaining thing I have to explain is how to implement our examples in JavaScript. And this is where the pain/misery starts. The main reason of my frustration comes from the fact that every object in JavaScript has a prototype, but we cannot (officially) see or touch them directly.

You may probably wonder why have I used the word 'officially'? In fact, there is a way to see or touch prototypes in Mozilla-based browsers, through the hidden __proto__ object member, but this is a non-standard feature, does not officially exist, should not be used and does not work in many other JavaScript implementations. So in practice, there is no way to access an object's prototype directly.

So how do we 'properly' work with prototypes in JavaScript? We must use the new operator, that looks very much like Java's new operator, but don't let it fool you! In Java, new is called in combination with the constructor defined in a class to create an object instance. Since we don't have classes in JavaScript, nor language constructs that allow us to define constructors, it achieves its goal in a different way:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

var sander = new Person("Sander", "van der Burg");
var john = new Person("John", "Doe");

In the above JavaScript code fragment, we define the constructor of the Person class as a (ordinary) function, that sets a person's first and last name. We have to use the new operator in combination with this function to create a person object.

What does JavaScript's new operator do? It creates an empty object, calls the constructor function that we have provided with the given parameters, and sets this to the empty object that it has just created. The result of the new invocation is an object having a first and last name property, and a prototype containing a constructor property that refers to our constructor function.

So how do we create a person object that has the Person class object as its prototype, so that we can share its behaviour and determine to which class an object belongs? In JavaScript, we can set the prototype of an object to be constructed as follows:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.generateFullName = function() {
    return this.firstName + " " + this.lastName;
};

/* Shows: Sander van der Burg */
var sander = new Person("Sander", "van der Burg");

/* Shows: John Doe */
var john = new Person("John", "Doe");

document.write(sander.generateFullName() + "<br>\n");
document.write(john.generateFullName() + "<br>\n");

To me the above code sample looks a bit weird. In the code block after the function definition, we adapt the prototype object member of the constructor function? What the heck is this and how does this work?

In fact, as I have explained earlier, functions are also objects in JavaScript and we can also assign properties to them. The prototype property is actually not the prototype of the function (as I have said: prototypes are invisible in JavaScript). In our case, it's just an ordinary object member.

However, the prototype member of an object is used by the new operator that creates objects. If we call new in combination with a function that has a prototype property, then the resulting object's real prototype refers to that prototype object. We can use this to allow an object instance's prototype to refer to a class object. Moreover, the resulting prototype always refers to the same prototype object (namely Person.prototype), that allows us to share common class properties and behaviour. Got it? :P

If you didn't get it (for which I can't blame you): The result of the new invocations in our last code fragment exactly yields the object diagram that I have shown in the previous section containing person objects that refer to a Person prototype.

Simulating class inheritance in JavaScript


Now that we "know" how to create objects that are instances of a class in JavaScript, there is even a bigger pain. How to simulate class inheritance in JavaScript? This was something that really depressed me.

As explained earlier, to create a class that has a super class, we must set the prototype of a class object to point to the super class object. However, since we cannot access or change object's prototypes directly, it's a bit annoying to do this. Let's say that we want to create an object that is an instance of a Rectangle (which inherits from Shape) and calculate its area. A solution that I have seen in quite some articles on the web is:

/* Shape constructor */
function Shape(color) {
    this.color = color;
}

/* Shape behaviour (does nothing) */
Shape.prototype.calculateArea = function() {
    return null;
};

Shape.prototype.calculatePerimeter = function() {
    return null;
};

/* Rectangle constructor */
function Rectangle(color, width, height) {
    Shape.call(this, color); /* Call the superclass constructor */
    this.width = width;
    this.height = height;
}

/* Rectangle inherits from Shape */
Rectangle.prototype = new Shape();
Rectangle.prototype.constructor = Rectangle;

/* Rectangle behaviour */
Rectangle.prototype.calculateArea = function() {
    return this.width * this.height;
};

Rectangle.prototype.calculatePerimeter = function() {
    return 2 * this.width + 2 * this.height;
};

/* Create a rectangle instance and calculate its area */
var rectangle = new Rectangle("red", 2, 4);
document.write(rectangle.calculateArea() + "<br>\n");

The "trick" to simulate class inheritance they describe is to instantiate the parent class (without any parameters), setting that object as the child class prototype object and then adding the child class' properties to it.

The above solution works in most cases, but it's not very elegant and a bit inefficient. Indeed, the resulting object has a prototype that refers to the parent's prototype, but we have a number of undesired side effects too. By running the base class' constructor we will do some obsolete work - it now assigns undefined properties to a newly created object that we don't need. Because of this, the Rectangle prototype now looks like this:



It also stores undefined class properties in the Rectangle class object, which is unnecessary. We only need an object that has a prototype referring to the parent class object, nothing more. Furthermore, a lot of people may also build checks in constructors that may throw exceptions if certain parameters are unspecified.

A better solution would be to create an empty object which prototype refers to the parent's class object, which we can extend with our child class properties. To do that we can use a dummy constructor function that just returns an empty object:

function F() {};

Then we set the prototype property of the dummy function to the Shape constructor function's prototype object member (the object representing the Shape class):

F.prototype = Shape.prototype;

Then we call the new operator in combination with F (our dummy constructor function). We'll get an empty object having the Shape class object as its prototype. We can use this object as a basis for the prototype that defines the Rectangle class:

Rectangle.prototype = new F();

Then we must fix the Rectangle class object's constructor property to point to the Rectangle constructor, because now it has been set to the parent's constructor function (due to calling the new operation previously):

Rectangle.prototype.constructor = Rectangle;

Finally, we can add our own class methods and properties to the Rectangle prototype, such as calculateArea() and calculatePerimeter(). Still got it? :P

Since the earlier procedure is so weird and complicated (I don't blame you if you don't get it :P), we can also encapsulate the weirdness in a function called inherit() that will do this for any class:

function inherit(parent, child) {
    function F() {}; 
    F.prototype = parent.prototype; 
    child.prototype = new F();
    child.prototype.constructor = child;
}
The above function takes a parent constructor function and child constructor as function parameters. It points the child constructor function's prototype property to an empty object which prototype points to the super class object. After calling this function, we can extend the subclass prototype object with class members of the child class. By using the inherit() function, we can rewrite our earlier code fragment as follows:

/* Shape constructor */
function Shape(color) {
    this.color = color;
}

/* Shape behaviour (does nothing) */
Shape.prototype.calculateArea = function() {
    return null;
};

Shape.prototype.calculatePerimeter = function() {
    return null;
};

/* Rectangle constructor */
function Rectangle(color, width, height) {
    Shape.call(this, color); /* Call the superclass constructor */
    this.width = width;
    this.height = height;
}

/* Rectangle inherits from Shape */
inherit(Shape, Rectangle);

/* Rectangle behaviour */
Rectangle.prototype.calculateArea = function() {
    return this.width * this.height;
};

Rectangle.prototype.calculatePerimeter = function() {
    return 2 * this.width + 2 * this.height;
};

/* Create a rectangle instance and calculate its area */
var rectangle = new Rectangle("red", 2, 4);
document.write(rectangle.calculateArea() + "<br>\n");

The above example is the best solution I can recommend to properly implement simulated class inheritance.

Discussion


In this lengthy blog post I have explained two ways of doing object programming: with classes and with prototypes. Both approaches makes sense to me. Each of them have advantages and disadvantages. It's up to developers to make a choice.

However, what bothers me is the way prototypes are implemented in JavaScript and how they should be used. From my explanation, you will probably conclude that it completely sucks and makes things extremely complicated. This is probably the main reason why there is so much stuff on this subject on the web.

Some people argue that classes should be added to JavaScript. For me personally, there is nothing wrong with using prototypes. The only problem is that JavaScript does not allow people to use them properly. Instead, JavaScript exposes itself as a class based OO language, while it's prototype based. The Self language (which influenced JavaScript) for instance, does not hide its true nature.

Another minor annoyance is that if you want to properly simulate class inheritance in JavaScript, the best solution is probably to steal my inherit() function described here. You can probably find dozens of similar functions in many other places on the web.

You may probably wonder why JavaScript sucks when it comes to OO programming? JavaScript was originally developed by Netscape as part of their web browser, in a rough period known as the browser wars, in which there was heavy competition between Netscape and Microsoft.

At some point Netscape bundled the Java platform with its web browser allowing developers to embed Java Applets in web pages, which are basically advanced computer programs. They also wanted to offer a light weight alternative for less technical users that had to look like Java, which had to be implemented in a short time span.

They didn't want to design and implement a new language completely from scratch. Instead, they took an existing language (probably Self) and adapted it to have curly braces and Java keywords, to make it look a bit more like Java. Although Java and JavaScript have some syntactic similarities, they are in fact fundamentally different languages. JavaScript hides its true nature, such as the fact that it's prototype based. Nowadays, its popularity has significantly increased and we use it for many other purposes in addition to the web browser.

Fortunately, the latest ECMAScript standard and recent JavaScript implementations ease the pain a little. New implementations have the Object.create() method allowing you to directly create an object with a given prototype. There is also a Object.getPrototypeOf() which gives you read-only access to a prototype of any object. However, to use these functions you need a modern browser or JavaScript runtime (which a lot of people don't have). It will probably take several years before everybody has updated their browsers to versions that support these.

References


In the beginning of this blog post, I gave a somewhat idealized explanation of Object Oriented programming. There is no uniform definition of Object-Oriented programming and its definition seems to be still in motion. On the web I found an interesting blog post written by William Cook, titled: 'A Proposal for Simplified, Modern Definitions of "Object" and "Object Oriented', which may be interesting to read.

Moreover, this is not the only blog post about programming languages concepts that I wrote. A few months ago I also wrote an unconventional blog post about (purely) functional programming languages. It's a bit unorthodox, because I draw an analogy to package management.

Finally, Self is a relatively unknown language for the majority of developers in the field. Although it started a long time ago and it's considered an ancient language, to me it looks very simple and powerful. It's a good lesson for people who want to design and implement an OO language. I could recommend everybody to have a look at the following video lecture from Stanford University about Self. Moreover, Self is still maintained and can be obtained from the Self language website.