Table of contents
Uses
Formal definition
Use is a relation :
holding when requires an instance for its correct functioning — cannot supply its function correctly unless supplies its function correctly.
One invariant. iff:
- Necessary ingredient: is an active ingredient of ’s correct operation, not merely a passive reference. Correct functioning of depends on correct functioning of : if is absent, faulty, or incorrectly specified, will fail to supply its function. Use is transitive in the dependency-correctness sense but not necessarily in the structural sense: if uses and uses , then ’s correctness depends (transitively) on ’s correctness, even if does not directly reference .
Use is the coarsest of the resource relations: implies ; implies ; implies ; does not imply (creating does not require to already function). The converse does not hold: use does not specify access mode or lifecycle impact.
Parnas: the USES relation and modular decomposition
David L. Parnas (Designing Software for Ease of Extension and Contraction, IEEE Transactions on Software Engineering, 1979): the USES relation on program modules defines the dependency partial order that structures decomposable systems. “ USES ” means: the correct functioning of depends on the availability of a correct implementation of .
The USES relation determines level structure: the levels of a system are defined by the longest USES-chain below each module. Level-0 modules use no other modules; level- modules use only modules at levels below . A well-structured system has a shallow USES hierarchy — few levels — enabling incremental delivery (levels 0, 1, … each independently testable).
Parnas’s key insight: the USES relation is an architectural decision, not a derivable property of code. Choosing which modules USE which others determines the system’s extension/contraction properties. A module that USEs few others can be replaced without cascading changes; a module that is USED by few others can be removed without cascading failures.
The distinction from the IS-COMPONENT-OF relation: IS-COMPONENT-OF describes physical containment; USES describes functional dependency. A module may be a component of a subsystem without using it, and may use a module outside its subsystem.
Harary and Liskov: dependency graphs and data abstraction
Frank Harary (Graph Theory, 1969): the USES relation defines a directed graph on modules. The strongly connected components of this graph identify circular dependencies — modules that mutually USE each other and cannot be separately tested or deployed. A good modular design has a directed acyclic graph (DAG) as its USES structure: the absence of cycles ensures that each module can be understood independently of those that use it.
Barbara Liskov and John Guttag (Abstraction and Specification in Program Development, 1986): in abstract data type (ADT) design, a type uses type when the operations of ’s interface are specified in terms of ’s values or operations. The abstraction function (mapping concrete to abstract) relies on the correct functioning of all types the abstract type uses. An ADT’s specification is correct only relative to the specifications of the types it uses.
W3C PROV: provenance and use
The W3C PROV Data Model (Moreau, Missier, et al., 2013): the relation prov:used links an Activity to an Entity it used. An activity prov:used an entity means was used in the execution of — ’s value was consumed or read as part of ’s operation. This is the provenance-graph counterpart of the USES relation: PROV tracks which entities (resources) were used by which activities (operations), enabling reconstruction of causal history.
The PROV-DM usage model: a usage record asserts that activity used entity at time . Multiple usages of the same entity by different activities are separately recorded. The usage graph is the provenance trace of a computation; reconstructing it from the PROV-DM records recovers the USES relation of the executed system.
UML dependency and component models
The UML dependency arrow (, «use» stereotype): component depends on component — a change to ’s interface or behavior may require changes to . The UML «use» dependency is the notational counterpart of Parnas’s USES relation at the model level. Required interfaces on UML components make the dependency explicit: a component exposes a required interface slot that names the types it needs to use.
OSGi and service registries: in component frameworks (OSGi, Spring), a component declares its service dependencies — the types it requires for injection. A component is only activated when all its declared dependencies are available. Use-as-dependency is the architectural primitive of injection frameworks: the dependency injection container resolves the USES relation at runtime by wiring providers to consumers.
Open questions
- Whether the USES relation has a categorical representation — whether corresponds to being a morphism in a slice category over , or to being in the image of a functor that factors through ’s type, and whether the coarseness of use (subsuming reads, writes, consumes) corresponds to a forgetful functor from the category of typed resource accesses to the underlying dependency category.
- Whether the transitivity of use (correct functioning depends transitively on all transitive dependencies) is compatible with abstraction barriers — whether hiding the USES relation behind an abstract interface (so that users of need not know that uses ) formally corresponds to a factoring of the correctness dependency through the abstract specification of , shielding the transitivity from external observers.