Component specification
Bibliography
• Main bibliography:
– Sommerville: Software Engineering, 10th Edition
• Chapter 16.3 Component Composition
– Ivica Crnkovic, Magnus Larsson (Eds.): Building reliable
component-based systems
• Chapter 2: Specification of Software Components
• Chapter 6: Semantic Integrity in Component Based
Development
• Other readings:
– B.Meyer: Applying Design by Contract
– Mary Shaw, Truth vs Knowledge: The Difference Between What
a Component Does and What We Know It Does
Review: Component models
Components must obey to common conventions or standards !
Only in this way they will be able to connect and communicate to each other
Review: Component Frameworks
Platform Services: allow
components written
according to the model to
Component Component Component communicate; locating,
linking, replacing
components
Component platform (component framework)
Middleware Horizontal Services:
Operating System application-independent
services used by different
components.
Hardware Concurrency, security,
transaction management,
Resource management
Component composition
• Composition involves integrating components with each other and
with the component infrastructure.
• The ways in which components are integrated with this
infrastructure are specific for each component model
• In the discussion of this chapter, we assume that the components to
be subject to composition belong to the same component model,
thus they can be integrated
• Component composition is the process of
assembling the components to create a system.
• Normally you have to write ‘glue code’ to compose components.
Component incompatibility
• When you design components specially for composition,
interfaces are designed to be compatible
• When the components are developed independently for reuse,
interfaces may be incompatible:
• Interface incompatibility (Syntactic incompatibility)
• Semantic incompatibility
• We recall that only components belonging to same component
model are considered (thus integration is physically possible)
Example
• Expression Component – Multiplier Component
• Interface incompatibility: The expression component requires
an operation multiply, while the multiplier component provides
an operation named do_op
• Semantic Incompatibility: The multiplier component implements
the operation by repeated addition, thus it works if the second
number is a positive integer. The expression component needs
to multiply any integers (positive and negative).
Interface incompatibility
• Situations of Interface incompatibility:
– Parameter incompatibility where operations have the same name but
are of different types.
– Operation incompatibility where the names of operations in the
composed interfaces are different.
– Operation incompleteness where the provides interface of one
component is a subset of the requires interface of another
• Interface incompatibility is addressed by writing
adaptors
• Adaptors address the problem of component incompatibility by
reconciling the interfaces of the components that are composed.
• Different types of adaptor may be required depending on the type of
composition.
Semantic incompatibility
• Component composition assumes you can tell from the component
documentation whether the interfaces are compatible
– Semantic compatibility: the meaning of parameters is right
• You have to rely on component documentation to decide if
interfaces that are syntactically compatible are actually compatible.
Component specification
• There should be no difference between:
– What a component does
– What we know it does
• The only way we get to know what a component does is
from its component specification
• Levels of a component specification:
– Syntax: includes specifications on the programming language
level.
– Semantic: functional contracts
– Non-functional: deals with quality of service.
Component specification levels
• Levels of a component specification:
– Syntax: includes specifications on the programming
language level.
– Semantic: functional contracts
– Non-functional: deals with quality of service.
Components and Interfaces
• A component provides:
– The implementation of a set of named interfaces, or types, each
interface being a set of named operations
• The following diagram is a UML metamodel
– This model allows an interface to be implemented by several
different components, and an operation to be part of several
different interfaces
Metamodel of the concepts used in
syntactic specification of software components
Figure 2.1 from [Crnkovic]
Forms of syntactic specification
• All component models use syntactic specification of
interfaces:
– Programming language
– IDL
Example: component SpellChecker
«comp spec» ISpellCheck
SpellChecker ICustomSpellCheck
Implementation as a COM component:
• Uses an IDL
IDL Example
interface ISpellCheck : IUnknown
{
HRESULT check([in] BSTR *word, [out] bool *correct);
};
interface ICustomSpellCheck : IUnknown
{
HRESULT add([in] BSTR *word);
HRESULT remove([in] BSTR *word);
};
library SpellCheckerLib
{
coclass SpellChecker
{
[default] interface ISpellCheck;
interface ICustomSpellCheck;
};
};
Uses of Syntactic Specification
• The primary uses of syntactic specifications are:
– Type checking (static of dynamic) of client code.
– Base for interoperability between independently developed
components and applications.
• Interoperability may be achieved in different ways:
– Binary format for interfaces
– IDL to programming language mappings
• An important aspect of interface specifications is how
they relate to substitution and evolution of components
Substitution
• Substituting a component Y for a component X is said
to be safe if:
– All systems that work with X will also work with Y
• From a syntactic viewpoint, a component can safely be
replaced if:
– The new component implements at least the same interfaces
as the older components, or
– The interface of the new component is a subtype of the
interface of the old component.
Component specification levels
• Levels of a component specification:
– Syntax: includes specifications on the programming
language level.
– Semantics: functional contracts
– Non-functional: deals with quality of service.
Contracts
Contracts for the semantic specification of
components are a kind of Meyer’s Design by
Contract:
“Applying Design by Contract,” B. Meyer, IEEE
Computer, pp. 40-51, October 1992.
Design-by-contract background
• A Client-Server Design
• Server Objects
– Provides services for client objects to use
– The object whose methods are being invoked
• Client Object
– Consumes the services offered by the supplier object
– The object that invokes the methods of the supplier object
• Contract
– A set of benefits and obligations that are mutually agreed upon by the
client and supplier
– In practice, specified by the supplier object
– Clients implicitly accept the contract by using objects of the supplier
class
• Good contracts are always in writing!
Contracts in real life - Example
Contract with a courier delivery service:
Party Obligations Benefits
Provide package of no
Client more than 5 kgs, each Get package delivered to
dimension no more than 2 recipient in 4 hours or less
meters; pay 100 francs
Supplier Deliver package to recipient No need to do deal with
in 4 hours and less deliveries too big, too heavy
or unpaid
Table 1 from [Meyer]
What is a Contract?
• A contract between a client and a supplier protects both sides
– It protects the client by specifying how much should be done to get the
benefit. The client is entitled to receive a certain result.
– It protects the supplier by specifying how little is acceptable. The
supplier must not be liable for failing to carry out tasks outside of the
specified scope.
• If a party fulfills its obligations it is entitled to its benefits
– No Hidden Clauses Rule: no requirement other than the obligations
written in the contract can be imposed on a party to obtain the benefits
Contracts for software
Example: add node to tree
• Contract is between:
– Client = caller
– Supplier = called routine
• Example:
– A class Tree describing tree nodes
– A routine put_child for adding a new child to the tree node Current
– The routine put_child receives a reference to an existing node object
and adds it as a child of Current
• Problem: a reference is either void or attached to an object.
• Question: who should check if new is void ?
• Approaches:
– Defensive programming: include as many checks as possible, even if
redundant with checks done by caller -> leads to increased complexity,
which leads to probability of errors
– Contracts
Table 2 from [Meyer]
Contracts for software
Example: add node to tree
Informal description of contract::
Party Obligations Benefits
Client Use as argument a Get updated tree where
reference, new, to an Current has one more child
existing node object – the new node.
Supplier Insert node new as child of No need to do anything if
Current new is void
Table 2 from [Meyer]
Contracts for software
Example: add node to tree
• Contracts for software are expressed through:
– preconditions - the obligations of the client
– postconditions - properties that are ensured in return by the
execution of the function call
• Example:
Operation put_child (new:Node);
-- add new to the children of Current
Precondition: new is not void
Postcondition: new’s parent is Current and the children-
count of current has been increased by 1
Weak and strong contracts
“Who has to check all the conditions?”
• Postconditions
– specify the exit conditions guaranteed by an operation at its end provided the
precondition was satisfied at the entry in the operation
– The outcome when the precondition was not satisfied is explicitly left
undefined [Meyer]
• Strong contract:
– the precondition specifies conditions for success
– postconditions need to specify only the outcome in the well-defined situations
– Back-end-components usually have strong contracts
• Weak contract:
– the precondition is incomplete, the component must be able to filter out
invalid uses
– The postconditions will specify also the outcome of the invalid uses
– Front-end-components (such as GUI-components) usually have weak
contracts
Contracts for components
Contracts for components are expressed through:
• Pre-conditions
• Post-conditions
• Invariants
A Pre-condition
• Is an assertion that the component assumes to be
fulfilled before an operation is invoked.
• Is a predicate over the operation’s input
parameters and this component’s state
A Post-condition
• Is an assertion that the component guarantees will hold just
after an operation has been invoked, provided the operation’s
pre-conditions were true when it was invoked.
• Is a predicate over both input and output parameters as well
as the state just before the invocation and the state just
after
An Invariant
• Is a predicate over the interface’s state model that will
always hold
• A set of invariants may be associated with an interface.
Metamodel of the concepts used in
semantic specification of software components
Figure 2.2 from [Crnkovic]
Semantic specification of components
• Semantic specification of a component comprises:
– Specify component interfaces
– For each interface, specify:
• Model of state and Invariants
• Operations with pre- and post-conditions
• The model allows that different interfaces act on the same state
model
– Inter-interface constraints
Note that state models and operation semantics are associated with interfaces
rather than with a component !
Component specification
Example: component SpellChecker
«comp spec» ISpellCheck
SpellChecker ICustomSpellCheck
Specifying a component that provides interfaces
Interface specification diagram
Example: Interface ISpellCheck
• State: words
• Operations:
– check (in word:String, out correct:Boolean):HRESULT;
• Pre: the word to be checked is non-empty string
• Post: if the return value indicates success, then the value of correct
is true if word was a member of words and false otherwise
Interface specification diagram
Example: ICustomSpellCheck
• State: words
• Operations:
– add (in word:String):HRESULT;
• Pre: the word to be added is non-empty string
• Post: if the return value indicates success, then word has been added to words
– remove(in word:String):HRESULT;
• Pre: the word to be removed is non-empty string
• Post: if the return value indicates success, then word has been removed from
words
Inter-interface Constraints
• The component specification can be completed by the
specification of its inter-interface constraints:
• Relationships between the models of state associated with the
different interfaces
context SpellChecker
ISpellCheck::words = ICustomSpellCheck::words
Uses of Semantic Specification
• Tool support for component developers
• Tool support for developers of component-based applications
Substitution extended with semantics
• Substituting a component Y for a component X is said to be safe if:
– All systems that work with X will also work with Y
• From a semantic viewpoint, a component can safely be replaced if:
– A client that satisfies the preconditions for X must always satisfy the
preconditions specified for Y
– A client that can rely on postconditions ensured by X can also be
ensured it can rely on Y
• Conditions for component Y:
– Interfaces of Y can have weaker preconditions on operations
– Interfaces of Y can have stronger postconditions on operations
– State models of X and Y need not be identical
Levels of Formalism for Semantic
Specifications
• The levels of formalism, in an increasing order of formalism:
– No semantics
– Intuitive semantics
– Structured semantics
– Executable semantics
– Formal semantics
An Example
• Component RandomAccess
– controlls the access to random access file of a record type R
– records of a fixed size
– access to the file is by record number, numbers start from 0.
– It is assumed that the file is continuous, thus record numbers go up to the current maximum number,
called the high water mark
• Operations:
– addRecord
– getRecord
– delRecord
– getHighWaterMark
The contract
• Operation getRecord – retrieves a record with a given number
public R getRecord(int number)
throws IOException
• The precondition :
– the single input parameter of the operation is the number of the record
concerned, which must exist in the file.
• The post-condition:
– If an unrecoverable system error occurs (file system error) the operation
indicates a failure
• Weak part of the contract: client does not have to check file status before
– the result of the operation is the required data record of type R.
• Strong part of the contract: assumes that record number is always correctly
given
Level 0: No Semantics
• The following definition of the operation getRecord illustrates
how a purely syntactic specification would be given:
public R getRecord(int number)
throws IOException
Level 1: Intuitive Semantics
• Plain text, unstructured description and comments about a component and
its parts
• An intuitive specification of the operation getRecord:
The operation getRecord retrieves a record by its number,
returning the record requested. If an error occurs, such as a disk
read error or a file system error, the an I/O error is returned.
Level 2: Structured Semantics
• The semantics is presented in a structured way but needs not be in
accordance with any particular syntax or formalism
• A structured specification of the operation getRecord:
getRecord returns a record identified by its number.
Parameters:
number: the number of the record to retrieve, counted from zero
Precondition: number >= 0 and number <= the high water mark
Postcondition: the record with the given number is returned,
unless a file system error occurs, in which case a file system
error is reported and the value returned is undefined.
Level 3: Executable Semantics
• The semantics is expressed in a way that can be executed and
controlled by the system during run-time.
• The executable specification is included in the implementation
of the component
• Limitation: not all conditions can be expressed in an executable
way
Executable specification for getRecord:
getRecord returns a record identified by its number.
Parameters:
number: the number of the record to retrieve, counted from zero
Precondition: (0 <= number) && (number <= hwm())
Postcondition: throw IOException || (result == record(number))
Examples of executable semantics
• For program implementations: Assertions in Java:
• For UML models: OCL (Object Constraint Language)
• General rules:
– The execution of the assertions should not add functionality !
– Assertions serve to detect coding errors and should not try to
handle or compensate for them
Ensuring a Correct Call
• The client code must check the precondition before the call, as
illustrated below:
if ((0 <= number) && (number <= theFile.hwm()))
{
try {
record = theFile.getRecord(number);
// record == the record requested
}
catch (IOException e)
{ /* unrecoverable IO error */ }
}
Trapping Offending Calls
• For debugging purposes, the component itself may use the
executable precondition to trap offending calls:
(The example here just assumes that the System class contains an assert method)
public R getRecord(int number) throws IOException
{
System.assert((0 <= number) && (number <= hwm()));
// the implementation of the method
}
OCL
• The Object Constraint Language (OCL) is a
declarative language for describing rules that
apply to UML models
• OCL can be used
– to describe constraints
• A constraint is a restriction on one or more values of a model or
system.
• A constraint is an expression that evaluates to true or false
– as a query language
• Queries are expressions that evaluate to a value (true, false
and other values)
• Can be used to define new attributes and operations
• OCL expressions are always associated with a UML
model
– OCL expressions can be associated with any model element
in UML
OCL Constraints vs. Queries
Flight
departing
origin Flights
Airport departTime: Time
1 * /arrivalTime: Time
name: String duration : Interval
1 * maxNrPassengers: Integer
desti- arriving
nation Flights
• Examples of constraints:
– Duration of a flight is the same as the difference between the arrival
and departure times
– The maximum number of passengers on a flight must be less than
1,001
– The origin of a flight must be different than its destination
• Examples of queries:
– Return all the departing flights from a given airport
– Return all the flights departing from a given airport with a departure
time after 4p.m.
– Derive the arrival time by adding the duration of the flight to the
departure time.
Different kinds of OCL constraints
• Class invariant
– a constraint that must always be met by all instances of the class
• Precondition of an operation
– a constraint that must always be true BEFORE the execution of the
operation
• Postcondition of an operation
– a constraint that must always be true AFTER the execution of the
operation
• Constraint context: the element that the constraint restricts
– Every OCL expression is bound to a context
– Own context may be denoted by “self”
Example: SpellChecker component
«comp spec» ISpellCheck
SpellChecker ICustomSpellCheck
Example: OCL Interface Specification
context ISpellCheck::check(in word : String, out correct :
Boolean): HRESULT
pre:
word <> “”
post:
SUCCEEDED(result) implies correct = words->includes(word)
context ICustomSpellCheck::add(in word : String) : HRESULT
pre:
word <> “”
post:
SUCCEEDED(result) implies words = words@pre->including (word)
context ICustomSpellCheck::remove(in word : String) : HRESULT
pre:
word <> “”
post:
SUCCEEDED(result) implies words = words@pre->exluding(word)
Example: OCL Inter-interface constraints
• The component specification is completed by the specification of its inter-interface constraints, an example
constraint is formulated in OCL below.
context SpellChecker
ISpellCheck::words = ICustomSpellCheck::words
Level 4: Formal Semantics
• With formal semantics programs can be proven to
have consistent and sound semantics
• Formal specification languages:
– VDM
– Z
– Lambda
Formal Semantics Example
• The visible state of the random access component is defined in a Z
state schema called RandomAccess
• The term records represent all the records in the file and R is the
record data type.
• The variable hwm (for 'high water mark') shows how much of the file is
in use.
• The formula expresses the invariant
RandomAccess
records: N R
hwm: N
i : 0..hwm { records(i) }
Formal Semantics Example Continued
• The file operation is defined as a state schema called getRecord
and is illustrated below:
getRecord
RandomAccess
number?: N
record!: R
status!: {OK, FileSystemError}
number? hwm
((status! = OK) record! = records(number?))
(status! = FileSystemError)
Component specification levels
• Levels of a component specification:
– Syntax: includes specifications on the programming
language level.
– Semantic: functional contracts
– Non-functional: deals with quality of service.
Quality-of-service specification
• What:
• Non-functional (extra-functional) properties (associated more with
component implementations rather than interfaces)
• Examples: Reusability, Configurability, Distributeability, Availability, Confidentiality,
Integrity, Maintainability, Reliability, Safety, Security, Affordability, Accessibility,
Administrability, Understandability, Generality, Operability, Simplicity, Mobility, Nomadicity,
Hardware independence, Software independence, Accuracy, Footprint, Responsiveness,
Scalability, Schedulability, Timeliness, CPU utilization, Latency, Transaction, Throughput,
Concurrency, Efficiency, Flexibility, Changeability, Evolvability, Extensibility, Modifiability,
Tailorability, Upgradeability, Expandability, Consistency, Adaptability, Composability,
Interoperability, Openness, Heterogenity, Integrability, Audibility, Completeness, ,
Conciseness, Correctness, Testability, Traceability, Coherence, Analyzability, Modularity, …
• Who:
• Credentials
• Why needed:
• Selection between semantic equivalent components
• Negotiation possibilities
Credentials
•Mary Shaw, Truth vs Knowledge: The Difference Between What a Component
Does and What We Know It Does, Proceedings of the 8th International
Workshop on Software Specification and Design,
•http://www.cs.cmu.edu/afs/cs/project/vit/www/paper_abstracts/Credentials.html
•Credential is a triple <Attribute, Value, Credibility>
•Attribute: is a description of a property of a component
•Value: is a measure of that property
•Credibility: is a description of how the measure has been obtained
•A specification technique based on credentials must include:
•a set of registered attributes
•notations for specifying their value and credibility
•provisions for adding new attributes. A technique could specify some
attributes as required and others as optional.
Metamodel of the concepts used in
extra-functional specification of software components
Figure 2.7 from [Crnkovic]
Summary
• A component has two parts: an interface and some code
• In current practice, component specification techniques specify
components only syntactically.
• There are many steps towards semantic specifications:
– Executable semantics: (Assertions, Code Contracts, OCL)
– Formal semantics
• Specification of extra-functional properties of components is
still an open area of research, and it is uncertain what impact it
will have on the future of software component specification
Component specification conclusion
•Software specification in a Conventional software doctrine :
•Sufficient and complete: provide everything a user needs to know and may rely on
in using the software
•Static : written once and frozen
•Homogeneous: written in a single notation
•Specification of architectural components:
•Incomplete:
•To use an architectural component successfully, information about more than just its
functionality is required.
•It is not realistic to expect specifications to be complete with respect to all such properties,
due to the great effort this would require. (Nor is it realistic to expect that the developer of a
component could anticipate all aspects of the component in which its user might be
interested.)
•Extensible:
• Because we cannot expect software components to be delivered with specifications that
are sufficient and complete, and because developers are likely to discover new kinds of
dependencies as they attempt to use independently developed components together
•Heterogeneous:
•since the diversity of properties that might be of interest is unlikely to be suitably captured by
a single notation.