Software architects must be motivated individuals who have the desire to
confront the challenges of technical leadership in a software development effort.
However, motivation is not enough. A software architect must be equipped with the
intellectual tools to concretely realize in software an architectural vision.
Basic training will cover the fundamental concepts of software technology,
which provide a foundation for software architecture. Software technology has evolved
through many trends and alternatives for software development. Currently, mainstream
software practice has evolved from procedural software to object orientation.
In corporate development, most new-start projects
are adopting object orientation because it is supported by the majority of commercial
development environments. As we will discuss, object orientation has a very weak notion
of software architecture, which leads to serious shortcomings. The emerging trend of
component orientation is replacing old approaches with strong elements of architectural
design.
Software architects must be able to articulate these development paradigms clearly, along
with appropriate uses of enabling technologies. In any given project, an eclectic mixture
of development paradigms (including relational database management) can be useful to
achieve the best results.
Software Paradigms
We will cover the fundamental concepts of software technology, which provide a foundation for software architecture.
Software technology has evolved through many trends and alternatives for software development.
Currently, mainstream software practice has evolved from procedural software to object orientation.
In corporate development, most new-start projects are adopting object orientation because it is supported by the majority of commercial development environments.
As we will discuss, however, object orientation has a very weak notion of software architecture, which leads to serious shortcomings.
The emerging trend of component orientation is replacing old approaches with strong elements of architectural design.
Today, most organizations will find their technology skill base engaged in one of the three major paradigms: procedural, object oriented, or component oriented.
Where you are today is highly specific to your organization and your staff skills. Procedural and object paradigms are closely tied to programming-language choice,
but you will find that component orientation is different in that it is more closely associated with the selection of an infrastructure.
Procedural programming languages include FORTRAN, COBOL, Pascal, BASIC, Delphi, SQL, and others.
In procedural technology, the program comprises the process for executing various methods.
The process is separated from the data in the system, and the process manipulates the data through direct access operations.
This is a direct outcome of the stored-procedure programming systems from which computer technology originates.
When the program and data are separated, there are many potential interdependencies between parts of the program.
If the data representation is modified, there can be substantial impacts on the program in multiple places.
Unfortunately, many systems are built with procedural technology, the dependencies upon these data representations can cause systemwide program errors
and the necessity for line-by-line program review and modification.
Object-Oriented Paradigm
Object-oriented programming languages support the encapsulation of data with accessor code in terms of abstract data types (commonly called classes). In
object-oriented programming languages, the encapsulation capabilities are sufficient for reasonably sized programs. As long as software modules are maintained by individual programmers, encapsulation is sufficiently robust to provide some intrinsic benefits.
However, we shall see that language-specific encapsulation is insufficient to support software reuse and distributed systems.
In object-oriented technology, the basic paradigm is changed to enable a separation of concerns.
The diagram below shows the object-oriented technology paradigm in which the
program is broken up into smaller pieces called objects.
Each object contains some of the data of the system, and the program encapsulates that data. In other words, access to the data is only available through using the program through which it is directly associated. In this way, the system is partitioned into modules which isolate changes. Changes in data representation usually only impact the immediate object which encapsulates that data.
Objects communicate with each other through messages. Messages can have an impact
upon state—in other words, changing the data—but only through the encapsulated
procedures which have an intimate relationship to the local data. For small-scale
programs, the object paradigm is effective in its isolation of change. However, the
paradigm is not perfect for all of its potential uses.
Technology and System Paradigm
When the size of the system is scaled so that many programmers are involved, the
encapsulations have been found to be insufficient to isolate change across systems.
In this case, additional component-oriented infrastructures are needed to provide industrialstrength encapsulations of the data and associated programs.
One example is the interface definition language, which defines object-oriented
interfaces that are sufficiently opaque to support the integration of large-scale distributed systems.
In fact, the encapsulation mechanism, or IDL, is powerful enough to enable the transparent integration of multiple programming languages such
as well as the object-oriented communication across heterogeneous systems which may involve multiple operation systems and protocol stacks.
Object-Oriented Architecture: An Oxymoron
For the majority of practitioners, object orientation is devoid of a software
architecture approach. This is manifested in multiple ways in object-oriented
methods and culture.
Since virtually nothing was written about architecture in the literature, most OO
practitioners had no architecture guidance. There was no reason to consider
architecture important. This has led to great confusion on OO projects, as team
members struggle to manage complexity and scalability with OO methods not
designed to address them.
In general, OO methods involve successive refinement of object models, where
most analysis objects are eventually transformed into programming objects. In
our terminology, we called these approaches model-based methods. The
assumption that each analysis object will inevitably become a programming
object is a major obstacle for OO thinkers to overcome in order to understand
architecture. In architectural models, specification objects represent constraints,
not programming objects. They may or may not be transformed into
programming objects; that is an independent decision of the developer.
OO also opposes architecture in other subtle ways, related to project culture. OO
encourages project teams to be egalitarian (e.g., CRC cards), where all decisions
are democratic. On such a project, there is no architect role, because there is
little separation of decision making between members of the development team.
OO encouraged "bad-is-better" thinking in development, a philosophy which is
virtually the opposite of architectural thinking. Using "bad is better," the
external appearance of a working implementation greatly outweighs any
requirement for maintainable internal structure. In other words, rapid iterative
prototyping, with ruthless disregard for architectural principles, is a normal,
healthy environment for OO development.
The topic of architecture has resurfaced only recently in OO literature, with the
newfound popularity of componentware. Now it is customary to include a token
chapter on architecture in most methodology books, whereas in the heyday of
OO, architecture was virtually taboo. In one sense, componentware is a response
to the shortcomings of OO. Componentware, with its emphasis on larger variable-
grained software modules, is a clear step toward an architectural mindset.
Componentware: The Component Orientation Paradigm
Moving to the next level of software sophistication requires fundamental changes in systems thinking, software processes, and technology utilization. The next major area of technology, componentware (or component orientation), contains key elements of the solution to today's critical software problems.
The componentware approach introduces a set of closely interrelated techniques and technologies. Componentware introduces a sophisticated mindset for generating business results. These componentware elements include:
- Component Infrastructures
- Software Patterns
- Software Architecture
- Component-Based Development
Componentware technologies provide sophisticated approaches to software development that challenge outdated assumptions. Together these elements create a major new technology trend. Componentware represents as fundamental a change in technology as object orientation did in previous generations. We will discuss these componentware technologies after a brief introduction to componentware's unique principles.
Components versus Objects
Componentware can be understood as a reincarnation of object orientation and other
software technologies. Distinguishing componentware from previous generations of
technology are four principles: encapsulation, polymorphism, late binding, and safety.
This list overlaps with object orientation, except that it eliminates the emphasis on inheritance. In component thinking, inheritance is a tightly coupled, white-box
relationship that is unsuitable for most forms of packaging and reuse. Instead,
components reuse functionality by invoking other objects and components instead of
inheriting from them. In component terminology, these invocations are called
delegations.
Componentware utilizes composition for building systems. In composition, we integrate
two or more components to create a larger entity, which could be a new component, a
component framework, or an entire system. Composition is the integration of components.
The combined component acquires joint specifications from the constituent component.
If the components have matching specifications for client calls and services, then they
can interoperate with no extra coding. This is often called plug-and-play integration.
When executed at runtime, this is a form of type casting. With matching client and service interface specifications, the
components can establish a run-time binding to each other and interact seamlessly
through the component infrastructure.
Component Software Patterns
Software patterns comprise a common body of software knowledge which can be applied
across all component infrastructures. The most famous category of software patterns, called design patterns, comprises proven software design ideas
which are reused by developers. Other important categories of patterns include analysis patterns and antipatterns. Analysis patterns define proven ways
of modeling business information that can be directly applied to the modeling of new software systems and databases.
Software patterns are a necessary element of componentware. The development of new,
reusable components requires expert-level quality of design, specification, and
implementation. Proven design solutions are necessary to establish successful component
architectures and frameworks for families of applications. Often, there are too many
variables to take chances on unproven design concepts.
The popularity of software patterns can be explained as a response to the practical
shortcomings of object orientation. Antipatterns explain the common mistakes that
people make when developing object oriented software systems (as well as other types of
systems). Much more is needed than basic object-oriented principles to build successful
systems. Design patterns explain the additional, sophisticated ideas that are required for
effective software designs. Analysis patterns present the sophisticated ideas necessary for
the effective modeling of concepts and data.
It is still commonplace in software development to reinvent design ideas, incurring the
risks and delays of trial-and-error experimentation. If fact, most software methods
encourage reinvention as the normal mode of development. Considering the challenging
forces of requirements change, technology innovation, and distributed computing, we
consider reinvention to be an unnecessary risk in many circumstances. This comment is
especially applicable to the development of components, where the costs of defects and
redesigns can affect multiple systems.
Component Software Architecture
Software architecture concerns the planning and maintenance of system structure from
earliest system concept through development and operations. Good architectures are
stable system structures which can accommodate changes in requirements and
technologies. Good architectures ensure the continuous satisfaction of human needs (i.e.,
quality) throughout system life cycles. Reusable components are examples of good architecture. They support stable interface specifications, which can accommodate
changes due to reuse in many system contexts.
Software architecture plays an important role in component design, specification, and use.
Software architecture provides the design context within which components are designed
and reused. Components have a role in predetermining aspects of software architecture.
For example, a component framework may predefine the architecture of a significant
portion of a system.
One of the most exciting aspects of software architecture for componentware is
supporting distributed project teams. A software architecture comprises a system
specification that enables parallel, independent development of the system or its parts. A
proper software architecture defines computational boundaries (i.e., API) that divide the
system into separate testable subsystems. These subsystems can be outsourced to one or
more distributed project teams.
Component Software Development
Component-based development is software development with a difference. Many process
aspects are reused, such as iterative, incremental development. The primary
componentware difference is the specialization of technical roles. Three key
componentware roles are software architect, component developer, and application
developer. These differ from object-oriented approaches, which promoted notions of allpurpose programmers, committee-based design, and architecture after-the-fact.
A typical leadership team for a project comprises a software architect and a project
manager. The architect works in conjunction with management to make key technical
decisions, those with systemwide impact. The architect is responsible for technical
planning of the system and for communicating these plans with developers. Since the
architect coordinates systemwide design decisions, many other technical decisions are the
responsibility of developers. To be effective, the architect must have the highest levels of
experience and technical training, with outstanding skills in design, specification writing,
and spoken communication.
The best component developers are also the most talented programmers. They design and
program the building blocks from which the application will be constructed. The architect
defines the major boundaries behind which component-based services will be provided.
Reuse of preexisting components is evaluated with respect to an organizational software
repository. For new component requirements, the component developers design and
construct new software, updating the organizational repository. Typically, components
will implement the horizontal functions and lower-level aspects of the system, reducing
the need for application developers to reinvent these capabilities. Component developers
make intensive use of software patterns, applying several overlapping patterns to each
component design and implementation.
Application developers are responsible for integrating components and implementing the
vertical requirements of the system, including user interfaces. They apply preexisting
components to the solution of application-specific problems. Application developers must
communicate with end users having some domain expertise.
The componentware revolution is an exciting opportunity to avoid the inadequacies of
outdated software approaches. Componentware enables you to survive and thrive when
facing the challenges of requirements change and rapid commercial innovation.
Componentware delivers the benefits of software reuse and enables outsourcing to
distributed project teams.