|
|
|
|
reuse and component management |
| |
| |
|
| |
overview
'Reuse' is a misleading term. Cutting a chunk out of an existing program
and adapting it to fit in another doesn't gain us much. Most of the work
done on any software is done after its first installation; so we only gain
substantial benefit if we use the same component in more than one
software product. That way, enhancements and fixes done on it will benefit
all the products in which it is used. This is what Component Based
Development is about: the idea that we will develop a library of components
that will be used, in different combinations, in more than one software
product.
But CBD isn't the only kind of reuse: the reusable artefacts don't have
to be executable components in the COM or EJB sense. Within a reuse library
we could find frameworks, tools, source code packages, design patterns,
requirements models ...: any piece of work that can be separated and have
limited dependencies on others.
reuse management
Managing reuse starts with separating Products which you deliver to your
customers, from Assets which you use to generate the Products. The library
has to be resourced separately from the products: it should be treated
as a capital asset, and effort should be spent on enhancing it. Planning
and organising the library is not a clerical job: it determines what products
can be produced in the future, and is the job of the Chief Architect.
There are three important distinct views of the library:
-
The repository: the space in which the Assets are stored, with suitable
search facilities. Some repositories are actual databases. Others are tangible
only as catalogues of items available from diverse distributed sources.
Or it may be that every Product includes a complete copy of the whole lot,
configured differently for each customer.
-
The technical framework: the means whereby the Assets are combined
to make Products. For example, they might be executable COM components
coupled via a registry; or they might be C++ classes that have to be linked
together; perhaps they all 'plug in' to a central application. Once linked,
they have to interact coherently, so there will be some protocol definitions
that they all adhere to. Some assets, such as design patterns, will have
only an informal framework.
There may be several such frameworks in one library.
-
The composition tool. A coherent library of components can be thought
of as a language, and your Products are statements of the language. For
example your library might form a kit of basic parts from which a variety
of air traffic control systems can be constructed. To satisfy a particular
customer, you choose and configure parts from the kit, and set their parameters,
just as you write a statement in a formal language. The kit forms a language
for describing ATC solutions.
It's optional how literally you take this view. However, there are
many cases in which it is useful to construct an actual language --- whether
textual or graphical --- to help build products. As examples, think of
workflow systems; and visual editors for GUIs.
Populating the library
There are two sensible approaches to deciding what goes in the library.
-
Product Line Architecture (or 'Family Planning'). The aim is to
build a family of products, and we know in advance what the main variants
will be (rather like car designers). We therefore design a framework in
which the variants can be created by substituting one component for another.
This works well where there is already lots of experience in the target
field, and we know what variants we're going to have.
-
Evolution. After designing two specific products, we realise that
they have a lot in common; maybe one was done by adaptation of the other.
We do some extra work to see how a common framework with some variable
parts could have satisfied both customers. The third product is delivered
using the new assets; we maybe retro-fit to the first products so that
they are easier to maintain in future. As each new order appears, there
are inevitably refactorings that we need to do to the assets, but these
gradually drop to a steady level.
Here are some faux pas not implicated in either of these strategies:
-
No adaptation. Components taken from the library should go into
the products without adaptation. As soon as you change them, they've got
a maintenance track of their own and you've lost much of the benefit of
reuse. If a product designer thinks a component does almost but not quite
what's required, a change proposal should be fed back to the library. However,
it is accepted that usually, part of the design of each product will involve
some 'glue' and some enhancement of library assets.
-
You ain't gonna need it. We don't put things in the library just
because they might possibly be nice. Nor do we over-generalise the
assets, parameterising everything in sight. They will slow performance,
introduce more bugs, and take your time up. We generalise only as much
as:
-
we can see a definite need for, in immediately forseeable products; or
-
it doesn't cost too much and is just part of good separation of concerns.
Generalisation of material to go in a library is hard; and many cycles
of improvement should be allowed for. It isn't worth generalising a piece
of code into a component, or a design idea into a pattern, unless you think
it will be used at least five times.
Maintaining
the library
The maintenance of the library, whatever form it takes ('component kit'
in this slide), needs to be resourced separately from any product, since
no individual product project has the motivation to devote time to the
benefit of other products.
One of the benefits of any form of 'reuse' is that we can deliver products
rapidly: they are assembled from existing components. This means earlier
feedback from the users, more opportunity to adjust what has been delivered
to suit their shifting requirements. A corollary is that less 'ceremony'
is necessary or appopriate: a less long-drawn out design process, less
documentation, less thrashing out of detailed requirements before moving.
(We can find out the requirements by putting a working prototype in front
of them, just as fast as we could write the detailed spec by paper-heavy
methods.) Typically, this rapid-feedback process is done incrementally,
delivering [prototypes of] the central features first. (RUP, DSDM, eXtreme
Programming are examples of this style.)
The same relationship exists between the product-builders and the component
designers. The big difference is that more ceremony must be applied to
the design of assets. A reusable asset will be used more (one hopes), so
the economics makes sense. But a component has to be designed without knowing
exactly which other components it will be coupled to, so specifying its
behaviour, and specifying what it expects of others, is important; test
harnesses should be devised as part of the component package, so that component
builders can easily make sure a configuration is working properly.
One of the component designers' main inputs will be material that was
initially designed for one product, and has been identified as worth generalising.
(In fact, its designer should also take part in the generalisation -- the
figures here represent roles rather than people.) Generalisation
is not an easy task. Several cycles of subsequent enhancement should be
expected.
What's in an Asset?
Library assets include:
-
standards and guidelines
-
patterns
-
modelling frameworks
-
software frameworks
-
source code packages (dangerous! encourages adaptation)
-
executable components
-
interface and protocol definitions
-
common domain model on which other models are built
-
tools, platforms, infrastructure
Each asset should have:
-
controlled name, version and variants -- no changes after publication
-
controlled compatibility relationship to previous versions
-
defined and not too many dependencies on other assets
-
catalogue entry with useful search terms (so that designers can find it)
-
documentation for users --- succinct but sufficient, particularly in respect
of how to specialise or parameterise it
-
documentation for maintainers --- ditto
-
robust interface: few and documented assumptions about the characteristics
of whatever it might be plugged into or used in conjunction with
-
test harnesses or built-in checking (for software, and for interface
definitions) --- so that product builders can easily check that the configuration
they build is working properly.
Robustness and verification are one of the biggest benefits in reuse,
and also one of the biggest challenges. They're a benefit because a component
that has been used in many contexts is very likely to work properly; they're
a challenge because, when you design a component, you don't know what other
components it will be working alongside (in contrast to merely modular
development). A component's designer therefore has to be extra careful
that it will work in all the situations allowed by the documentation ---
even in contexts not dreamed of when it was designed. This requires careful
verification, and is one of the reasons for the 'high ceremony' of component
design.
Product Line
Design
The two separate development loops mentioned above take care only of the
Evolutionary approach to library planning. The Product Line aspect -- in
practice, all libraries have some mixture of the two -- needs to be dealt
with by a longer feedback path that looks at shifts in the product market.
It plans what components should be designed, to enable construction of
the products that will be in future demand.
The coherent design of the library contents as a kit from which a family
of products can be designed is called 'Product Line Architecture' or 'Component
Kit Architecture'. Again, it needs to be a separately resourced activity.
In practice, there aren't always just two separate layers, components
and products. Within a small product, there may be several assets used
in many places in the product, which may have several variants. The product
may itself be part of a larger family and draw on a larger common library.
Elements in that library may themselves be built from a more basic kit.
So the picture in this slide is fractal: it can be interpreted at many
different scales, and each of the activities can itself be composed of
smaller such loops.
Reuse Teams
One successful organisation of reuse involves a reuse team, many of whose
members are seconded to product teams. These people take care to think
about how the assets can be used within their products; and think about
how requirements can be fed back to the asset library, and what locally-devised
material might be generalised for the library.
There is also an Architectural staff attached to the library. Their
roles include: a clerk to keep track of the contents; framework and technological
underpinnings experts with a keen understanding of the mechanics of specialisation
and composition; an Architect who coordinates overall about what should
be in the library (including designers' guidelines and patterns, not just
software components); and a market analyst who understands the requirements
on the product family as a whole (takes care of that outer feedback loop).
Some folk are particularly good at the lower or higher-ceremony styles
of work, and some are better at relating to end-users. (The product designers
should get to see a lot of the end-users.) The rest should be moved occasionally.
When something in a product is identified as good for generalisation, move
its designer onto the reuse team to give them space to make a good robust
component of it.
complete solutions for component design
(consultancy, courses, workshops, mentoring, seminars, development)
|
|
|
| |
|
|
email
us or tel UK:
01625 850 839 international:  +44 1625
850 839 |
|
|
|
|