Reuse of concurrent, distributed, persistent, and/or secure components
faces challenges not seen for example in most UI toolkits, data
structure libaries or spell-checker plug-ins. Reasons include:
- Extended senses of correctness
- The need for safety, liveness,
fault-tolerance, auditability, recovery, and so on make components
more difficult to specify, test, and reason about.
- Large policy spaces
- Each of these aspects introduces
specification and design choices in places where no such choice
exists in simpler systems: Optimistic or pessimistic?, Local or
remote? Synchronous or asynchronous? Persistent or transient? Clear
or encrypted? Support infractructures that accommodate all of the
associated mechanisms create an unwieldy policy jungle. Those that
do not become unusable.
- Architectural constraints
- TO avoid policly clashes, components
cannot be build in isolation, but must observe compatibility
constraints that are often phrased as architectural rules; for
example those concerning locking or flow. These rules are often
sub-optimal, even arbitrary, but must be fervently believed in
anyway by developers.
- Infiltration
- The imposition of architectural constraints
generates a slew of programmer obligations when building or adapting
even the simplest parts. Policies and constraints inevitably alter
nearly every line of code, and resist factoring and
layering[#!lea97!#]. Nearly every successful concurrent,
distributed, persistent, and/or secure system was designed that way
from the outset.
- Compositionality failures
- Many components are safe, live,
recoverable, secure, mobile, and so on, only within particular sets
of contexts, and thus may be composed only within those contexts.
These problems are compounded when more than one of these aspects is
involved. For example, when serializing objects that may engage in
multiple threads.
- Need for abstraction without transparency
- Interfaces and the
like must be abstracted out enough to manage complexity. Yet
implementations cannot afford to be treated as pure black boxes.
Eventually, someone else will need to get behind an abstraction,
often as a result of a policy change or customization. Open source
helps.
- Verticality
- Systems increasingly entail reflective, multilevel design in
which objects at each level manipulate, manage, and coordinate
lower-level ground objects as resources. Thread-objects
interpret passive objects. Distributed server-objects pass around
informational resources. Database-objects manage states of ground objects.
Builder-objects create functional objects for later deployment.