Practice 15. Leverage Patterns


Bruce MacIsaac

Leverage patterns to solve problems and to capture and communicate solutions.

Problem

Broad experience is a quality in short supply, and even experts should not be inventing new solutions if there are proven solutions that work. Patterns offer "distilled experience" with the following benefits:

  • Patterns can help users solve problems faster by providing tried and true solutions.

  • Systemwide patterns ensure that problems are solved once and that solutions are applied consistently across the system.

  • Experts in short supply can be leveraged more effectively by capturing their experience in patterns that can be applied over and over again.

This practice describes how to use patterns to solve problems and capture and communicate solutions.

Background

Let's start with a few key definitions.

Pattern: A General Definition

Before giving a definition, let's start with a simple example. "Divide and conquer" is a time-honored strategy in war, government, and computing science. The strategy can be described as follows:

  • Name: Divide and conquer

  • Problem: The opposing army is large and imposing. Or, in mathematics or computing terms, the problem is large and intractable.

  • Solution: The divide-and-conquer strategy consists of weakening an enemy by dividing its forces. This military solution has a long history, going back at least to Sun Tzu's Art of War 2,400 years ago. The Romans also used it to build their empire, making treaties with one state so that they could attack its neighbor.

    In mathematics and computing science, the strategy is applied by dividing a large problem into several smaller problems that are easier to solve and can be combined to solve the larger problem.

  • Applicability: This pattern fails if the opposing armies refuse to be divided. American revolutionary forces in 1776 successfully applied the counter-pattern "united we stand."[1]

    [1] Oddly enough, "divide and conquer" can also fail in mathematics. Reference "Simpson's Paradox" at http://en.wikipedia.org/wiki/Simpson's_paradox.

Figure 6.2. Divide and Conquer.

A pattern, such as "divide and conquer," applies to many different situations.


This simple example demonstrates the defining characteristics of a pattern:

  • The memorable and descriptive name makes it easy to remember and apply. You don't need to describe the technique every time it is applied.

  • The pattern solves a recurring problem.

  • It is not a complete solution, but rather a strategy that can apply in different circumstances (sometimes as different as war and computing science).

  • The pattern doesn't apply in all circumstances. A good pattern description indicates when the pattern should be applied.

Benefits of Patterns

Whether developing a new system or integrating or upgrading an existing system, basic problems recur that have already been solved. When the solution is distilled and captured as a pattern, it can be reused, which saves time. But more important, using proven solutions reduces risk and so increases the likelihood of success.

Patterns are proven solutions to common problems.


Patterns are also useful as a means to understand and document existing systems. Like an archaeologist, you can excavate the patterns used by the original software designers and use patterns to document that architecture.

Learning standard patterns provides developers with a rich vocabulary for communicating design alternatives and offers a toolkit full of proven solutions that can be applied as needed. Developers thus become more effective and efficient. One caution: overuse of patterns can complicate a design. It is generally best to apply new patterns in their simplest form until you have gained experience.[2]

[2] The Agile Modeling practice is to "apply patterns gently"; see Ambler 2004.

Overuse of patterns can complicate a design.


Software Design Patterns

Software design patterns are patterns that solve software design problems. In addition to providing a name and description, design patterns can often be enhanced by diagrams. Figure 6.3 shows an example of the "Proxy" design pattern,[3] expressed in UML.[4]

[3] For a detailed description of the problems solved by this pattern, see Gamma 1994.

[4] See Practice 18: Model Key Perspectives for more on using UML.

Figure 6.3. Structure of the "Proxy" Design Pattern.

The client uses an interface. Both the Proxy and RealSubject implement that interface, but the Proxy just redirects calls to the RealSubject.


Figure 6.4 shows the behavior (how invoking the proxy results in a delegated call to the RealSubject).

Figure 6.4. Behavior of the Proxy Pattern.

Calls to the proxy are redirected to a class that provides the real implementation.


Note the following characteristics of the notation used in this pattern:

  • It does not identify actual classes; rather, it describes generic roles to describe characteristics of pattern participants.

  • The real classes could be anything, from an online auction querying a credit card system to a ground station talking to a satellite.

  • The use of roles allows the pattern to be applied in many different kinds of software systems, with many different classes.

Software Architecture Patterns

A software architecture pattern is a design pattern that has a wide impact on the overall system. Because of the wide range of problems encountered in software development, architecture patterns (and more generally design patterns) are typically organized into categories of the problems they solve, such as the following:[5]

[5] The Pattern-Oriented Software Architecture Series (Buschmann 1996, Schmidt 2000, and Kircher 2004), and Fowler 2003 are excellent references for architectural patterns.

  • Structural patterns: how to organize software into manageable units for development.

  • Distribution patterns: how to distribute processing across multiple processors.

  • Concurrency patterns: how to deal with parallel processing.

  • Persistency patterns: how to store data in files and databases.

  • Presentation patterns: how to design software for user interfaces.

The pattern categories above closely relate to the architectural views described in RUP.[6] Considering each view and pattern category helps ensure that the key aspects of the architecture are addressed.

[6] RUP uses the architecture views described in Kruchten 1995.

A reference architecture is a collection of patterns that define a basic architecture for a system. Using a reference architecture is easier than picking and choosing individual patterns, but offers less flexibility.

Using a reference architecture is easier than picking individual patterns.


Applying the Practice

Learning to apply patterns is a skill that takes time and practice to cultivate. The following section provides guidance for getting started with patterns and introduces more advanced applications of patterns.

Increase Your Knowledge of Relevant Patterns

It is important for developers to be familiar with key patterns relevant to their field and to use them as basic tools for solving problems and communicating solutions. The section Additional Information at the end of this practice lists some good places to start.

Developers should be familiar with key patterns.


Use Reference Architectures

There may be existing documented architectures within your organization, or in literature, that fit closely with the system that you are trying to build. A good "reference architecture" is a collection of related patterns that fit a particular business and technical context and should include examples and other artifacts to enable their use. One such set of reference architectures is IBM's Patterns for e-Business.[7] The IBM Patterns for e-Business Web site provides more than a simple list. It includes a wizard that helps you progress from identifying the business problem that you are trying to solve to choosing the specific architecture that meets your needs.

[7] Accessible at http://www.ibm.com/developerworks.

Reference architectures are patterns proven to work together.


Reference architectures are a good way to start looking at patterns. The set of patterns is predefined, which saves you picking and choosing patterns yourself. Reference architectures are also less risky, since the selected patterns have been proven to work together.

Identify Patterns for Cross-Cutting Concerns

Solving common problems the same way keeps an architecture consistent and understandable. Architectural patterns for structure, distribution, concurrency, persistency, and presentation generally impact multiple components of the system. Requirements to support globalization, security, redundancy, error reporting, and so on typically also affect multiple components.

There are two aspects to addressing most cross-cutting concerns: (1) identifying software that provides common services (sometimes referred to as "mechanisms") and (2) describing how those mechanisms are to be used by the client software (patterns).

In early analysis, these mechanisms are described textually, as a placeholder for one or more components yet to be selected or designed. Classes are mapped to mechanisms as shown in Figure 6.5.

Figure 6.5. Mapping Design Elements to Analysis Mechanisms.

Classes and subsystems are mapped onto the identified analysis mechanisms: the arrows indicate that the class uses the mechanism. A client class often uses several mechanisms.


As analysis and design proceed, analysis mechanisms, such as "persistency," are narrowed to specific design mechanisms, such as "relational database persistency" and patterns of use. This relationship is then further refined to specific implementations such as "Cloudscape database," and patterns of use can be demonstrated with working examples.

As the system evolves, you may find similar code appearing in several places, or different code being used to solve similar problems. Such discoveries frequently signal a need to define and refactor to a common pattern.

Multiple solutions to similar problems indicate a need for patterns.


Document Patterns Used in Your Project

Architectural patterns are solutions to key technical challenges, many of which have systemwide implications. If there are no guiding systemwide patterns, developers may come up with different solutions to similar problems, causing additional effort and unnecessary complexity. Consciously applying patterns throughout the system generally leads to more consistency and simplicity.

Applying systemwide patterns improves consistency and simplicity.


To ensure that the architecture doesn't degrade, architectural patterns need to be documented and enforced. Enforcement here simply means that the architecture should not be allowed to degrade through sloppiness; developers and reviewers should defend standard patterns and avoid deviations whenever possible. The simplest way to do this is to create good examples early in the project for others to follow.

Using UML to Document Patterns

An intermediate application of patterns is to use UML to document the patterns in your software, as shown in the previous "Proxy" example. UML provides a rich standard visual notation for capturing both structure and behavior. The advantages of UML are further discussed in Practice 18: Model Key Perspectives.

Your main goal should be to document the problem and to describe when the pattern applies and when it does not apply. Diagrams, UML or otherwise, can help you create compact and precise descriptions.

Document patterns precisely and compactly with UML.


Automated Pattern Application

Tools[8] are available that not only document patterns using UML but can also apply and enforce patterns in a model. As an example, you might decide to apply the "Proxy" pattern (described earlier) to a particular client and subject class. A wizard can automate applying the patterngenerating the interface and proxy class from the subject class, revising the original client to invoke the proxy, and generating calls from the proxy to the real-subject class.

[8] For a list of UML tools, with varying levels of support for patterns, visit http://www.uml.org.

Note that since patterns are not generally complete solutions, but rather characteristics of solutions, only some patterns can be automated. The best approach is to identify excessive repetition in your designs or your implementations and use automated patterns as a tool to simplify your work.

Use automated patterns as a tool to simplify your work.


Other Methods

Traditional waterfall development details all the design before implementing and testing. Patterns can be incorporated in this approach, but waterfall development does not provide the opportunity to validate these patterns on a small amount of code before they are used broadly.

Patterns are a key part of the Unified Process's focus on architecture. Patterns are validated by implementing and testing examples before they are widely implemented, allowing the patterns to be improved without impacting a lot of the design and code.

Patterns are a key part of the Unified Process's focus on architecture.


Early implementation of patterns is consistent with XP's principle of "incremental design," which states that "design done close to when it is used is more efficient."[9] However, the Unified Process explicitly recommends looking for key patterns and implementing them. XP doesn't have this same architecture focus; rather, patterns and consistency emerge through continuous refactoring.

[9] Beck 2004.

RUP encourages automated application of patterns and reuse of patterns to increase productivity, although this is an advanced application of RUP. XP doesn't discuss this topic explicitly, but XP's value of simplicity and principle of "baby steps" remind teams to be cautious about doing too much too soon.

Levels of Adoption

This practice can be adopted at different levels:

  • Basic. Learn patterns. It is important for developers to be familiar with key patterns relevant to their field and to use them as basic tools for solving problems and communicating solutions.

    Create and follow good examples of cross-cutting patterns.

    Understanding and applying patterns can speed development and enhance communication. Less design documentation is needed if standard patterns are followed.

  • Intermediate. Use reference architectures; these partial solutions can add a lot of value relative to the effort required to use them.

    Understanding and applying reference architectures can speed development of projects that can leverage a reference architecture.

    Use UML to document design patterns; the visual representation provides a compact and precise means of documenting patterns.

    Documenting patterns using UML takes time, but it is an investment that can pay off in more accurate communication and, more important, be the basis of reusable pattern assets.

  • Advanced. Use pattern automation to speed repetitive work and improve consistency.

    Apply patterns across the enterprise as part of an enterprise architecture. Create repositories of reusable patterns as part of a reuse program.

    Advanced applications of pattern automation, enterprise reuse, and aspect orientation are investments that suggest more discipline, at least initially.

Related Practices

  • Practice 2: Execute Your Project in Iterations describes iterative development as offering the opportunity to discover and test patterns in early iterations, make any necessary corrections, and then use those patterns consistently through the rest of the development effort.

  • Practice 10: Prioritize Requirements for Implementation illustrates that examples of cross-cutting patterns should be developed early. Prioritize requirements that will create such examples and allow you to get them right.

  • Practice 16: Architect with Components and Services describes many useful patterns for identifying components and for using components.

  • Practice 17: Actively Promote Reuse shows that patterns are reusable assets and should be a part of any systematic reuse effort.

  • Practice 18: Model Key Perspectives demonstrates that UML collaborations are a good way to document design patterns.

Additional Information

Information in the Unified Process

OpenUP/Basic covers the basics of applying patterns and reference architectures. RUP and RUP plug-ins elaborate on these basics. For example, the J2EE plug-in to RUP describes important J2EE design patterns, while the Service-Oriented plug-in describes patterns that apply to service-oriented architectures.

Additional Reading

The following classic work popularized design patterns:

Erich Gamma et al. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995.

There are many books on patterns. The following address patterns of architectural scope:

F. Buschmann et al. Pattern-Oriented Software Architecture: A System of Patterns. John Wiley & Sons, 1996.

Douglas Schmidt, Michael Stal, et al. Pattern-Oriented Software Architecture, Volume 2: Patterns for Concurrent and Networked Objects. John Wiley & Sons, 2000.

Michael Kircher and Prashant Jain. Pattern-Oriented Software Architecture, Patterns for Resource Management (Wiley Software Patterns Series). John Wiley & Sons, 2004.

Martin Fowler. Patterns of Enterprise Application Architecture. Addison-Wesley, 2003.

Gregor Hohpe and Bobby Woolf. Enterprise Integration Patterns. Addison-Wesley, 2004.

For guidance on improving existing code with patterns, see the following:

Joshua Kerievsky. Refactoring to Patterns. Addison-Wesley, 2005.

For guidance on applying patterns and UML in the context of an overall software development process, see the following:

Craig Larman. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development. Prentice Hall, 2005.



Agility and Discipline Made Easy(c) Practices from OpenUP and RUP
Agility and Discipline Made Easy: Practices from OpenUP and RUP
ISBN: 0321321308
EAN: 2147483647
Year: 2006
Pages: 98

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