- Evolutionary prototyping
Modern replacement for the waterfall model of development. Rather than
designing, implementing, and testing the system all in one go, design an
incomplete but highly flexible system and then iterate implementation,
testing, and re-design. Each pass through the cycle should entail small
changes as new features are added, until finally all requirements are met.
Thanks to good design, the program easily adapts to changing requirements,
before and after delivery.
- High probability that a change in one module will require change in
other modules. Essentially the opposite of modularity. Ince cites coupling as a major indicator of maintenance
cost, and therefore a major hinderance to evolutionary prototyping. In
"Notes on the Synthesis of Form", building architect Christopher Alexander,
who originated the pattern form, first identified module independence as a
requirement of a good design.
A program part which is expected to change, due to hardware/software
reconfiguration, changing user requirements, new languages, marketing
demands, etc. A function argument or global constant is a variability, as
is, to some degree, a well-structured loop which allows editing its
endpoints. Documenting the latter kind of variability is one of the
challenges of modern software design.
Identifying variabilities is an important part of
requirements analysis. Missing a variability can be expensive, as well as
anticipating a false variability. Variabilities lay the groundwork for
Marshall Cline has an excellent discussion of patterns and variabilities
(so-called "hinges") in Communications of the ACM, Oct'96.
- Design pattern
A bite-sized chunk of engineering knowledge. It gives a name to a
relationship between objects which is used time and time again by software
professionals. Patterns also include a rationale for their context of
applicability, and situate themselves among the other known patterns.
Ideally, all programs would be describable as a collection of standard
design patterns. See the Patterns
Home Page for a more complete definition. Also see Douglas
Schmidt's allegory. Communications of the ACM, Oct'96,
has another good introduction, available here.
- Observer pattern
Define a one-to-many dependency between objects so that when one object
changes state, all its dependents are notified and updated automatically.
- Document/View paradigm in ET++ and MFC, Model/View/Controller in Smalltalk
- Event notification between objects in Smalltalk, CORBA, and ActiveX
- Graphical constraints in Inventor
- Chain of Responsibility pattern
Avoid coupling the sender of a request to its receiver by giving more than
one object a chance to handle the request. Chain the receiving objects and
pass the request along the chain until an object handles it.
- Format conversion, e.g. image reading in Tk
- Event handling in X and Windows
- "Shadow" inheritance in Python
- Variable scope in MatLab, Tcl, and Smalltalk
- Replication (Backup pattern in PLoP'95)
- Interpreter pattern
Given a language, define a representation for its grammar along with an
interpreter that uses the representation to interpret sentences in the
- Compilation in Python
- Scene graph in Inventor and VRML
- Execution in SCM
- Decorator pattern
Attach additional responsibilities to an object dynamically. Decorators
provide a flexible alternative to subclassing for extended functionality.
- Process filters in communication stacks and ImageVision
- Caching requests in ImageVision
- Graphical embellishment and clipping in ET++
- Restricting access to parts of an object, or disabling an interface widget
- Echoing requests for debugging, as in InterViews' DebuggingGlyph
- Simulating lists, e.g. attribute lists
- Adaptor pattern
Convert the interface of a class into another interface clients
expect. Adapter lets classes work together that couldn't otherwise because
of incompatible interfaces.
- Strategy pattern
Define a family of algorithms, encapsulate each one, and make them
interchangeable. Strategy lets the algorithms vary independently from
clients that use it.
A Decorator lets you change the skin of an object; a Strategy
lets you change the guts.
- Proxy pattern
Provide a surrogate or placeholder for another object to control access to
- Client stub in RPC
- Local interface to a distributed object
- Smart pointers for reference counting
- "Promise" in lazy evaluation
- Reflection pattern
Provide meta-level objects which describe the ground-level objects in the
software's functional core and user interface. Changes in meta-level
objects affect subsequent behavior of the ground-level objects.
Also see the Metamorphosis pattern in "Evolution, Architecture, and
- Meta Object Protocol in CLOS, mirrors in Self,
__dict__ in Python
- Field access and initialization in Inventor
- Streaming, copying, and inspecting in ET++
- IDLs and ODLs in RPC, CORBA, and COM
- Garbage collection in Smalltalk
- Abstract Factory pattern
Provides an interface for creating families of related or dependent objects
without specifying their concrete classes.
Eliminates coupling caused by global names.
- Allowing frameworks to create instances of your objects, e.g.
Document and View objects in MFC
- Unstreaming objects in ET++, CORBA, and COM
- Command pattern
Encapsulate a request as an object, thereby letting you parameterize
clients with different requests, queue or log requests, and support
- Undo and redo in ET++ and CommonPoint
- Queued actions, alarms, and conditions
- Transaction logging, recovery, and cloning (cf Builder pattern)
- Atomizer pattern
Read arbitrarily complex object structures from and write them to varying
data structure-based backends. Efficiently store and retrieve objects from
different backends, such as flat files, relational databases, and RPC
- Object streaming in ET++
- CORBA externalization service
- Distributed Shared Memory
Memory shared among several processors. To attain reasonable performance,
processors must cache parts of the memory. This migration and replication
can lead to inconsistent views of the memory, requiring elaborate
consistency protocols for locating and propagating up-to-date
- Object-Oriented Database Management System
- A distributed shared memory based on objects as the unit of
distribution (so-called distributed objects). Objects may exist
in different implementation formats, e.g. in a disk archive, and
transparently switch between formats. The crucial difference between
OODBMS's and Distributed Object Management Systems (DOMS's) is
that OODBMS's use closed, proprietary formats. DOMS's are intended to be
open and interoperable with multiple languages, even non-object-oriented
ones, as well as other DOMS's. Thus the existence of DOM standards like
- Component software
- Applications assembled at run-time from independently engineered and
possibly distributed parts. For example, combining text editor,
spreadsheet, file browser, and graphing components to form an integrated
desktop publishing system. A compound document is one kind of component
- Compound document
- A dynamic container of components, with both a visual and persistent
representation. The visual container is essentially a geometry manager,
like the Tk packer. The persistent container is a "filesystem within a
file." Compound documents encompass enough functionality to replace
stand-alone applications. For example, a compound document can contain
text with embedded spreadsheet, graph, and drawing components, each with
their own native functionality.
- Uniform data transfer
- Communicating data between components which may know nothing about each
other. Drag-and-drop is an example where uniform data transfer is needed.
Current practice is to enclose the data in a special "carrier" object. The
carrier describes which formats are available, e.g. as an icon, as a
floating-point number, in French, or in monochrome. The receiver examines
the formats and picks one it understands. The sender may provide copies of
the data in these other formats, or the carrier may automatically convert
the data into another format.
- Glue languages
- Languages for automating components. In addition to control flow, they
can also handle naming and shared memory for the components. Visual Basic
is an example. Component languages are for writing the components
themselves. Notes from Programming
- Interface Description Language (IDL)
- A convenient way to automatically generate Adaptors and Proxies for
integrating an object into a distributed shared memory. Originally used in
RPC for the automatic generation of marshalling code. An Object
Description Language (ODL) is a convenient way for objects to describe
themselves to other objects. The same language may be used for an IDL and
ODL. Both can be avoided by using implementation languages with Reflection
or by using a small, fixed set of interfaces, as in Plan9 and the Hurd.
- Multiple interfaces
- Providing more than one abstraction boundary for a single object.
For example, a bar graph object may support an interface for visual display
as well as an interface for archival. Also known as viewpoints or
pieces of a split object. Currently popularized in Microsoft's
Component Object Model, the foundation of ActiveX.
- A special kind of class library which aspires to provide a ready-made
architecture for communication and control flow. Frameworks have carefully
designed variabilities which are usually modified by subclassing. The
framework absorbs the main loop so that the added code is event-driven and
highly declarative. Examples: MFC, MacApp, Taligent's CommonPoint, ET++.
Darrel Ince. Software Development: Fashioning the Baroque.
Oxford University Press, Oxford, 1988.
Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.
Design Patterns: Elements of Reusable Object-Oriented
Software. Addison-Wesley, Reading, MA, 1994.
"Software Patterns" in Communications of the ACM,
Robert Orfali, Dan Harkey, Jeri Edwards. The Essential Distributed
Objects Survival Guide. John Wiley & Sons, 1996.
Last modified: Fri Sep 02 17:13:35 GMT 2005