Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ajax Patterns And Best Practices (2006)

.pdf
Скачиваний:
39
Добавлен:
17.08.2013
Размер:
15.94 Mб
Скачать

C H A P T E R 4 C A C H E C O N T R O L L E R P A T T E R N

109

The server framework manages the state completely, and the entity tag is calculated by using the hash code of the state of the objects. The hash code should never be taken based on the HTML content that is sent because that would conflict with the Permutations pattern.

A predictive cache that preloads data is based on the ability of associating a URL or its response with one or more URLs. If the predictive cache cannot logically associate URLs, a predictive cache cannot be created. Very often the logic used in the predictive cache is directly related to the operations that can be carried out on the data presented to the user. In the case of mapping, this means zooming and panning.

C H A P T E R 5

■ ■ ■

Permutations Pattern

Intent

The Permutations pattern is used by the server to separate the resource (URL) from the representation (for example, HTML or XML). Separating the resource from the representation makes it possible for an end user to focus on the resource and not have to worry about the content associated with the URL. For example, if a client’s bank account is at the URL http://mydomain. com/accounts/user, the same URL can be used regardless of device (phone, PC, and so on).

Motivation

In the early days of the Web, there were applications called price comparison services. Price comparison services compared prices between multiple online vendors. The price comparison services were made possible by using screen-scraping technologies. Essentially, screen scraping involves the deciphering of the HTML content to extract the price and product information. What made screen scraping complicated was that the generated HTML content was intended for consumption by an HTML browser. Because screen scraping was inefficient, another idea arose: to create a web service that must be explicitly called by a device other than a browser. The web service and HTML content provided two different content streams for the same content.

The web service example illustrates how the same data can have multiple representations. Extrapolating the illustration a bit further, an idea would be to consider the data as a resource that can be associated with a representation. As much as we would like to have data associated with a single representation, it is not possible because each end device has its own way of representing information. A web browser loads Dynamic HTML that results in the user being presented with images, text, and links. To get more content, a user will click on a link that will load more Dynamic HTML content in the browser. Typically, you create links in Dynamic HTML by using the HTML tag <a href="somelink" />. The a tag is a built-in mechanism used by HTML to replace the currently loaded HTML content with the content referenced by the href attribute.

111

112

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

The preceding two paragraphs discuss the problem in relatively abstract terms, and it would be better to illustrate the problem. The problem of not getting the right content can be practically illustrated by using three browsers to visit two websites. Specifically, for this example I will visit the websites http://www.google.com and http://www.yahoo.com. The three browsers used are not Mozilla Firefox, Microsoft Internet Explorer, and Apple Safari. The three browsers are indeed three completely different browser types, namely a GUI browser, a text-based browser, and a Wireless Access Protocol (WAP) browser. Each browser represents a different segment of the browsing public. The graphical browser is used by most people, text-based browsers are used by those who cannot or do not want to see the graphical HTML representations (for example, a blind or a host-terminal–based user), and the WAP browser is used by those operating cell phones. Figures 5-1, 5-2, and 5-3 show snapshots of the three browsers visiting the website http://www.google.com.

Figure 5-1. Graphical browser presentation of http://www.google.com

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

113

Figure 5-2. Textual browser presentation of http://www.google.com

Figure 5-3. WAP browser presentation of http://www.google.com

114

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

What you should notice is that the resource is the Google search engine, but the representation of each resource is different. You might be tempted to believe that there is nothing special going on because http://www.google.com is a simple website and hence the representation of the content is relatively simple. However, look closely at each of the figures and you will see that although the pages look similar, there are differences. Downloading the content from http://www.yahoo.com illustrates the different representations. Figures 5-4 and 5-5 show two of the browsers at the Yahoo! site.

Figure 5-4. Graphical browser presentation of http://www.yahoo.com

Yahoo! has a fairly complicated portal website and will present one of three formats depending on the browser making the request. This means that a user can call the URL http://www. yahoo.com and be presented with the appropriate content. This is how most people want their websites to function because users expect that kind of web experience. What users do not expect are experiences such as that illustrated in Figure 5-6.

In Figure 5-6, the user uses a nondefault browser and receives an error message and a message about launching another HTML content type.

Let’s take the example of the WAP content. Imagine needing to transfer some money into a bank account and being confronted with a message to launch another application that does not happen to exist on your cell phone. That would be frustrating and entirely unnecessary.

Maybe some websites have other URLs for the nondefault devices, but is it the responsibility of the user to figure that out? The answer is a definite no; it is the responsibility of the website to figure that out. Frankly, it would have been better for the website to just not offer the content than to have a customer grumble and panic midway through a transaction.

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

115

Figure 5-5. WAP browser presentation of http://www.yahoo.com

Figure 5-6. Incorrect web user experience when using a nondefault browser

116

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

The main idea behind the Permutations pattern is to present the right content at the right time. It is about creating content and presenting it appropriately based on the requirements of the end browsing device. By using the Permutations pattern, content is created like that of Google and Yahoo! From an end user perspective, that means users will need to remember only a single URL such as http://mydomain.com/bank/account/cgross, and then be assured regardless of device that they will be presented with similar content.

Applicability

The Permutations pattern is a core pattern that can and should be used as much as possible. However, it is a pattern that requires extra work, and that extra work should not be underestimated. For example, both Yahoo! and Google provide a similar, but different, user interface for their mobile clients. When implementing multiple user interfaces, a significant amount of work is associated with creating each one of them. Also understand that the Permutations pattern is not only user-interface related, but should be considered device related. With respect to current URLs used by current web application frameworks, the Permutations pattern may require redefinition. This means this pattern will revisit topics that seem already solved, such as session identification and authorization.

The following contexts define when the Permutations pattern should be used:

For the main entry points of a web application (such as http://mydomain.com/ application) or for a specific user (for example, http://mydomain.com/account/user). The idea is that if the end device and/or user has been identified, you don’t have to keep re-identifying what or whom the device is.

For web applications that are more Internet than intranet in nature. Controlling the end devices accessing an intranet web application is easy. In contrast, it is not possible to control the end devices accessing an Internet web application, nor should any attempt be made to control them.

Associated Patterns

The Permutations pattern is the basis of all patterns defined in this book. The Content Chunking and Persistent Communications patterns use the Permutations pattern directly, and the remaining patterns use it indirectly. The only pattern that does not explicitly use this pattern is Cache Controller.

Architecture

The big-picture architecture idea behind the Permutations pattern is to separate the resource from the representation. This means that when a URL is referenced, the data that is returned from the URL is not bound to the resource. This section explains the details of why you should separate the resource from the representation and how to do that.

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

117

Understanding Why the Resource Is Separated from the Representation

The need to separate the resource from the representation has not been adequately explained, and some developers may wonder why it is necessary at all. After all, many websites work well and nobody has complained too loudly. The reason why many websites work well is because they have probably implemented the separation of resource from representation. And those that have not done so have received complaints. Separating the resource from the representation is not complicated, but it is associated with quite a bit of grunt work. What makes matters more complicated is that many of today’s web application frameworks get it completely wrong as they bind resource with representation. It’s not that today’s web application technologies cannot manage resources and representations properly, but the fact is that they don’t do it.

To illustrate the separation of resource from representation, consider the following C# code:

interface IBase { void Method();

}

class Implementation1 : IBase { public void Method() { }

}

class Implementation2 : IBase { public void Method() { }

}

The interface IBase defines a method and is implemented by two classes, Implementation1 and Implementation2. This is called interface-driven development because when the client uses either of the implementations, the client doesn’t use the implementations but the interface of the implementations, as illustrated by the following source code:

class Factory {

public static IBase Instantiate() { return new Implementation1();

}

}

class UseIt {

public void Method() {

IBase obj = Factory.Instantiate(); // ...

}

}

118

C H A P T E R 5 P E R M U T A T I O N S P A T T E R N

In the example source code, the class Factory has a static method, Instantiate, that creates an instance of IBase by instantiating Implementation1. In the class method UseIt.Method, an instance of IBase is instantiated by calling the method Factory.Instantiate. The class UseIt has no idea whether Implementation1 or Implementation2 is instantiated. The class UseIt uses the interface as defined by IBase and expects the interface methods to be implemented correctly. Those users of dynamic programming languages such as Ruby or Python do not implement interfaces. Dynamic programming languages use contracts where functionality is implied.

Let’s relate this to URLs and separate the resource from the representation. The resource is the interface, and the representation is the implementation. Right now most web technologies bind together resource and representation or use implementations directly, as the URLs http://mydomain.com/item.aspx and http://mydomain.com/item.jsp illustrate. The direct bindings are the extensions .aspx, and .jsp, and the proper interface-defined URL would have been http://mydomain.com/item.

Ironically, all web technologies implement the separation of resource from representation for the root URL /, as illustrated by the following HTTP conversation. (Note that the conversation has been abbreviated for explanation purposes).

Request:

GET / HTTP/1.1

Host: 192.168.1.242:8100

User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O;

en-US; rv:1.7.8) Gecko/20050511

Response:

HTTP/1.1 200 OK

Server: Apache/2.0.53 (Ubuntu) PHP/4.3.10-10ubuntu4

The requested URL is /, and it is returned by the server as index.html or index.jsp or index.php or even default.aspx. If web technologies are capable of separating the resource from the representation for the root URL, why can’t they carry this throughout the entire web application? It is a truly puzzling question. The root URL implements the Permutations pattern, and many other URLs would implement the pattern, but the pattern does not need to be used everywhere, as illustrated in Figure 5-7.

The URL /account[user] has two representations, HTML and XML. Which representation is returned depends on the preference of the client. The preference of the client is determined by the Accept header. Let’s say that the client wants the HTML content. Contained within the HTML content is a link to the file details.aspx. If the URL were theoretically pure, the URL /account/[user]/details.aspx should have been /account/[user]/details. However, in some situations being theoretically pure is the wrong approach. Just as with interface-driven

development, you do not always reference interfaces. However, in the content of details.aspx, the resource-based URL /account/[user]/transactions is referenced. The resource-based URL is referenced by two representations: details.aspx and details.xml.

When implementing the Permutations pattern, what you are implementing is interfacedriven development for the Web. A resource is an interface, and the representations are implementations. The current batch of web technologies supports web application components, but their granularity is too coarse.