Simulation Service - Ajax Patterns

Simulation Service

From Ajax Patterns

(Difference between revisions)
Revision as of 03:31, 20 November 2005
Mahemoff (Talk | contribs)
Solution
← Previous diff
Current revision
Mahemoff (Talk | contribs)
Want to Know More?
Line 49: Line 49:
= Decisions = = Decisions =
-= How will you switch between different services? =+== How will you switch between different services? ==
It's easy enough to create a [[Simulation Service]], but how do you switch between the simulation and the real thing? And, how do you switch between different simulation services, since you might prefer one or the other for different tasks. Right now, there's no easy answer to that because there's no real support in the way of tools and libraries. Where the practice of [[Simulation Service]] is followed, most developers probably switch over to a real service in the most brute-force way possible: edit the code. But doing so means there's a manual step involved in order to test or deploy. Here are a few ways to make the process more manageable: It's easy enough to create a [[Simulation Service]], but how do you switch between the simulation and the real thing? And, how do you switch between different simulation services, since you might prefer one or the other for different tasks. Right now, there's no easy answer to that because there's no real support in the way of tools and libraries. Where the practice of [[Simulation Service]] is followed, most developers probably switch over to a real service in the most brute-force way possible: edit the code. But doing so means there's a manual step involved in order to test or deploy. Here are a few ways to make the process more manageable:
* Keep the Javascript pointing at the same service URL, but have your server-side build tool (e.g. ant) decide what implementation resides there. * Keep the Javascript pointing at the same service URL, but have your server-side build tool (e.g. ant) decide what implementation resides there.
* Build some configuration into the Javascript to help it point to the correct service. This would be useful for an automated Javascript-based test. You could even create a simple browser control to let the user choose which service is executed, helpful during development. * Build some configuration into the Javascript to help it point to the correct service. This would be useful for an automated Javascript-based test. You could even create a simple browser control to let the user choose which service is executed, helpful during development.
-* Instead of hosting Javascript in a static file, dynamically generate it from the server, so that critical URLs can be +* Instead of hosting Javascript in a static file, dynamically generate it from the server, so that critical URLs can be set on the fly.
<!-- =================================================================== --> <!-- =================================================================== -->
Line 60: Line 60:
= Refactoring Illustration = = Refactoring Illustration =
-The [http://ajaxify.com/run/reader/ Ajax Pattern Reader] is designed to run against a couple of [[Cross-Domain Mediators]] services. They fetch information from the AjaxPatterns.org website and returning them in a format easily parsed by the browser. For development purposes, [http://ajaxify.com/run/reader/ the Basic version] uses [[Simulation Service]]s.+The [http://ajaxify.com/run/reader/ Ajax Pattern Reader] is designed to run against a couple of [[Cross-Domain Proxy]] services. They fetch information from the AjaxPatterns.org website and returning them in a format easily parsed by the browser. For development purposes, [http://ajaxify.com/run/reader/ the Basic version] uses [[Simulation Service]]s.
The first service produces a [[Semantic Response]] containing the patterns in a pipe-separated list. [http://www.ajaxify.com/run/reader/patternList.phtml A hand-created simulation] is used instead of fetching the page from ajaxpatterns.org, parsing the HTML, and reformatting it. The first service produces a [[Semantic Response]] containing the patterns in a pipe-separated list. [http://www.ajaxify.com/run/reader/patternList.phtml A hand-created simulation] is used instead of fetching the page from ajaxpatterns.org, parsing the HTML, and reformatting it.
Line 98: Line 98:
= Related Patterns = = Related Patterns =
-== [[Service Unit Test]] ==+== [[Service Test]] ==
A [[Simulation Service]] is a good starting point for a real service. You might begin developing a [[Service Test]] against a [[Simulation Service]], then refactor evolve both into a real service and test. A [[Simulation Service]] is a good starting point for a real service. You might begin developing a [[Service Test]] against a [[Simulation Service]], then refactor evolve both into a real service and test.
<!-- =================================================================== --> <!-- =================================================================== -->
- 
-= Want to Know More? = 
- 
-* [http://abc.truemesh.com/archives/000093.html Lean IT Processes] This pattern facilitates a "Pull System", where design is driven by customer demands rather than technical capability. 

Current revision

Evidence: 0/3

Tags: Canned Dummy Fake Masquerade Mock Service Shunt Sim Simulation Stub


Contents

Goal Story

Dave is beginning to work on a new email application. Eventually, the server will need to expose a mail API, so the browser can query for recent messages and upload new ones. However, that will require email expertise, and Dave wants to focus on the user-interface in the browser for now. Thus, he hard-codes the responses he'd like in "fake" server-side service. This allows him to proceed with user-interface development while someone else takes care of the real server implementation.


Problem

How can you develop the browser script in parallel with the services it uses?


Solution

Develop the browser application against "fake" web services that simulate the actual services used in production. A Simulation Services is typically a hard-coded response that ignores any input parameters. So instead of:

 $taxRate = calculateTaxRate($userId, $year);
 print $taxRate;

a simulation service would just say:

 print "0.1235";

It's also possible to do all this in a browser. If you use a library to perform Web Remoting, you could make the implementation produce a hard-coded response, and ignore the server altogether.

In some cases, you might make the service more flexible, e.g. it can expose an operation to let the browser tell it what to output later on.

Simulation Service decouples the server and browser components of the application. Once the interface is defined, each can be developed in parallel. Moreover, this pattern paves the way for an agile process for building the application, based loosely on concepts such as Test-Driven Design (TDD) and lean manufacturing.

A Simulation Service is a kind of "stub". In software testing, simple stubs are created to provide isolated tests. Instead of working with real components, the tested component works with simple stubs. Because the stubs are simple and stable, any test failures can then be attributed to the tested component. Furthermore, stubs will always yield the same result, so it's easier to automate the test.

It's important to distinguish between "Mocks" and Stubs, because the terms are often used interchangeably. Like a Stub, a "Mock" simulates a real component. But for a Mock, the simulation is only a bi-product of its true purpose: to verify that it's used correctly. Before a test, the Mock is told what calls the component will make on it. As soon as that sequence is violated, the Mock will complain and the test will fail. There are several potential applications for Mocks in Ajax, and one of those involves Mock Services. The browser could start a test by telling a Mock XMLHttpRequest wrapper what calls will soon be made. Then, the wrapper will throw an exception if that call isn't actually made. "Mock Service" is too immature a concept to form a pattern at this stage, but it's something that might emerge as Ajax developers focus on testing techniques.

Conventional web development is usually a bottom-up approach: first comes the database, then the data layer to access it, then the business components on top of that, and finally the user-interface. This sequence might seem like the most logical thing to do, given the dependency relationships involved. But the problem is that the user-interface is really the whole point of the application, so there's a good argument for starting there. For a given feature, flesh out the user-interface, and use that work to drive the service interface. So instead of making the browser script work with whatever interface the server happens to offer it, let the browser script dictate the interface. Consequently, the service will not only contain the precise functionality required by the browser, but also expose it with the most suitable interface.

Starting development in the browser sounds like a good idea until you realise the browser depends on the service, which doesn't yet exist! That's where a Simulation Service comes in: it lets you define what the service offers, not how it achieves that. As you develop the browser script, you'll continue to come across refinements to the service - an extra operation here, a different response format there. In each case, changing the Simulation Service is usually as simple as editing the hard-coded response. Once you're confident with the requirements for the Service, you - or someone else - can go build the real thing.

Another application is in Browser-Side Tests. When testing a browser component, it's important to test only the unit, and not the things it depends on. Imagine you're testing a browser component that renders news arriving from an RSS web service. An automated test should then interrogate the DOM and run a bunch of assertions to ensure it was formatted correctly. But if the component uses the real service, the resulting DOM will reflect the news of the hour. A human could manually verify it, but automation isn't possible. A hard-coded response would eliminate that problem, allowing the assertions to be consistent with the simulated RSS. Furthermore, there's no dependence on the real implementation - no matter how complex the actual search algorithm, the rendering component will always be tested on its own merit.


Decisions

How will you switch between different services?

It's easy enough to create a Simulation Service, but how do you switch between the simulation and the real thing? And, how do you switch between different simulation services, since you might prefer one or the other for different tasks. Right now, there's no easy answer to that because there's no real support in the way of tools and libraries. Where the practice of Simulation Service is followed, most developers probably switch over to a real service in the most brute-force way possible: edit the code. But doing so means there's a manual step involved in order to test or deploy. Here are a few ways to make the process more manageable:

  • Keep the Javascript pointing at the same service URL, but have your server-side build tool (e.g. ant) decide what implementation resides there.
  • Build some configuration into the Javascript to help it point to the correct service. This would be useful for an automated Javascript-based test. You could even create a simple browser control to let the user choose which service is executed, helpful during development.
  • Instead of hosting Javascript in a static file, dynamically generate it from the server, so that critical URLs can be set on the fly.


Refactoring Illustration

The Ajax Pattern Reader is designed to run against a couple of Cross-Domain Proxy services. They fetch information from the AjaxPatterns.org website and returning them in a format easily parsed by the browser. For development purposes, the Basic version uses Simulation Services.

The first service produces a Semantic Response containing the patterns in a pipe-separated list. A hand-created simulation is used instead of fetching the page from ajaxpatterns.org, parsing the HTML, and reformatting it.

 Periodic Refresh|||One-Second Spotlight|||Slider

For comparison, the real service outputs a list looks similar, but is much longer, and, of course, not hard-coded.

 Ajax Stub|||Browser-Side Cache|||Browser-Side Templating||| ... |||XML Message|||XMLHttpRequest Call

Similarly, there's a simulation of the summary service, whose job is to produce an HTML Response summarising a given pattern. The simulation includes some rudimentary logic to make the response vary according to the input:

  <?  $patternName = urlDecode($_GET["patternName"]); ?>
 
    <h1><?= $patternName ?></h1>
 
  <?  if ($patternName=="Periodic Refresh") { ?>
 
      With periodic refresh, it's all about the timer.
 
  <?  } else if ($patternName=="Slider") { ?>
 
     <p>The slider slides from left to right.</p>
     ...
  <?  } else {
      print ("Text goes here.");
    }
 
  ?>

The output from the real service is in the same format, but as with the list service, it's fetched from AjaxPatterns real-time.


Related Patterns

Service Test

A Simulation Service is a good starting point for a real service. You might begin developing a Service Test against a Simulation Service, then refactor evolve both into a real service and test.