RAD Architecture and Design


A RAD architecture is one that upholds timeliness of delivery as a central overarching principle. A RAD architecture both meets the needs of your customers and expedites the delivery of the system. In short, it is about defining an architecture that is implemented easily and efficiently by the development team and hence completed in a timeframe acceptable to the customer.

The following are some options for achieving this goal.

Work to the Strengths of the Team

Contrary to what many project managers would like to believe, software engineers are not faceless drones who spend all their spare time reading technical reference material on Java. The members of any given project team have acquired a diverse and varied range of skills and knowledge during their time in the software development industry. Knowing the strengths of the team is an important consideration when designing the system: the architecture should take advantage of these strengths.

Some people may find this a contentious statement, arguing that architecture must be based on the technology that best fits the system requirements. This is a valid argument. If the choice of technology was always based on the knowledge of the team, most IT applications would still be implemented in COBOL. Nevertheless, the team's collective technical background should be taken into consideration when time is a critical factor for the project.

Important

The same rule applies when looking to the job market for skills for the project. If members of the team leave, or a new project team has to be formed, filling vacant job roles could prove problematic if skills in an uncommon technology are required.


As an example, consider the choice of which scripting language to adopt on a new project. Both Jython and Groovy are excellent choices as scripting languages. Both are each compatible with Java and offer highly expressive language constructs. Nevertheless, if the team has a large base of experience with Perl, then neither Jython nor Groovy may be the best option. Where possible, you may wish to stick to what the team knows well and work to your strengths. Without doubt, there is value in learning new technologiesjust be cautious of learning on time-critical projects.

Chapter 9 looks at Jython and Groovy.


Use Best-of-Breed Frameworks

J2EE is all about frameworks, yet extensive as the J2EE platform is, it does not cater to every scenario. Enter the application framework to plug the gaps.

A suitable software framework can significantly reduce the amount of code we need to write and improve the quality of the design. Thanks to the groundswell of support for all things Java, J2EE developers are spoiled for choice when it comes to the availability of software frameworks.

Frameworks are available for just about every conceivable application, including Web development, security, build environments, test environments, and GUI development. Table 4-1 lists a selection of the popular offerings from the Java community and highlights the diversity of the frameworks available.

Table 4-1. Open Source Frameworks

Name

Description

Reference

Web

Apache Struts

Struts is a popular Web application framework based on the model-view-controller (MVC) design paradigm.

http://jakarta.apache.org/struts/index.html

JavaServer Faces

A technology for developing user interfaces for Web applications using an industry-standard set of APIs. JavaServer Faces technology was developed under the Java Community Process as JSR-127.

http://java.sun.com/j2ee/javaserverfaces

Apache Tapestry

Dynamic Web application development framework that centers on a component model in preference to a scripting approach.

http://jakarta.apache.org/tapestry

Persistence

Powerful, high-performance, object/relational persistence framework for Java objects.

http://www.hibernate.org

Hibernate

ObjectRelational-Bridge

OBJ is an object/relational mapping tool from Apache Software Foundation.

http://db.apache.org/ojb

Logging

Apache Log4J

Log4J provides an externally configurable logging framework.

http://logging.apache.org/log4j/docs/index.html

Application

Spring

Spring provides a layered framework for producing Java and J2EE applications. The Spring framework can either augment the services of the J2EE platform or be used standalone for developing highly flexible component-based systems.

http://www.springframework.org

Build Environment

Apache Ant

Popular Java-based build utility that uses an XML-based syntax for creating build scripts.

http://ant.apache.org

CruiseControl

Framework for supporting the practice of a continuous-integration build environment.

http://cruisecontrol.sourceforge.net/index.html

Apache Maven

Maven describes itself as a project management and project comprehension tool, and takes responsibility for managing and orchestrating the various artifacts that the project comprises.

http://maven.apache.org

Testing

JUnit

An almost ubiquitous xUnit-based testing framework for Java developers.

http://junit.sourceforge.net

Apache Cactus

Cactus extends JUnit and focuses on the challenges of testing server-side components.

http://jakarta.apache.org/cactus/index.html


The choice of which framework to use on a project is an important decision that can be critical to the success of the project. The following guidelines should help you through the decision-making process:

Team knowledge.

Look to work with products that have proven successful on other projects, and consider frameworks with which the team already has experience.

Maturity.

How long has the framework been used in commercial software development? Is it an open source project maintained by Apache, or is it the result of someone's PhD? A mature software product has all the rough edges knocked off. Be prepared for problems if the software has yet to be used on a commercial development.

Fit for purpose.

Pick a framework that meets the specific needs of the system. Where an acceptable match cannot be found, longer term benefits maybe realized by investing in the development of your own framework for a specific business area.

Tool support.

Tool support is a significant criterion in the selection of a suitable framework, because the combination of framework and development tool can offer significant productivity gains.

Longevity.

Try to select frameworks that will remain supported for the predicted lifetime of the system. A framework that disappears from view once a system reaches production presents ongoing maintenance and support problems.

Picking the best framework for your project reduces the development timeframe and should contribute to the quality of the final application. Here are some metrics to use as a guide when assessing a framework in terms of its maturity and longevity:

  • Availability of mailing lists and discussion forums

  • Level of activity on these forums

  • Response time for users getting questions answered and quality of the answers

  • Frequency of new releases of the framework

  • Community feedback in terms of perceived quality and usability

  • Number of open defects

  • Quality of documentation

Choosing a framework is an important decision, so be sure to do your homework before making it.

Think Ahead

By thinking ahead during the design process, you can make the lives of developers and testers alike a lot easier. The need to think ahead is especially relevant in the area of testing.

Sadly, testing is often unfairly seen as the poor relation to development. This perception is unwarranted, as testing is an integral part of the software development lifecycle. As a rough rule of thumb, testing hours on a project will likely equal that of developmentany less, and the system is probably undertested.

Any actions you can take as an architect to make testing easier will not only result in a higher quality system, but also reduce the total testing effort. Exactly how the architect can design with testing in mind is largely dependent on the application.

Testing is a key part of RAD and is covered in some detail in Chapters 14 and 15.


Outlined below are some points for consideration when working on the system design.

Include Test Stubs and Unit Tests as Part of the Design

Considerable effort is often wasted on projects when developers produce their own ad hoc testing harnesses. These test harnesses sprout like weeds throughout the project's code base. They burst into existence as developers find themselves unable to test new components or modules due to a dependency on a piece of software that hasn't yet been written. The solution is often to quickly implement a test stub in place of the missing software. Unfortunately, this task consumes time, and on a large project, this practice can quickly get out of hand with engineers duplicating the same test stubs.

These test stubs seldom find their way into source control and are often of dubious quality because no time has been set aside to the developer for this task on the project plan. To avoid this problem, the architect must think strategically and incorporate all necessary test stubs into the design. The designer must work in conjunction with the project manager to ensure software components are built in a logical sequence to avoid the need for ad hoc test stubs. Where this is not possible, the test stub should be included as part of the object model and time set aside on the plan for the development of the stub.

With this approach, all test harnesses and stubs become part of the project's build cycle and are available to the entire team. They can also be made available to the test team for early testing of delivered components. The test team in turn can give feedback on the quality of the test stubs.

Therefore, the rule is, think about your testing needs early on, and design testing into the system. Your developers and your testers will thank you for it.

Be Wary of Weakly Typed Interfaces

Due to the surge in popularity of XML as a format for data transfer, the interfaces on distributed components the world over are taking on a very similar appearance. Thus, many methods now have the signature

 void update(String document); 

The parameter document in this case carries an XML document as the payload. Using XML in this way has largely taken over from the conventional approach of defining each argument as a typed parameter on the method as it provides an effective approach for ensuring loose coupling between components. The structure of the XML document can be modified without the need to change the interface, allowing for a design that is very resilient to change.

The downside to this approach is that the compiler cannot perform any type checking of the data on our behalf. Type checking, or validation of the document against a schema, must now take place at runtime. With XML, Java becomes a type-less language.

This presents the test team with something of a headache. Errors are harder to catch at runtime than at compile time, and the testing effort must now be exhaustive.

If you intend to use XML in this manner to achieve a highly decoupled system, then ensure the necessary safeguards are in place to replace the compiler's type safety. Where practical, validate against an XML schema and always log any errors caught at runtime in a manner that makes them immediately apparent.

Be Wary of Designing for Reuse

Software reuse is a key element of RAD, but reuse is a double-edged sword. Making the reuse of software components part of your strategy for rapid development is not an easy task, even with the benefits of Java as an OOP language and J2EE as a container for housing prefabricated components.

Designing code for reuse is a difficult and time-consuming task. The developer must consider all reasonable future scenarios for a component and accommodate them accordingly within the software architecture. This adds excessive complexity to the component's design and implementation. On a project with a tight timeframe, you should avoid overengineering the architecture for future reuse purposes. Rapid development project teams should design only to have the software meet the current known requirements, not possible future ones.

This fits in with the fundamental XP principle of keeping the design simplea principle aptly described by the XP expression, "You ain't gonna need it," or YAGNI. Remember, less code means fewer defects.

Chapter 3 covers the practices of XP.


Warning

Rapid development requires designing with reuse as opposed to designing for reuse.


Designing for reuse adds considerable complexity to the project and hence consumes additional resources and time. Instead, develop reusable components as a separate research and development project aimed at building your company's adaptive development foundation.

Have the components built, tested, and documented before rapid development project teams use them. A suite of suitably designed prefabricated components provides a development company with a competitive advantage, but this is an investment that needs to be made as part of a company's preparation effort for rapid development. Don't build the components of your adaptive foundation on time-critical customer projects.

Apply Orthogonal Design

Orthogonality is a term taken from geometry that applies to two lines that intersect at right angles. As vectors, these lines are said to be orthogonal and therefore independent. Thus, move along one of the lines, and your position projected on the other line remains unchanged.

Despite its origins in geometry, orthogonality is becoming a watchword in development circles after being popularized as a software engineering concept by Andrew Hunt and David Thomas in their book The Pragmatic Programmer [Hunt, 1999].

For software engineering, the term neatly summarizes those elements of design that are synonymous with well-constructed software; that is, they exhibit the admirable characteristics of loose coupling and high cohesion.

Orthogonal components are independent, self-contained, and have a clearly stated responsibility. Changes to the internals of an orthogonal component do not impact other components within the system.

This independence between components is vital to rapid development. A loosely coupled system can more easily accommodate change than one that is tightly coupled. A change in the database should not require a change in the code responsible for the application's user interface, and vice versa.

An orthogonal design safeguards against change, and a design that can absorb the impact of change supports rapid development. Moreover, components that exhibit orthogonality are easier to code, test, and maintain due to their self-contained nature. Again, these are all attributes that help make a team productive and greatly benefit a RAD project.

Object-oriented development practices, if applied correctly, result in orthogonal designs. A staple of object-oriented design is the use of interfaces. By designing our components around interfaces, we can use interfaces as shields against implementation changes.

One successful approach for achieving an orthogonal design is to base your design upon the use of layers.

Adopt a Layered Architecture

In software engineering, separating the application code into layers is good design practice and enables the construction of robust applications. In the layered approach, each layer provides its services to the layer immediately above through a series of well-defined interfaces.

Each layer should rely only on the services of the layer immediately beneath it. This ensures higher layers in the design hierarchy are insulated from changes in the lower layers.

Here are the layers commonly found in business software:

  • Presentation, for user-interface components

  • Application, where the system's business logic resides

  • Data, for providing business components with access to external resources such as persistent data stores or other enterprise systems

Layers are abstract and represent a logical boundary within the software, not a physical one. Distributed computing makes it possible to achieve a physical separation of a system's logical layers into tiers. The tiers of a multitier architecture are physically remote from one another, typically located on different servers or executing in a separate process. This physical division of the layers into tiers gives rise to a multitier architecture.

The architecture of a J2EE application comprises three tiers.

Client Tier

The client tier is the "final front-tier." It should contain code specific only to the user interface and rely upon the middle tier for all business knowledge. J2EE clients run on anything from desktops to handheld devices and access the middle tier remotely, using an appropriate network infrastructure such as a LAN or via the Internet.

Middle/Business Tier

On the J2EE platform, this middle tier is the J2EE server, which provides services for addressing the concerns of both Web clients and application business logic. The middle tier of the J2EE platform divides into two tiers for each of these concerns:

  • The Web tier provides services for orchestrating the interaction between Web-based clients and the system's business logic

  • The EJB tier manages the system's business components deployed within the tier as Enterprise JavaBeans

The J2EE server manages access to resources required by the business components. These resources reside within the enterprise information system (EIS) tier.

Enterprise Information System Tier

The EIS tier, or back-end tier, is the lowermost tier in J2EE and houses the enterprise resources upon which a J2EE application relies. Examples of enterprise resources include relational databases and existing legacy systems. The resources of the EIS tier do not fall under the control of the J2EE server. Instead, the J2EE server offers a set of standard services for integrating with EIS tier resources. These services include

  • The JDBC API for relational database access

  • Java Naming and Directory Interface (JNDI) for access to directory servers

  • The J2EE Connector Architecture (JCA) for integration with existing information systems

  • Java Messaging Service (JMS) for asynchronous communications with other application resources

The J2EE server undertakes the responsibility of managing and pooling connections to the various resources of the EIS tier as well as the management of transactions that span enterprise resources.

The J2EE platform makes possible the design of orthogonal systems using multitier architectures. The next section considers the strengths and weaknesses of using multiple tiers and explores some design options for J2EE architectures.



    Rapid J2EE Development. An Adaptive Foundation for Enterprise Applications
    Rapid J2EEв„ў Development: An Adaptive Foundation for Enterprise Applications
    ISBN: 0131472208
    EAN: 2147483647
    Year: 2005
    Pages: 159
    Authors: Alan Monnox

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net