Design Patterns for Reuse
Software Maintenance and Generation
Dec. 10, 1996
Abstract: Finding ways to reuse software is critical to software development. The problems of reducing cost, facilitating maintenance, re-engineering legacy systems, complexity control, and constructing maintainable software can be addressed with several new approaches, design patterns being one of them. Given the manner in which programmers gain expertise in their field, patterns are a natural by-product. As an industry, we can learn to develop better software not just by mimicking more experienced software engineers but by taking examples for other disciplines.
The Role of Design Patterns
The role of the design pattern concept is to abstract this imitation activity
and enhance it with a set of rules describing how to accomplish certain tasks.
- EXAMPLE -
Literature on algorithms are a category of general design patterns.
Object-Oriented Design Patterns have a higher spectrum of abstraction
than the example.
The greater the degree of abstraction, the more rewards are afforded the programmer
in terms of framework development and reuse.
"In the preindustrial age, an interdisciplinary scientist was more common than those individuals who specialized in one field. These scientists applied many concepts and techniques from one domain to another. As the domains of science became more and more extensive, scientists also became more specialized. In contemporary times, a scientist usually spends the majority of their effort within the confines of a certain range of topics within a particular domain. The enormous amount of knowledge required to be an active researcher in a particular domain prevents many individuals to become experts in many fields. The scientific community deals with this trend by assembling multi-disciplinary teams to take on complex and diverse tasks. Although these interactions between diverse scientists often have led to the formulation of interesting metaphors, the application of a technique native to one domain to another is often considered a novelty."
It seems strange that interdisplinary cooperation be viewed as a "novelty" when there is so much to gain from this approach. In fact, so much has already been gained. Much of our medical insights came out of military endeavors, chemistry from space explaration, music from mathematics, art from computer science, civil engineering from environmental studies.
Recently several scientists have demonstrated that the use of interdisciplinary study is not only valuable for its metaphors and analogies but also for its application. The most exciting work has been carried out by researchers who have used of DNA and other genetic metaphors to compute the solution of the Hamiltonian Circuit problem and other problems in the domain of NP-Complete Complexity. By representing vertices by nucleotide sequences and binding them together to form the graph, the resulting DNA molecules encode the solution to the problem. By utilizing the enormous parallelism of the chemical reactions, this method determines a solution faster than a typical supercomputer by a thousandfold. This is a very valuable result as many other NP Hard problems such as optimal path scheduling and boolean logic satisfaction can be reduced to the Hamiltonian Path Problem. These interdisciplinary approaches may shed light onto the solutions of other difficult problems. These techniques all fall in the realm of Evolutionary Algorithms and Strategies which correlate software development and application with biological evolutionary principles.
The OO software engineering community has borrowed much from the discipline of architecture in an attempt to help improve the software building process. Taking most of their ideas from the works of the modern architect Christopher Alexander, they attempt to make software engineering more like other design-intensive professions with histories that are proven to be successful. One of the most influential pieces of work to software engineers are his books that describe the rationale, methods and details of patterns. Timeless Way of Building and A Pattern Language describe patterns and their applications to building objects ranging across a large level of granularity. "Architectures can't be made, but only generated, indirectly , by the ordinary actions of the people, just as a flower cannot be made but only generated from the seed," quoted from Alexander. Within the context of software development, patterns can be considered as representing recurring structural or behavioral solutions in software. These solutions can be found in almost any context imaginable as The vocabulary that describes the pattern and its related components (name, context, tradeoffs) and rules that govern its usage are essential both in the classification of design patterns and the application. By classifying these components and the nature (structural or behavioral) of the solution, software engineers can categorize patterns.
"Patterns can be collected in a structured manner to make up what Alexander calls a pattern language. The patterns are related by building on each other in order to transform needs and constraints into an architecture. In the Alexandrian sense, each pattern is applicable to a particular context and the product of this application is a new context. The next pattern in the language must be applicable to this new context. This implies that there is a strict ordering of patterns. Since OO software is built using more iterative approaches, the application of pattern languages have been modified to reflect the iterative nature."
An architectural framework is a reusable design of a program or a part of program's implementation expressed as a set of classes. It is often domain specific and it can be considered an object of domain-level reuse. A framework consists of classes that collaborate and detail instructions on how to use and modify these classes. Hence, they consist of not just code so they are more abstract than most software, making them more difficult to document. A framework can be decomposed into components called design patterns. These design patterns are often domain independent and provide solutions to a number of contexts. The collection of design patterns can be documented within the domain of a pattern language.
Design patterns express object-oriented
- Identifying, naming, and abstracting common themes in OOD.
- Provide a common vocabulary for design
- Reduce complexity
- Constitute a base of experience for building reusable software
- Act as building blocks
Design Pattern Goals:
- Motivate developers to go beyond concrete objects.
- Assist in naming classes.
- Effective way to teach OOD.
- Highly effective reuse mechanism.
- Reduce effort required to learn a class library
Alexander defines "fit" as: "mutual acceptibilty between context - that part of the world that we have no control - and form - the part over which we do control." So that, in deciding which of two patterns would be more suitable for a given context, one could compare each of their fittings in terms of extendibility, reusability or other criteria. This raises concern when we consider the level of complexity and is involved in developing software projects in todays world.
Brook's said that, "the complexity of software is an essential property, not an accidental one." He realized that complexity is a part of the nature of software development rather than just being constructed by the ineffectiveness of human effort. Software engineers have been traditionally dealing with this complexity by adding layers of interfaces that shield developers from the internal mechanics (usually more complicated) of the system (a.k.a. encapsulation). As projects become larger and larger in terms of developers and code sizes, it is believed that organizational chaos tends to take effect. The complexity of the entire software process increases to levels where production is hampered. Other disciplines must also deal with the complexity in nature. How do they cope with it? And, what lessons can software engineers gain by mapping interdiscipliary struggles? In nature, we see "pattern survival" where those patterns that help to propagate a species are genetically passed on.
The use of patterns unlike any other methods dealing with design. Design
patterns provide complexity reduction by bringing a vocabulary to the process
of designing process as well as helping designers use the proper tools
(patterns) for a given context. In the context of the implementation, design
patterns tend to promote the use of components over inheritance based relationships.
This seems to support reusability while decreasing complexity as it aligns
with modern complexity reduction approaches. These approaches place more
emphasis on the relations of objects whereas traditional approaches used
ontological schemes which emphasized objects and their properties. Many
view the application of patterns to the software development process as
a considerable shift in thinking. By bringing patterns to a much higher
granularity, we can utilize them to help reduce and control complexity
as they do in the lower granularity of design patterns.
Patterns may also be useful in reducing the complexity in maintenance which many view as closely coupled to program comprehension and testing. When someone is put into the position where they inherit OO code, there is little in terms of CASE tool support that could help them understand this new code. It is well known that OO promises easier maintenance due to better encapsulation and less ripple effect, but that only covers only a small portion of maintenance issue. Comprehension is also important in OO technology because it helps determine whether developers find reusable code to be usable or not. Users of reusable code must be able to understand how to use it and be able to modify it to meet their needs for this functionality to be inherant to software.
System comprehension generally starts with high-level understanding and then given time it develops into a more detailed system design and system understanding. Class hierarchy and system browser tools can indicate the inheritance and component relations between classes. These are useful tools that are available for most OO languages. But, OO environments are lacking non-static tools dealing with dynamic binding and tracing type dependencies. The use of design patterns can greatly enhance the ability to track innovations of methods as well as the chain of inheritance.
Pattern languages are often used to document frameworks. Each pattern should contain as many examples as possible in order to illustrate the context (more so the range of contexts that are suitable for the pattern) to facilitate its use within a framework.
There are several pattern languages developed for frameworks. HotDraw is a structured drawing editor framework. Conduits+ is a framework for network protocol software (generalized communication framework for implementing the signalling system of multi-protocol ATM access switch). Other frameworks include ET++ and MacApp.
Not only do patterns make suitable documentation tools for frameworks, they also may make suitable documentation tools for any reusable components including class libraries. Here we see the a reduction in complexity in comprehension with respect to reusability.
In general, design patterns reduce complexity in real-life situation. Look at these example of human design patterns:
behavior pattern (sequence of actions):
- for manuvering a vehicle with manual transmission.
- for how to eat a meal
- for coordinating fashion
- for interacting (e.g. greeting) with other people
So, how can the concept of design patterns be applied to software development in an object-oriented sense?
Here are some examples (taken from "Design Patterns for Object-Oriented
Development" by Wolfgang Pree):
The purpose of this pattern is to put instance variable of a class ITEM into a separate class ItemDescriptor. ITEM instances refer to an instance of ItemDescriptor. If several Item objects refer to one ItemDesriptor object, changes to the ItemDescriptor object will affect all corresponding Item objects.
This design pattern can be used "when some attribute values may apply to more than one object in a class. The notation used in the graphical representation of the Item pattern is from Coad (1992). The gray arrow expresses that a message is sent from Item instances to their corresponding ItemDescriptor instance. the connections between the graphic representation in both diagrams express that any number of Item object refer to exactly one ItemDescriptor object. The details of how the association is established is "abstracted" out.
The purpose of this pattern can be described by he analogy "A PLAYER object... wears different hats, playing one or more Roles." An instance of the Player class refers to one Role object at a time. The Role object may be changed. Class Role constitutes a typical example of an abstract class. Since the description of the pattern is general, no hints can be given as to whichbehavior can be defined in class Role. the design pattern desription only mentions that the two instance variable timeWhenRoleStarts and timeWhenRoleEnds are common attributes of the various roles. Additional common behavior is also defined in class Role. particular instance varialbe of role can be referred to by player objects dynamically by type-checking the instance variable of role.
Coad categorizes Design Patterns into:
The design pattern concept can be viewed as an abstraction of the imitation activity we see in programming since imitation involves noticing the pattern of some other code and adapting it to the program at hand. Design patterns constitute a set of rules describing how to accomplish certain tasks in the the realm of software development. In the same sense, books on algorithms, cook books, can also be viewed as general design patterns. Framework cookbooks are being developed. These cookbooks use design patterns as their recipes to describe typical ways to use a particular framework. They desribe the design of a framework and its individual class without revealing implementation details making the framework more adaptable. They help to understand the implementation details of a framework just as a roadmap provides understanding of your physical environment.
Simple Stub Generator Tool
Automatic generation of patterns to code with a GUI similar to visual programming.
1) Expert system providing decision making support based on a description of the context. Heuristics could aid the choosing among alternative patterns (without claiming quality for the actions suggested).
2)In a tutorial-like manner, expert systems support users with tasks help. These systems diminish their interaction as skills are learned. This training facility can be a nice instructional tool for design.
3)A similar tool but geared for easing into the comprehending a framework.
Reverse Architecture Support
Rapid Prototyping Environment with Patterns and Component Library.
Although studies have shown that it is a myth that users mistake a prototype for the real product, a problem still exists in the phenomena that users often change their requirements and have a tendency of adding more and more features. The use of patterns in prototypes allow for easier flexibility, extendibility and adaptability which turns into better response times to implement user requests. Also, prototyping using patterns can help designers decide which patterns are most suitable for a task.
"Lighting the way in dark times."