Você está na página 1de 11

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.

html

June 2004

Discuss this Article

Disclaimer
This is not a new framework to reduce your code, and by no means, a fully developed concept or a tool to be
immediately used. At worst, its a wild thought, and at best, it might provide a new way to inspect your
design from the view point of standard roles for each functional unit, independent of its level, resulting in a
more modular and maintainable system.

The next few sections will introduce the "unit", the building block of this perspective, by describing its
structure, roles and communications. Latter sections discuss a sort of case study and tool support.

Structure
Generally, an object can be assigned with a role by means of class inheritance or interface implementation.
But how do we attach a role to a module, a subsystem or a method? How can I inherit a module or
subsystem from the other? We need a means to express things in terms of role and organization at all levels
inside a software system.

TOP looks at a software system as a hierarchical organization of units. Each node in the tree is a functional
unit performing a well-defined and possibly standardized role. As a concrete form, a unit can represent an
object, a method, a module, a layer, a tier, a subsystem, or an entire system.

A unit commonly has

1. Input and output interfaces


2. Local data and cached data (optional)
3. Access to its peer units, inner units and container.
4. Access to an external service provider for common concerns such as logging and security (optional)
5. Mechanisms such as request queuing, caching, and resource pooling (optional)

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (1 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

Standard roles
A unit performs all the basic roles and a specific role as assigned by its container:

Basic roles

1. Server, servicing requests from its peer units


2. Container, managing a set of inner units
3. User, sending requests to its peer units

Specific roles

These roles are assigned to a unit by its container, for its container

1. Builder / Dismantler
An inner unit, which knows how to build or dismantle its container.

2. Input controller / Output controller,


An input interface of a unit is a set of inbound requests for dispatching to its inner units. An

inner unit designated as input controller will handle all the inbound requests.
An output interface of a unit is a set of outbound requests from its inner units for dispatching

to its peer units and container. An inner unit designated as output controller will handle all the
outbound requests.
An interface controller can talk to its peer units as wells as its containers peer units. This is an

exception since interface controllers represent their container's identity.


Examples

HTML document loaded in a web browser.

Servlet

Front controller session beans

Data access objects

Input validation and internal routing logic inside methods of a class.

Common concerns

Validation of input

Invoking request handlers

Routing of request / responses.

3. Request handler
Examples:

Shopping cart handler

Job scheduler

Search engine

Common concerns

Request validation, delegation and coordination of preparing the response.

4. Serializer / Deserializer
Collaborates with state manager for transformation of the unit state into custom formats and

vice-versa.

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (2 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

Examples:

Database import / export (application state)

Object serialization / de-serialization

Common concerns

Conversion between formats

5. State manager
Manages access requests to persistent and non-persistent data from its peer units. Sometimes it

could just be the state without a manager.


Examples

Data tier (data access components, database drivers and the database)

Entity beans (EJB)

Users http session data

Data local to object instances,

Variables with page level scope (JSP)

Data stored in cookies

Common concerns

CRUD operations

Managing concurrent access

Refresh at intervals

Security

Auto expiry/update

6. Error handler
Helps request handlers and processors to handle error conditions encountered during

processing of a request, in a unit-specific way.


Can also be seen as a common concern such as logging and security validation. In such cases,

units do not maintain this role.

The terms controller, interface, handler have different concrete forms at different levels. A units
communications are generally limited to its peer units, its container, its inner units and an external service
provider for common concerns.

Communications
Units talk through their interfaces. An interface always means capability to handle a set of valid inbound
requests or outbound responses or a combination of them, in a defined format, protocol and sequence,
complying with a defined functional specification. An unit's output interface controller (dispatcher unit) can
send requests to its container's peer units. Units in all other roles can only talk to their peer units.

A Unit recieves messages from two kinds of sources - its inner units and other units. Inner units talk to its
container through the output controller of the container, mostly for sending requests for their container's peer
units. The "other" units which are not inner, talk to a unit using its input controller.

Results for an synchronous call are returned to the caller through the input controller, while asynchronous

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (3 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

results are routed through its output controller. The ouput controller is also used while processing
synchronous calls, for involving its peer units. The return types could references to units.

Fractal nature
The most important aspect of this perspective is independence from scale and complexity of systems. The
same principles can be possibly applied at any level. Such fractal characteristics are generally displayed by
some natural systems such as topographic features like landscapes and rock formations. The large rock
formations resemble the crystal structures at micro level. If encapsulation, inheritance, interfaces are too
good at object level, they might be good at at other levels as well.

Also, application of standardized hierarchical role patterns in design could lead to defining sets of common
concerns applicable to each role and identification of standard ways of addressing these concerns, and
finally, standard ways for testing the units based on their roles.

Case study: Pet store application


I'm not trying to build the Sun's Pet store application using the TOP perspective here. This section attempts
to identify the hierarchical roles in the application, by applying the description of a "unit", which was
discussed so far.

As we all knew, the multi-tiered architecture for the Sun's J2EE Blueprints application is reflected in the
following diagram.

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (4 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

Lets examine a mini laboratory model of Pet store - a multi-tiered java class! This is a really tiny model of a
generic Petstore application, which allows us to apply TOP perspective to it, though on a tiny scale.

class PetStore extends Unit {


// ------ Database / State ----------
private ArrayList inventory = new ArrayList();
private ArrayList orders = new ArrayList();

// ------ HTML pages / Application front controller ----------


public Response processRequest(ArrayList request) { // override of
Unit's only method
switch (getRequestType(request)) {
case 0: storefrontHandler(request); break;
case 1: supplierHandler(request);
}
return new Response(); // based on results
}

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (5 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

// ------ Web tier / Request handlers ----------


private void storefrontHandler(ArrayList request) {
switch (getRequestType(request)) {
case 0: checkoutHandler(request); // checkout
}
}
private void supplierHandler(ArrayList request) {
switch (getRequestType(request)) {
case 0: inventoryHelper(request); // add stock
}
}
private void checkoutHandler(ArrayList request) {
switch (getRequestType(request)) {
case 0: request.add(0, "0"); // new order
storefrontDispatcher(request);
}
}
private void storefrontDispatcher(ArrayList request) {
switch (getRequestType(request)) {
case 0: orderHelper(request); // add order
}
}
// ------ EJB tier / Request helpers ----------
private synchronized void orderHelper(ArrayList request) {
switch (getRequestType(request)) {
case 0: addOrder(request); // new order
removeInventory(request);
}
}
private synchronized void inventoryHelper(ArrayList request) {
switch (getRequestType(request)) {
case 0: addInventory(request);
}
}
// ------ Data access / State manager ----------
private synchronized void addOrder(ArrayList request) {
orders.add(request.get(0));
}
private synchronized void addInventory(ArrayList request) {
inventory.add(request.get(0));
}
private synchronized void removeInventory(ArrayList request) {
inventory.remove(inventory.indexOf(request.get(0)));
}
// ------ Utility ----------

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (6 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

private int getRequestType(ArrayList request) {


return Integer.parseInt((String) request.remove(0));
}
}

A discussion of various parts of the above model is in order. The HTML UI is represented by the only public
method processRequest(), which means that this method is invoked by the unit "user" by populating
the request with form data etc, such as -

// ------- User unit ----------


PetStore app = new PetStore();
// populate inventory using supplier interface
app.processRequest(prepareRequest(new String[] {"1","0","0", "Dog"}));
app.processRequest(prepareRequest(new String[] {"1","0","0", "Cat"}));
// place order using storefront interface
app.processRequest(prepareRequest(new String[] {"0","0","0","0",
"Dog"}));

Ofcourse, Ive omitted several details. And, most importantly, this does not indicate any implementation
pattern for TOP based design

This micro-scale model did a poor job of addressing all the features needed for a Pet store application, but it
tries to capture the essential role based division of work. EJB tier represents more generic and frequently
used operations compared to Web tier. We could probably host these methods in a separate container with
better performance and scalability because they are frequently used. Data tiers major concerns are
concurrent access, security and performance. We made the data access methods as private (security),
synchronized (isolation) and havent done anything for performance right now.

It is interesting to note that multi-tiered partitioning, which helps to address the non-functional concerns
such as performance, scalability, security, is relevant at micro level as well, and so is modularity. While the
modular and multi-tiered partition is quite visible, an equally predominant view is role based hierarchical,
recursive perspective (TOP). processRequest() represents the interface controller, while the request
handlers and state manager (set of data access methods) are obvious in their roles.

There may be a small glitch in the Blueprints Petstore application. If you close the browser, your shopping
cart is lost. Shopping cart can be stored as cached state for the application interface controller units (html
pages), and TOP reminds you to about this concern during design of this unit.

If you noticed, the method storefrontDispacther() is the output controller for storefront unit. The
storefronts inner unit checkoutHandler() talks to orderHelper() through
storefrontDispacther(), because orderHelper() is not a peer unit for checkoutHandler
().

Now its time for an interesting step - growing up by cell division. Spin-off separate classes (units) to handle

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (7 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

roles of interface controller, request handlers and state manager. Each of these units will again have their
own internal units (methods) performing the standard roles, just like the PetStore class had in its childhood
days. The units can choose their own implementation strategy Java class, JSP page, EJB bean or even
XML etc and their protocols to communicate. Following is the code for a little grown up Storefront handler
unit.

class Storefront extends Unit {


// ------ Unit state ----------
private ArrayList userSession = new ArrayList();
private ArrayList catalogCache = new ArrayList();
private ArrayList shoppingCart = new ArrayList();

// ------ Container unit reference ---


private Unit container;

public Storefront(Unit store) { // A Petstore object is passed


this.container = store;
}
// ------ Front controller ----------
public Response processRequest(ArrayList request) {
switch (getRequestType(request)) {
case 0: checkoutHandler(request); break;
case 1: catalogHandler(request); break;
case 2: shoppingCartHandler(request); break;
case 3: signonHandler(request); break;
}
return new Response(); // based on results
}
// ------ Request handlers ----------
private void checkoutHandler(ArrayList request) {
switch (getRequestType(request)) {
case 0: request.add(0, "0"); // new order
storefrontDispatcher(request);
}
}
private void catalogHandler(ArrayList request) {
switch (getRequestType(request)) {
case 0: getCatalog(request); // view items in a category
}
}
private void shoppingCartHandler(ArrayList request) {
switch (getRequestType(request)) {
case 0: addCartItem(request); // add item to cart
}
}

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (8 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

private void signonHandler(ArrayList request) {


switch (getRequestType(request)) {
case 0: request.add(0, "1"); // authorize
storefrontDispatcher(request);
}
}
// ------ Output interface controller ----------
private void storefrontDispatcher(ArrayList request) {
switch (getRequestType(request)) {
case 0: container.getOrderHelper.processRequest(request);
break;
case 1: container.getSignonHelper.processRequest(request);
break;
}
}
// ------ State manager ----------
private synchronized Object getCatalog(ArrayList request) {
return catalogCache.get(catalogCache.indexOf(request.get(0)));
}
private synchronized void addCartItem(ArrayList request) {
shoppingCart.add(request.get(0));
}
// ------ Utility ----------
private int getRequestType(ArrayList request) {
return Integer.parseInt((String) request.remove(0));
}
}

Tool support
The concept is still in its infancy. While it gains momentum and gets refined through corrections, tool
support would naturally follow it. Currently an XSL based viewer is available to visualize the perspectives.
The tool, including its source code is available for download. The viewer renders an XML formatted
perspective in a browser using XSL, Javascript and DHTML, allowing a user to navigate through the
perspective. I'm also working on a Swing based full-fledged visualizer, with lot more features for working
with perspectives. Following is a screenshot of the TOP Viewer loaded with a sample perspective for
Petstore application.

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (9 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

Conclusion
This article does not tell you to start a project by writing a mini Java class and grow it up by cell division.
Nor does it mean to say that almost the entire application could be built using XML files, except for the low-
level leaf units, which need to be implemented in a non-XML programming language. It also doesn't mean
that one has to use ArrayLists and switch case statements to implement a TOP based designs; it's just an
example I chose to fit space constraints here.

The article does attempt to provide a new perspective on the architecture. Applying the perspective on
existing applications might let you find missing roles and optimize the performance of standardized roles.
The perspective will help new applications to be conscious of the standard internal roles and their

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (10 of 11)01/07/2004 8:49:19


http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html

hierarchical division. This reduces complexity of the design and provides high degree of modularity and
encapsulation and fights against crisscross references between objects, Thus, we just tried to visualize a role
based tree perspective that can be recursively applied using standardized roles that share common concerns.

PRINTER FRIENDLY VERSION

http://www.theserverside.com/articles/content/TreeOrientedPerspective/article.html (11 of 11)01/07/2004 8:49:19

Você também pode gostar