Chapter 1. The Tenets

As applications on the Web become larger and larger, how can web developers manage the complexity? In many ways, we need to turn to some of the same good practices used in other types of software development. Generally speaking, these practices are not yet pervasive in web development—that is, in software development primarily using HTML, CSS, JavaScript, and various server-side scripting languages (we’ll use PHP for the server-side scripting in this book, but the same principles apply to many other languages). Furthermore, the uniqueness of these technologies poses a challenge for developers trying to apply good practices in a cohesive way.

One of the themes that you’ll see repeated in this book is the importance of extending modular development practices to web development. This book presents concrete, practical techniques to achieve modularity in large web applications. In the process, we’ll explore many of the finer aspects of HTML, CSS, JavaScript, and PHP. You’ll find that most of the techniques are relatively simple to apply, and none rely on the use of specific frameworks. That said, it’s important to realize that they don’t preclude you from using various frameworks, either; to the contrary, these techniques create a better landscape in which to use many frameworks. As a case in point, we’ll look at several examples that utilize the Yahoo! User Interface (YUI) JavaScript library.

At the outset, it’s important to establish why the techniques that we’re going to explore in this book are especially useful for web developers working on large web applications. We’ll begin by looking at some of the factors that contribute to the complexity of many large web applications. Then we’ll explore how modularity plays an important role in managing this complexity. Last, we’ll examine a list of tenets that will guide our discussions throughout the rest of the book.

Managing Complexity

If you consider how different the Internet is today from just 10 years ago, it’s clear how complicated web applications have become and just how quickly the changes have taken place. Far too often, this complexity makes large web applications difficult to maintain, less reliable, and more costly over their lifetimes. Let’s examine some factors that contribute to the complexity of many large web applications. Typically, large web applications have the following characteristics:

Continuous availability

Most large web applications must be running 24/7. In addition, response times have to be fast at any moment, even at peak load times. Web developers need to write code that is especially robust.

Large user base

Large web applications usually have large numbers of users. This necessitates management of a large number of simultaneous connections or layers of caching. Web developers often need to write code to manage these situations.

Piece-by-piece delivery

Whereas many types of software are distributed as complete units, web applications have many parts delivered page by page, or connection by connection via Ajax. As a result, large web applications operate within an environment effectively shared by a huge number of users.

Diversity

It’s hard to think of a business or service that doesn’t have at least some sort of web interface. For example, we see financial applications, ticketing sites, applications that organize massive amounts of data (e.g., search engines), media systems (e.g., news sites), and the list goes on. Web developers need to write code that may be reused in unexpected places.

Longevity

The largest web applications today, even those that have been around many years, are just at the beginning of their lifetimes. Web developers need to write code under the assumption that it will have to stand up to years of changes and maintenance.

Multiple environments

The Web is a fast-changing landscape littered with old browsers and other devices that can be difficult to support. Users access large web applications from all types of environments and with screens of wildly different sizes (including mobile devices). Web developers must write code that can handle the numerous idiosyncrasies that result from this.

Real-time updates

Large web applications are not static; they are constantly fluctuating applications for which changes are typically pushed to servers regularly. Web developers need to write code to address this potential for moving parts.

Over time, web developers often end up addressing complexity in large web applications via one-off fixes and tweaks as their applications reach various breaking points. But there is a better way. This book will show you how to address challenges like the ones above head-on from the start. Mitigating the complexity from these challenges can often be attributed to one or more byproducts of modularity that we’ll examine in a moment. For example, I stated above that large web applications need to be available all the time. From the perspective of the web developer, this is an issue of reliability, which modularity plays a key role in addressing.

Modular Components

In a large web application, to address complexity with modular components, or modules, you need to encapsulate everything the component needs within small, well-defined pieces of the application. This allows you to divide a large application into more manageable pieces that you can build with a specific focus and reuse wherever needed. In addition, you hide (or abstract) the implementation details of each module and take steps to ensure each module can operate more or less independently of the others. Even relatively small web applications can benefit from such modularity. After all, the small web applications of today are the Googles, Yahoo!s, and Amazons of tomorrow. Building web applications in a modular way at the start provides a solid foundation for future growth.

Modularity seems like a simple thing, but it can be deceptively difficult to attain in a cohesive manner across the HTML, CSS, JavaScript, and server-side scripts that web developers write for large web applications. Let’s look more closely at the concept of modularity and some basic ideas to help you achieve it.

Achieving Modularity

You achieve modularity in large web applications, as in other types of software, through encapsulation, abstraction, and maintaining as much of a loose coupling as possible among an application’s modules.

Encapsulation

Encapsulation is the process of bundling everything that a module requires within a single, cohesive unit. Modules for web applications need to encapsulate all the HTML, CSS, JavaScript, and PHP that they require. Chapter 7 shows how to accomplish this using object-oriented PHP. We’ll also have to employ techniques in the HTML, CSS, and JavaScript itself for a module to support this. These techniques are presented in Chapters 3, 4, and 5, respectively.

Abstraction

Abstraction is the process of hiding details that should not be observable when working with a module from outside its implementation. Defining a good interface is the key to abstraction. Web applications present special challenges because HTML is not built for hiding information in the manner that many languages enforce and because CSS cuts across module boundaries, or cascades, and must therefore be managed rigorously. Chapter 7 shows how object-oriented PHP can be used to define interfaces that abstract the details of working with sections of HTML and CSS. Data managers, presented in Chapter 6, are good examples of interfaces that abstract working with dynamic data managed by the backend.

Loose coupling

A loose coupling between modules means that one depends on the other as little as possible and only in clearly defined ways. In Chapter 2, you’ll see that it’s relatively easy to create a dependency graph that depicts the dependencies among objects in an object-oriented system. When object orientation is used to implement modules in a large web application, it’s easier to notice how changes to one part of a system may affect another. The techniques presented for modular HTML and CSS in Chapters 3 and 4 also promote loose coupling.

Benefits of Modularity

Once you create modules that take advantage of encapsulation, abstraction, and loose coupling, you’ll have better reusability, maintainability, and reliability across your entire web application. When a module is reusable, it’s clear how to make it operate and do new things. You can move it from place to place in the application with the confidence that everything it needs to work properly will come with it, and that you won’t experience unexpected consequences when you reuse the module. When a module is maintainable, it’s clear which area of the application you need to change to affect certain features and how to make the changes. Modules that are easy to maintain are more reliable because they reduce the risk of side effects when changes take place.

Ten Tenets for Large Web Applications

With an eye toward modularity, we’ll use the list of tenets in this section to guide our discussions in the chapters that follow. A tenet is a principle or belief that we will accept as true—that is, it’s an assertion. A quick read-through of this list will provide you with a high-level understanding of where we’ll be heading. Later, you may find this list to be a concise reminder of the concepts we’ve discussed. Each tenet is examined in the chapter with the corresponding number. For instance, Tenet 4 describes the robust use of CSS, and Chapter 4 shows how to apply this tenet when implementing your CSS.

Tenet 1

Large web applications are built from modular components that are highly reusable, maintainable, and reliable.

Tenet 2

The use of object orientation in JavaScript and server-side scripting languages improves reusability, maintainability, and reliability in large web applications by promoting modularity.

Tenet 3

Large-scale HTML is semantic, devoid of presentation elements other than those inherent in the information architecture, and pluggable into a wide variety of contexts in the form of easily identifiable sections.

Tenet 4

Large-scale CSS forms a layer of presentation that is separate from the information architecture, applied in a modular fashion, and free of side effects as we reuse modules in various contexts.

Tenet 5

Large-scale JavaScript forms a layer of behavior applied in a modular and object-oriented fashion that prevents side effects as we reuse modules in various contexts.

Tenet 6

Dynamic data exchanged between the user interface and the backend is managed through a clearly defined data interface. Pages define a single point for loading data and a single point for saving it.

Tenet 7

Pages are constructed from highly reusable modules that encapsulate everything required (e.g., HTML, CSS, JavaScript, and anything else) to make each module an independently functioning and cohesive unit that can be used in a variety of contexts across various pages.

Tenet 8

Large-scale Ajax is portable and modular, and it maintains a clear separation between data changes and updates to a presentation. Data exchange between the browser and server is managed through a clearly defined interface.

Tenet 9

Large-scale HTML, JavaScript, CSS, and PHP provide a good foundation on which to build large web applications that perform well. They also facilitate a good environment for capturing site metrics and testing.

Tenet 10

The organization of files on the server for a large web application reflects the architecture of the application itself, including clearly demarcated scopes in which each file will be used.

Get Developing Large Web Applications now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.