Many a time when you design or implement solutions for a software system, you get the feeling of dij` vu. Even though this may sound too extreme, it is undeniable that parts of different software systems may share similar aspects. With software design going the assembly line way, reusability has become an important criterion in software design
A pattern is a commonly occurring reusable piece in software system that provides a certain set of functionality. The identification of a pattern is also based on the context in which it is used. So, using patterns in modeling of systems helps in keeping design standardized and more importantly, minimizes the reinventing of the wheel in the system design. This article is all about patterns; especially design patterns.
Ok so you might ask how does a pattern relate to the UML? The patterns that we encounter need to be captured and documented in a sufficiently descriptive manner so that they can be referred for future use. UML provides the perfect tools to do just this. The class diagram in UML can be used to capture the patterns identified in a system. In addition, UML has a sufficiently extensive and expressive vocabulary to capture the details of patterns.
Over the previous articles in this series, we explored the different UML diagrams and learned how to model each of the diagrams in a case study application. Building on this background we will see how to leverage the usefulness of well-known patterns to make application designing a lot easier.
To sum up, a pattern should have the following characteristics
- Useful solution
Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides first popularized the concept of patterns with their book on design patterns. These authors came to be known as the “Gang Of Four” or GOF. The name stuck ever since and the patterns catalog that they documented is known as the GOF patterns catalog.
Since a system is made up of static as well as dynamic elements, you will find patterns that can be used for either of these types. For static elements of a system especially the architecture and design of a system, there are design patterns – the focus of this article. The dynamic aspects of a system are abstracted and captured as process patterns. But patterns are not limited to this. Patterns can be abstracted for the implementation aspects of a system as well.
Based on how they are to be used, patterns are primarily categorized as:
Creational patterns define mechanisms for instantiating objects. The implementation of the creational pattern is responsible for managing the lifecycle of the instantiated object. A few examples of Creational design patterns are listed below.
One of the easily recognized and frequently used design patterns is the Factory pattern. If you have designed any object that is responsible for creating and maintaining the lifecycle of another object, you have used the Factory pattern. Obtaining a database connection in your application using a connection manager or connection factory object is a good example of the Factory pattern.
Figure 1. Factory pattern
A singleton is another example of a factory pattern. What makes the Singleton pattern unique is that one and only one instance of the object can exist irrespective of the number of times the object is instantiated. The most common use of a Singleton pattern is for server applications like a Java based Remote Method Invocation (RMI) server application.
Figure 2. Singleton pattern
The composition of objects and their organization to obtain new and varied functionality is the underlying basis of Structural patterns. A few examples of Structural design patterns are listed below.
In the Adapter pattern, an object provides an implementation of an interface used by other objects in a consistent way. The adapter object wraps different disparate implementations of the interface and presents a unified interface for other objects to access. A good example of this is a database driver like an ODBC (Open Database Connectivity) or JDBC (Java Database Connectivity) driver that wraps the custom database accessing implementation for different databases and yet, presents a consistent interface that is a published and standardized API.
Figure 3. Adapter pattern
A Proxy pattern constitutes use of proxy objects during object interaction. A proxy object acts as a substitute for the actual object. Use of proxy objects is prevalent in remote object interaction protocols. As an example, when an object needs to interact with a remote object, say across a network, the most preferred way of encapsulating and hiding the interaction mechanism is by using a proxy object that mediates communication between the requesting object and the remote object.
Figure 4. Proxy pattern
Interaction between different objects is specifically covered by Behavioral patterns. Some examples of behavioral patterns are given below.
The Command pattern is commonly used for gathering requests from client objects and packaging them into a single object for processing. The Command pattern allows for having well defined command interfaces that are implemented by the object that provides the processing for the client requests packaged as commands.
Figure 5. Command pattern
A simple mechanism to traverse and access a list of objects is defined by the Iterator pattern. The Iterator pattern encapsulates the internal implementation of the list while providing a standardized mechanism for list traversal.
Figure 6. Iterator pattern
UML Tools and Design Patterns
Quite a few UML tools in the market support design patterns. Many such tools have a pre-built catalog of well-known design patterns. With this using Creational, Structural or Behavioral design patterns in your system is a breeze! The design patterns can be easily pulled in into your design as templates and then customized for your application design. Some examples of UML tools that support design patterns are Rational Rose and Together ControlCenter.
Applying Design Patterns
Now let us take a look at the Courseware Management System and see if we can identify any possible design patterns. Our class diagram of the Courseware Management System only captured the primary entities in the system. If we go about refining and elaborating the class diagram we will come across a few design patterns.
One of the simplest design patterns that we can identify is the Behavioral pattern. The methods in the classes of the Courseware Management System that return multiple results, like the viewCourses() method of the CourseAdministrator class, will use the Iterator pattern to iterate through the list of courses in the system.
We can identify atleast a couple of examples of Structural patterns. For instance, one component that is not shown in the class diagram is a database accessing element that will provide database accessing services for all the classes in the class diagram that need to interact with a data store. All database interactions to retrieve or update information required for their business functionality can be routed through this database access element, which acts as a bridge between the database and the application components. This is an example of the Bridge design pattern.
If we take things to the implementation level, we can define a common interface object that is used to package data passed between the different classes. This would help to keep the interface between interacting classes the same while allowing for flexibility in implementation. Such a common interface object is a good example of the ValueObject pattern that falls under the category of Structural design pattern.
The above examples in the Courseware Management System show how design patterns are an integral part of well-designed systems and you should always keep the use of design patterns in mind when you model software systems.
Using patterns does not mean that you have are restricted to using only well defined standard design patterns. If you have pieces in a software system of your organization that you think are reusable and can be applied to other software systems that you may build in future, it would be well worth the effort to capture such specific design patterns using a UML tool for future use. Examples of such organization specific patterns are authentication and authorization mechanisms, approval chains, workflow/process patterns etc that you have put in effort to design and can be easily reused in other systems.
As we saw in this article, design patterns are an extremely useful mechanism to document and learn about common reusable design approaches. Using design patterns you can reduce the designing time for building software systems and more importantly ensure that your system is consistent and stable in terms of architecture and design. The UML class diagrams provide an easy way to capture and document Design patterns. In the next and concluding article of this series we will discuss the Rational Unified Process and how it applies to the lifecycle of building projects.
About the authors
Mandar S. Chitnis, Lakshmi Ananthamurthy and Pravin S. Tiwari are the co-founders of Novusware inc. They have co-authored the book “Teach Yourself BEA WebLogic Server 7.0 in 21 Days” (SAMS publishing Oct 2002) based on the recently launched WebLogic Server 7.0 by BEA Systems inc. For any questions or queries regarding the article contents, please contact [email protected]