Summary
[ Content Index | Design ]
This document describes a few forward-thinking observations: the advantage to separating scripted features from content, a principle of auto-discovery in client-side scripts (Intelligent Abstraction), and an introduction to one method of DHTML development.
Content Type: Design
Content Created: July 2003
This work is licensed under a Creative Commons License.
Index
Modification History
| Author | Date | Description |
| Stephen W. Cote | 12/22/2003 | Continued Revisions. |
| Stephen W. Cote | 07/14/2003 | Revised content. Based on feedback, my vision of an edgy, racy, dark, sexy article didn't quite pan out. |
| Stephen W. Cote | 07/08/2003 | Revised content to remove from-the-hip remarks. |
| Stephen W. Cote | 07/07/2003 | Document Created. |
Introduction
From UI Toolkit to Framework
This document purports to describe the separation of functionality from form; code from content.
To put this into the proper context, the following is a summary of why a GUI toolkit became a framework for helping achieve this separation.
Almost a year ago, I wrote the design notes for what would develop into the Engine for Web Applications project.
The design was based on my experience developing the Multi-Document Interface Script API(MDI) and the MDI redesign, the M3 project.
Until the Summer of 2002, I had been working on one version or another of the MDI Project since December 1998.
Screenshots
Somehow equivalent to a box of vacation slides, here are various screenshots taken from the last five years documenting the progression of projects from a UI toolkit to a client-side framework.
- MDI Behavior (Version 1):
- MDI Version 2 Alpha:
- MDI Version 2 Beta:
- MDI Version 2:
- Engine for Web Applications:
On Shelving the UI Toolkit
Between the last MDI Version 2 Beta screenshot and the MDI Version 2 screenshots, as well as the Engine MDI Beta screenshots, the abilities of the MDI toolkit should be clear.
Nonetheless, here is a quick summary:
- Skinnable - One method invocation could switch the skins for all components.
- Easy To Use - The API was pretty easy to use
- Good Performance - Decent UI performance for a DHTML-based GUI toolkit.
- Decent Look-and-Feel - There are a number of UI toolkits available that look much better, but these skins were pretty good.
- OK Component Containment - Components were extended by layout and style managers, making it very easy for the developer to define complex layouts.
Ultimately, the MDI toolkit was shelved for the following reasons:
- It did not support downlevel browsers like the DHTMLCentral Windows, and it did not have the extensible plumbing like netWindows. I felt the MDI toolkit had many of its own advantages, but internally was too discombobulated.
- Designing a complex UI toolkit without a solid architecture results in a kludgy implementation. The end result of the MDI toolkit was nice on the surface and in functionality, but the manner in which it was architected was not.
- Work on the MDI Version 3 (M3) project resulted in a design document that highlighted a core architecture that went far beyond a UI toolkit, with many benefits for developing Web-based applications.
- ASP.NET. While I do like most aspects of .NET, I do not care for the ASP.NET Web Forms implementation; specifically, how Web pages are tied to server side components. This relates to the MDI toolkit because the goal of the MDI toolkit was to reduce the need to reload the Web page, and ASP.NET went in the other direction. It seemed to me that what was lacking was a solid client-side framework, beyond an XML RPC or Web Services library, to make the ASP.NET Web Forms implementation more dynamic. While I have yet to specifically address ASP.NET with my project, it was one of the key developments that lead to the change in strategy.
If the MDI Project was shelved due to architectural problems, why was it not rewritten based on the new design?
At first, that was the idea (refer: both Engine MDI Beta screenshots).
However, tacking the UI toolkit back onto the new framework skewed the objective of the redesign: to create an application interface architecture for the browser client, including a core set of services and utilities.
While developing these various projects, my view of Web Development had changed and from that change came the maxim that functionality should be separated from content.
On Separating Functionality From Content
The fundamental clause in the separation of structure from content is that data should not be the style.
To wit, Web pages that lay out content in massively embedded tables and liberally use the HTML FONT element or repeat use of the style attribute have not separated structure from content.
The separation of structure from content argument can be both heated and overrated.
The claims for keeping the content and structure segregated are very valid.
However, such separation may occur at the client, or earlier in the content delivery process.
Therefore, observing the aforementioned classic examples of merging structure with content does not necessarily imply that the two were not once separated.
For example, if the content is based on a standardized XML schema, at least across an organization, then the end result of the transformation may seem messy and littered with embedded style, where those elements were not a part of the original content.
When client-side script is added to the mix, another paradigm is created: a union of functionality and content.
This precludes a need to separate the scripted functionality from the content.
Web pages that include script, and where that script directly affects specific HTML elements, have fused functionality with content.
By separating scripted functionality from content, the content remains pure and may be representative of some type of data or a user interface element without being statically bound to a particular action.
When the functionality is abstracted from the content, the functionality may then be tasked to specific duties and intermix with actual content as needed.
Such separation implies a means of connectivity and association of functionality with content.
This type of association may exist with something like DHTML Behaviors.
It is also addressed by the Engine for Web Applications project.
[ top ]
Part 1: DHTML Today
DHTML could be described as being a collection of HTML element objects, CSS style, script, and DOM members.
It is dynamic because the browser exposes the HTML elements as objects and CSS styles to the script interpreter through a DOM, and along with application and interface events, provides developers with an environment to easily alter the original content and style.
Incredible implementations DHTML are possible.
Consider the XUL interface for Mozilla, which is a sort of DHTML.
Or, those clever DHTML MDI Window toolkits, menus, and portals.
Part 1.1: DHTML Yesterday
Trouble starts when content is dynamically appended to the original content, or changed in the original content.
Not every Web browser supports DHTML,and those that do support DHTML may not follow the same specification.
Many DHTML libraries have been written to mask the disparity between implementations.
In consideration of Web browsers that support the W3C DOM specification, where the DOM could be described as binding the collective elements of DHTML together, the necessity of supporting the older and partisan APIs is brought into question.
In certain light, the older APIs might seem backwards and arcane.
Supporting older APIs might not be in everyone's best interest in the long term, though the older APIs may still be used based on the misconception that they are still required to support an ever shrinking percentage of browser clients.
With new features being designed for the later and more commonly used browsers, designing those features to support older APIs would seem as though the features were crowbarred into an otherwise streamlined implementation.
A time will come when it will be necessary to judiciously approve requests to support the older APIs; Netscape 4.x and Internet Explorer 4.x to be specific.
While certain aspects of the older APIs were common and are now included in the DOM specification, the remainder shall go the way of the dinosaurs.
At least, they probably should.
Part 1.2: Contemporary DHTML
This article will eventually lead to suggestions about how the structure of DHTML development might change in the future.
To that end, it is not the intent of this article to overly discourage contemporary implementations of DHTML.
Instead, the goal is to suggest how those implementations might be streamlined at some time in the future.
A question to ponder: if the best content is gold, what are the odds that the best content will be the result of the programmatic equivalent of a Philosopher's stone?
If the origins of content reside within some functionality (eg: script) - as opposed to being imported via functionality (eg: frames, frame buffers, XML) - then that content is statically bound to the functionality.
Situations like this are less common, but can be found in the Wild Wild Web.
Most software developers would frown upon including static content in code because it then makes the component or product more difficult to maintain, and depending on the situation, less scalable.
The Web presents an interesting situation because the content, the structure, the style, and the functionality can be quite fluid.
At some point in a DHTML-ready Web page, scripted functionality is bound to the content.
The following are a few examples:
<!-- Example #1 -->
<script type = "text/javascript">
document.body.innerHTML += "<p>new paragraph</p>";
</script>
<!-- Example #2 -->
<script type = "text/javascript">
var oP = document.createElement("p");
var oLabel = document.createTextNode("new paragraph");
oP.appendChild(oLabel);
document.body.appendChild(oP);
</script>
<!-- Example #3 -->
<input type = "button" value = "Act" onclick = "someFunction()" />
<!-- Example #4 -->
<input type = "button" id = "oButton" value = "Act 2" />
<script type = "text/javascript">
document.getElementById("oButton").onclick = someFunction;
</script>
- The first example represents content statically declared in script. This also shows one use, or misuse, of the popular innerHTML property.
- The second example reprentsts content nodes created with the W3C DOM APIs that is statically declared in script. The second example is a variation on the first example.
- The third example demonstrates how a script function is bound-inline with HTML element for an event handler.
- The fourth example demonstrates how a script function is statically bound to an HTML element through script and a DOM property representing the event.
On a Web page, it is often undesirable to include static content in code because, as mentioned previously, this makes both the content and the script harder to maintain.
What then might be concluded from the inverse case where code is statically bound to content?
It has to happen in some fashion, and today, the latter case is the preferable one.
Part 1.3: DHTML Tomorrow
Today, there are few compelling reasons to change how DHTML is developed, apart from designing a new architecture or adding support for an existing standard.
In the context of this article, one reason could be to remove the static bindings between functionality and content.
But is there a compelling argument to do so?
If there is such an argument, how might it be accomplished?
Two product-specific approaches to separating functionality from content are the XML User interface Lanuage and DHTML Behaviors.
XUL shows a lot of promise and has been in development since as early as 1999.
Also, XUL was not necessarily designed for use in the context of a Web page.
DHTML Behaviors offer the most immediate implementation, although are specific to Internet Explorer like XUL is to Mozilla.
Without a cross platform and generic drop-in method to form the associations between content and functionality, developers have no reason or real alternative to change.
Intermediate approaches for making these associations do exist, such as using a template language like XSL, but are then no longer drop-in and form expectations about the source of the content.
The only approach that makes sense would be for the content to be associated with the functionality without the developer having to statically declare the association.
Today, DHTML Behaviors are the only way to do this, but then only for Internet Explorer.
In terms of creating this association, consider the following HTML element and JavaScript function.
<!-- Example #5 -->
<input type = "button" value = "Action" />
<!-- nothing connects the function to the element -->
<script type = "text/javascript">
function doActionClick(){
doLibraryFunction();
}
</script>
The goal of making the association between the HTML INPUT element and the doActionClick function is to achieve the equivalent of examples #3 and #4 in the previous example section.
The purported advantage is that core code and script libraries may be distanced from the Web page content, leaving the event handlers and functions that represent non-core features to be associated with the content.
By shifting the burden of connectivity to the handlers and the non-core functions developers would have a more scalable and maintainable architecture.
However, this type of architecture would only seem beneficial if the expected association was made automatically.
If there is no architecture describing a drop-in solution, product-specific technologies aside, then there can't really be a compelling argument to change.
If there was an architecture for a drop-in solution, though, perhaps the argument would be compelling.
[ top ]
Part 2: Web Pages of the Future
If content and functionality could be separated with a drop-in solution, or one that operated without any intervention by the developer or closed API to learn, Web pages might be designed differently.
In the Web page of this possible future, the content and functionality would be separated, third-party libraries that interact with the content could be abstracted, and the general approach to authoring script would change.
This may seem like a forbidding place, but the conventional wisdom of the future would be that developers won't have to untangle all the various widgets and toolkits that make their Web application complete.
Part 2.1 : Feature Compartmentalization
Assume for the time being that if content is not statically bound to functionality then some process will come by later to automatically make the association.
If that assumption can be made, then the manner in which other objects and functions are referenced might change.
Every function, non-HTML object, and global variable would be given some form of scope.
While this practice is quite practical and is becoming more common, there is less reason to move declarations out of the global scope when the bindings between the content and functionality tend to remain in the global scope.
This only speaks towards the manner in which a Web page was originally developed, and it is certainly not universal.
However, if the association between content and functionality are not present at the start, then it is easier for the functionality of specific bindings to be compartmentalized.
For example, one approach to creating a few variables, scoped within a literal object, follows.
/* Example 6 */
var mystuff = {
variable_1:"value",
variable_2:"value",
myfunction:function(){
}
};
An example of creating an object constructor, which may also define some variables within an instance of that object, follows.
/* Example 7 */
function MyStuffImpl(){
this.variable_1 = "value";
this.variable_2 = "value";
this.myfunction = function(){
};
}
var mystuff = new MyStuffImpl();
With the assumption that the binding between content and functionality will be filled in later, most static event handler declarations could then be removed (as in the Part 1.3 example).
If a Web page is to be available to as many browsers as possible, the most common and supported features should be readily available, and be ready to go.
Afterwards, additional functionality and features could then be added based on the abilities of the client browser.
The purpose of making such a separation is to distance the base content and core functionality from the additional features.
At the absolute minimum, the Web page remains accessible to everyone.
The difference between this approach and tacking features onto the page at the time it is dermined the browser may support those features is that the leg-work involved in the instrumentation would be handled by the drop-in association widget.
Or, put plainly, developers do not need to learn how the associations are made, but instead may continue development as they normally would.
Consider the following example:
<!-- Example #8 -->
<!-- Static Inline Event Declaration -->
<input
type = "button"
id = "oButton"
value = "Action"
onclick = "mystuff.button_click()"
/>
<script type = "text/javascript">
function MyStuffImpl(){
this.button_click = function(){
};
}
var mystuff = new MyStuffImpl();
/* Static Scripted Event Binding via an event property wrapper */
document.getElementById("oButton").onclick =
function(){
mystuff.button_click();
}
;
/* Statically scripted binding via event property */
document.getElementById("oButton").onclick = mystuff.button_click;
/* Statically scripted binding via DOM */
document.getElementById("oButton")
.[attachEvent | addEventListener]("click",mystuff.button_click)
;
</script>
In order to bind the click event for "oButton" to the "button_click" function for an instance of MyStuffImpl:
- a static inline declaration such as onclick="mystuff.button_click()" may be used,
- or a node reference to "oButton" could be obtained and the onclick event property set to the mystuff.button_click function pointer,
- or a wrapper function could be added to the onclick event property and in turn invoke the mystuff.button_click function.
- or the addEventListener or attachEvent methods may be used to bind the button_click method to button instance.
Note: In each of the above examples except #3, the button_click method inherits scoped variables but is evaluated globally, those changing the value of this so that it may not be used to refer back to the object.
One approach to compartmentalizing the content and script is to first contain the script, and second to apply that containment to the button node.
Consider the following representation:
<!-- Example #9 -->
<html-component>
<input
type = "button"
value = "Action"
/>
</html-component>
<script-component>
function handle_click(){
}
</script-component>
The above representation identifies two types of components: a typical HTML form button, and a JavaScript function handle_click.
If the JavaScript function naming convention identifies an event handler for the click event, then a method of applying that script component to the html component could deduce that an onclick handler need be applied to the html component.
Also, if the script component is integrate into some other form of component container, then the simple function declaration might then inherit a number of helpful accessor interfaces.
By compartmentalizing the script, and then applying it back to the HTML node, the script might inherit some of the following features:
- Access to the source element.
- Protected scope.
- Access to the source element 'container' (eg: the application 'body'; not the parent node).
- Access to the compartmentalization component which equates to access to the features of the protected scope.
Part 2.2: Toolkit Compartmentalization
Third-party widgets and libraries serve an important role in Web page development by encapsulating otherwise unavailable features.
In many cases, incorporating widgets into a Web page or Web application requires instrumentation in the content.
Typically the learning curve grows steeper as a widget or toolkit becomes more complex.
Also, complex widget and toolkit instrumentation often times require an all-or-none implementation; one page with the instrumentation, and one page without.
Many toolkits are already compartmentalized to some degree, leaving the instrumentation issue open, and there isn't a nice way to get around instrumentation.
The instrumentation may include its own logic to check whether or not its features are supported.
At some point, a reference to the widget or toolkit must be made.
A popular approach is to use HTML ID attributes and instrument functionality based on included logic and a reference to the ID.
Another popular approach is to look for some other HTML atribute value or identifying characteristic.
Consider the various methods DHTML Behaviors are instrumented for Internet Explorer: through CSS classes and class ids, and the addBehavior method applied to a node reference.
Ultimately, the widget or toolkit must include logic to instrument itself, or the Web page developer must provide the instrumentation.
This could be a method invocation, an attribute, or simply including the script on the page.
The method of instrumenting a widget or toolkit can determine how wide spread it is used.
The simpler it is, the more people will use it.
Conversely, if the instrumentation is harder or more complex, then more people will be alienated.
Not everyone knows or wants to know how or why the widget or toolkit works, they may just want to use it.
If the instrumentation of the toolkit or widget could be compartmentalized into a declarative initializer, along with the widget or toolkit, then it might be much easier to use and reuse.
For instance, if you have an XML script for loading external XML and copying the nodes into an HTML node, would it be easier on the consumers of the XML script to use the API, or to provide a declarative API that allows the consumers to use declarative invocations?
Consider the following example:
<!-- Example #10.A -->
<import-xml src = "someExternalData.xml" />
The above example assumes two things: first, there is a definition for import-xml somewhere that points to the XML script and, second, that the node is permissable in its context (eg: do you really want it in an HTML document?).
For the moment, assume the latter case is acceptible.
Then, the declaration for import-xml might resemble the following:
<!-- Example #10.B -->
<definitions>
<definition id="import-xml">
<implementation>
<package pid="YourXMLScript" />
<constructor name="getXml">
<param value="ora:src_attr" />
</constructor>
</implementation>
</definition>
</definitions>
If a process is available that evaluates the import-xml element against the supplied definition, then the code for YourXMLScript can be abstracted from the implementation.
Also, the consumer of the code only needs to know what the declarative syntax is, not the script API.
[ top ]
Part 3: Intelligent Abstraction
One way to consider abstraction is that it provides an obfuscation of interface members and routines to make something else.
For example, some toolkits use abstraction to provide a set of complex features in an easier-to-implement routine.
Abstraction may be glue for disparate toolkits and APIs.
Or, it may be an unnecessary complication.
Part 3.1: Toolkits
Toolkits ostensibly provide useful features.
At times those features render obtuse APIs into something more acute.
Consider an XML Library for browsers.
It provides a couple methods for working with XML, and some features otherwise not universally supported (eg: selectSingleNode and selectNodes) supported).
In the context of working with XML support on a per-implementation-basis (browser sniffing: bad), it could be said that this toolkit abstracts features supported by the browser.
And, in exchange for figuring out browser support, the aforementioned toolkit then burdens the developer with learning a different API.
No matter the context, if the API changes, the developer will need to leran it.
The most developers can hope for is an API based on an existing specification (refer Appendix A: f(m) project) or have very good API documentation (refer Appendix A: netWindows).
Part 3.2: Declarative Abstraction
Declarative Abstraction is defined as thus: plain text.
Consider XML and its ilk, including Web Services and SOAP, XSL, XHTML, and SVG, to name just a few.
XML does one thing and one thing only: it describes data.
As such, XML is not the Wonka-vator of programming that the high-tech media would have readers believe.
But, that doesn't mean that the described data is not rich (a la SVG).
For example, WSDL, SOAL, and SVG can be quite complex and very useful.
In essence, these structures of data can represent declarative abstractions.
In the context of the XML Library mentioned in Part 3.1, a declarative abstraction of this library would be an implementation of an XML Data Island element (Internet Explorer).
This is not so much markup as the element represents a specific API invocation.
A custom declaration was suggested for Example #10.A, and a Declarative Definition (refer Part 3.3) was suggested for Example #10.B.
More useful than simply loading XML might be transforming it with an XSL stylesheet.
Such a declaration might be as follows, using an altered name so as not to conflict with the existing implementation:
<!-- Example #11.A -->
<xml2
id = "oXML2"
src = "/{path}/file.xml"
xsl = "/{path}/file.xsl"
/>
Of course, the above example won't do anything by itself because there is no xml2 element aside from existing as an arbitrary element.
If a developer was tasked with adding support for a custom client-side xml2 element that leveraged some non-specified XML library, that developer would wind up having to lookup the element in the Web page DOM and make a programmatic connection between the element and the toolkit.
The toolkit that abstracted browser-level XML support is then further abstracted, and not necessarily for the better.
However, the value of supporting the declarative xml2 element for other developers and content authors may outweigh the disadvantage of creating an additional layer of abstraction because the xml2 element is ultimately easier to use for the masses than adding a block of script.
Part 3.3: Declarative Definitions
Consider Example #11.A (refer: Part 3.2) and Example #10.B (refer: Part 2.2).
If a developer was tasked with adding support for a custom element that represented a declarative invocation, the element would have to be interpreted by some process.
Such interpretation might include the developer looking up the element name in the DOM, retrieving some attribute values, and then performing some programmatic routine.
Alternately, the developer might create a declarative definition for the element that performs two key tasks:
1) the definition defines the element, and
2) the definition defines access to the desired routine.
The following example, and adaption of Example #10.B, defines the xml2 element and also defines a constructor that refers to a transform method for YourXMLLibrary, and provides the values of the src and xsl attributes to the transform method.
<!-- Example #11.B -->
<definition id = "xml2">
<implementation>
<package pid = "YourXMLLibrary" />
<constructor name = "transform">
<!-- reference @src attribute -->
<param value="ora:src_attr" />
<!-- reference @xsl attribute -->
<param value="ora:xsl_attr" />
</constructor>
</implementation>
</definition>
</object-definitions>
Part 3.4: Separating Functionality and Content
In the manner that a process may be declared within XSL, a description in WSDL, or an invocation in SOAP, so might scripted functionality be declared for an element without specifying static scripted connections.
Consider the following input button element.
The element defines the field type (button), a value, and the custom attribute acid (application component id) attribute.
No global ID, no name*, and no custom event handlers.
*Note: A name is needed for elements when submitting the field as a part of a form.
<!-- Example #12.A -->
<input type = "button" value = "Act!" acid = "act_button" />
In lieu of specifying any custom handlers or processes, the custom attribute may refer to some arbitrary component with its own unique instance.
For example, the following XML and CDATA block describes a handler for the click event.
<!-- Example #12.B -->
<application-components>
<application-component id = "act_button">
<![CDATA[
_handle_click:function(){
/* do your stuff here */
}
]]>
</application-component>
</application-components>
Similar to Example #11.B, a declarative definition may be used to associate the custom attribute in Example #12.A with the component definition in Example #12.B.
Consider the following declarative definition.
<!-- Example #12.C -->
<definition id = "component-fragment">
<!-- match an 'input' node -->
<matdef rid = "input" />
<implementation>
<package pid = "ApplicationComponent" />
<constructor name = "newInstance">
<param value="ora:parent_element" />
<param value="ora:node_context" />
<param value="ora:acid_attr" />
</constructor>
</implementation>
</definition>
With single declarative definition, and one or more component definitions, the functionality for the input element in Example #12.A has been intelligently abstracted from the actual declaration of the element.
While these examples describe the approach used by the Engine for Web Applications project, it is the approach more than the Engine framework that is one tactic for separating functionality from content.
Some advantages to abstracting the functionality in this fashion are as follows.
- Apart from writing the script in separate component blocks, developers shouldn't have to load any external file(s) or make the connections between a component definition and the referenced node.
- Event handlers may automatically be registered based on a configured list of supported handlers, and only be used if the component defines a handler. Therefore, developers would only need to specify a handler to support the event for the given node.
- Full exposure to the hosting framework is available from the context of the component.
- The component is a unique instance, without requiring a globally unique id.
- The component may support a reference id applicable to the container (eg: Engine Service).
- The framework may allow components to communicate with each other (eg: Transaction Service) without knowing a component instance id.
- The component may exist as an external library, or be integrated back into the framework.
-
The component may have immediate awareness to the source element, the container element, and any reference container (eg: Engine object).
A developer could then access these elements without knowing names or IDs.
-
If the framework supports components communication, components may push packets of data to other components.
From the context of the component, the developer would not need to setup such component communication, but just use it is so desired.
That's a whole lot of power for one custom attribute, without having developers write script to connect declarative definitions to existing toolkits or worrying about namespace collisions.
One progression from here is to have components communicate some events with the server, thus making .NET WebForms that much cooler (no further explication).
Part 3.7: Content Architecture
Content.
It falls out of the database, pops up from the file system, and magically appears from code.
It could come from anywhere and most likely will wind up going somewhere.
Some content is shoved into one Web page.
Other content is broken up into frames.
Some content is magically written from off-screen buffers.
Or, there are plugins like Flash that provide content.
Content is data, and data is gold.
Anything mixed in with data is an impurity, and that is why no sane person claims HTML is a great way to store structured data.
Yet, ultimately, and apart from plugins, HTML is what the browser interprets, whether it comes from XML or a server-side application.
To follow the idea that data is gold, marking-up the data to support client-side script is adding impurities.
The reader is left to consider data that is only accessible if the client-side script functions properly.
Just as inline styles are eschewed in favor of CSS classes, so might static script connectors be considered.
If some script is associated with the content without a static binding, such as through a declarative definition, then the risks of tainting the data are greatly reduced.
One advantage to separating functionality from content by using declarative definitions is the content then may be designed (visualize a Visual Content Editor) and functionality may be associated with the content.
From such a context, it would be trivial to change the declaration, or the code, yet there would be no need to worry about changing the plumbing between the content and componentized functionality.
[ top ]
Part 4: Conclusion
One reason I feel so strongly about Intelligent Abstraction and the need to separate functionality from content is because I really do believe in the separation of form from content, and in XML as a delivery vehicle for data.
Personally, I like the idea of building software where the bindings between content and functionality are easily replaced; without modifying the content or the functionality.
I also realize this is not likely to happen for some time.
What I have found to be true is that the bleeding edge can be made a destination.
Consider .NET and J2EE.
Both were only on the fringe for a long while.
Ultimately, the decision to follow a design pattern rests with the designer.
That may be you, whipping up a specification in your spare cycles on how you will accomplish your next project.
Or, it may be your boss, whom you constantly deride for making irrational decisions.
Either way, a decision must be made.
The decision that needs to beis whether the architecture of a solution can adapt when the next change comes.
[ top ]
Appendices
Appendix A
Related Links:
[ top ]