Notes I
Notes I
Unit I
Introduction
Object modeling is useful for designing computer systems, whether those
systems are to be implemented in object-oriented languages or not. Most designs
are likely to need more than an object-oriented language, such as a database.
Object modeling also has a use outside of the design of computer systems.
It is an excellent analysis method, and it can be used in business process
reengineering, in social science research, or any complex environment where it is
important to capture the structure and functionality of some world.
Objective
This subject aims to provide you with
A simple, clear, analysis and design notation.
A good basic understanding of the concepts of object oriented
systems.
A method for construction of analyses and designs.
Some discussion of the implementation of designs.
ii) Topology
The topology of First and Early Second Generation Programming Languages
By topology, we mean the basic physical building blocks of the language
and how those parts can be connected. Applications written in these languages
exhibit a relatively flat physical structure, consisting only of global data and
subprograms. The arrows in the figure indicate dependencies of the
subprograms on various data. During design, one can logically separate different
kinds of data from one another, but there is little in these languages that can
enforce these design decisions.
The topology of Late Second and Early Third Generation Programming
Language
The realization that subprograms could serve as an abstraction
mechanism had three important consequences. First, languages were invented
that supported a variety of parameter passing mechanisms. Second, the
foundations of structured programming were laid, manifesting themselves in
language support for the nesting of subprograms and the development of
theories regarding control structures and the scope and visibility of declarations.
Third, structured design methods emerged, offering guidance to designers trying
to build large systems using subprograms as basic physical building blocks.
Object-Oriented Programming
Object-oriented programming is a method of implementation in which programs
are organized as cooperative collections of objects, each of which represents an instance of
some class and whose classes are all members of a hierarchy of classes united via
inheritance relationships.
There are three important parts to this definition: object-oriented
programming (1) uses objects, not algorithms, as its fundamental logical building
blocks; (2) each object is an instance of some class; (3) classes are related to one
another via inheritance relationships.
A language is object-oriented if and only if it satisfies the following
requirements:
It supports objects that are data abstractions with an interface of
named operations and a hidden local state.
Objects have an associated type.
Types may inherit attributes from super types.
Object-Oriented Design
Object-oriented design is a method of design encompassing the process of object-
oriented decomposition and a notation for depicting logical and physical as well as static
and dynamic models of the system under design.
There are two important parts to this definition: object-oriented design (1)
leads to an object-oriented decomposition and (2) uses different notations to
express different models of the logical and physical design of a system, in
addition to the static and dynamic aspects of the system.
Object-Oriented Analysis
Object-oriented analysis emphasizes the building of real-world models,
using an object-oriented view of the world:
Object-oriented analysis is a method of analysis that examines requirements from
the perspective of the classes and objects found in the vocabulary of the problem domain.
Abstraction
Abstraction is one of the fundamental ways that we as humans cope with
complexity. Hoare suggests that “abstraction arises from recognition of
similarities between certain objects, situations or processes in the real world and
the decision to concentrate upon these similarities and to ignore for the time
being the differences”. Shaw defines an abstraction as “a simplified description
or specification of a system that emphasizes some of the system’s details or
properties while suppressing others”.
An abstraction denotes the essential characteristics of an object that distinguish it
from all other kinds of objects and thus provide crisply defined conceptual boundaries,
relative to the perspective of the viewer.
An abstraction focuses on the outside view of an object and so serves to
separate an object’s essential behavior from its implementation. Deciding upon
the right set of abstractions for a given domain is the central problem in object-
oriented design.
The following are the kinds of abstractions:
Entity abstraction An object that represents a useful model of
a problem domain or solution domain
entity
Action abstraction An object that provides a generalized set of
operations, all of which perform the same
kind of function
Virtual machine abstraction An object that groups together operations
that are all used by some superior level of
control, or operations that all use some
junior-level set of operations
Coincidental abstraction An object that packages a set of operations
that have no relation to each other
A client is any object uses the resources of another object known as server. We
can characterize the behavior of an object by considering the services that it
provides to other objects, as well as the operations that it may perform upon
other objects. This view forces us to concentrate upon the outside view of an
object and leads us to what Meyer calls the contract model of programming: the
outside view of each object defines a contract upon which other objects may
depend and which in turn must be carried out by the inside view of the object
itself. This contract thus establishes all the assumptions a client object may make
about the behavior of a server object.
Individually, each operation that contributes to this contract has a unique
signature comprising all of its formal arguments and return type. We call the
entire set of operations that a client may perform upon an object, together with
the legal orderings in which they may be invoked, its protocol. A protocol
denotes the ways in which an object may act and react, and thus constitutes the
entire static and dynamic outside view of the abstraction.
Central to the ideal of an abstraction is the concept of invariance. An invariant
is some Boolean condition whose truth must be preserved. For each operation
associated with an object, we may define preconditions as well as postconditions.
Violating an invariant breaks the contract associated with an abstraction. If a
precondition is violated, this means that a client has not satisfied its part of the
bargain and hence the server cannot proceed reliably. Similarly, if a
postcondition is violated, this means that a server has not carried out its part of
the contract and so its clients can no longer trust the behavior of the server. An
exception is an indication that some invariant has not been or cannot be satisfied.
All abstractions have static as well as dynamic properties. For example, a file
object takes up a certain amount of space on a particular memory device; it has a
name and it has contents. These are all static properties. The value of each of
these properties is dynamic, relative to the lifetime of the object: a file object may
grow or shrink in size, its name may change, and its contents may change.
In a procedure-oriented style of programming, the activity that changes the
dynamic value of objects is the central part of all programs: things happen when
subprograms are called and statements are executed. In a rule-oriented style of
programming, things happen when new events cause rules to fire, which in turn
may trigger other rules. In an object-oriented style of programming, things
happen whenever we operate upon an object. Thus, invoking an operation upon
an object elicits some reaction from the object.
Encapsulation
Abstraction and encapsulation are complementary concepts: abstraction
focuses upon the observable behavior of an object, whereas encapsulation
focuses upon the implementation that gives rise to this behavior. Encapsulation
is most often achieved through information hiding, which is the process of
hiding all the secrets of an object that do not contribute to its essential
characteristics; typically the structure of an object is hidden as well as the
implementation of its methods.
Encapsulation provides explicit barriers among different abstractions and
thus leads to a clear separation of concerns. Each class must have two parts: an
interface and an implementation. The interface of a class captures only its outside
view, encompassing our abstraction of the behavior common to all instances of
the class. The implementation of a class comprises the representation of the
abstraction as well as the mechanisms that achieve the desired behavior. The
interface of a class is the one place where we assert all of the assumptions that a
client may make about any instances of the class.
To summarize, encapsulation defined as follows:
Encapsulation is the process of compartmentalizing the elements of an
abstraction that constitute its structure and behavior; encapsulation serves to separate
the contractual interface of an abstraction and its implementation.
Modularity
Modularization consists of dividing a program into modules which can be
compiled separately, but which have connections with other modules. The
traditional practice in the C/C++ community is to place module interfaces in
files named with a .h suffix; these are called header files.
Modularity packages abstractions into discrete units. A package has two
parts: the package specification and the package body. The connections among
modules to be asserted separately in the specification and body of a package.
Thus, it is possible for a package body to depend upon modules that are
otherwise not visible to the package’s specification.
Deciding upon the right set of modules for a given problem is almost as
hard a problem as deciding upon the right set of abstractions. Modules serve as
the physical containers in which we declare the classes and objects of our logical
design.
In traditional structured design, modularization is primarily concerned
with the meaningful grouping of subprograms, using the criteria of coupling and
cohesion.
Modularity is the property of a system that has been decomposed into a set of
cohesive and loosely coupled modules.
Two additional technical issues can affect modularization decisions. First,
since modules usually serve as the elementary and indivisible units of software
that can be reused across applications, a developer might choose to package
classes and objects into modules in a way that makes their reuse convenient.
Second, many compilers generate object code in segments, one for each module.
Hierarchy
Encapsulation helps manage this complexity by hiding the inside view of
our abstractions. Modularity helps also, by giving us a way to cluster logically
related abstractions. A set of abstractions often forms a hierarchy and by
identifying these hierarchies in our design, we greatly simplify our
understanding of the problem.
Hierarchy is a ranking or ordering of abstractions.
The two most important hierarchies in a complex system are its class structure
and its object structure. The following are examples of hierarchy.
Single Inheritance
Multiple Inheritance
Aggregation
Typing
The concept of a type derives primarily from the theories of abstract data
types. A type is a precise characterization of structural or behavioral properties
which a collection of entities all share.
Typing is the enforcement of the class of an object, such that objects of different
types may not be interchanged, or at the most, they may be interchanged only in very
restricted ways.
Examples of Typing
i) Strong and Weak Typing
A given programming language may be strongly typed, weakly typed or
even untyped, yet still be called object-oriented.
Strong typing prevents mixing abstractions. It use our programming
language to enforce certain design decisions and so is particularly relevant as the
complexity of our system grows. A strongly typed language is one in which all
expressions are guaranteed to be type-consistent.
There are a number of important benefits to be derived from using
strongly typed languages:
Without type checking, a program in most languages can crash in
mysterious ways at runtime
In most systems, the edit-compile-debug cycle is so tedious that early
error detection is indispensable
Type declarations help to document programs
Most compilers can generate more efficient object code if types are
declared
iii)Polymorphism
It represents a concept in type theory in which a single name may denote
objects of many different classes that are related by some common superclass.
Any object denoted by this name is therefore able to respond to some common
set of operations. The opposite of polymorphism is monomorphism, which is
found in all languages that are both strongly typed and statically bound.
Concurrency
A single process known as a thread of control is the root from which
independent dynamic action occurs within a system. Every program has at least
one thread of control, but a system involving concurrency may have many such
threads: some that are transitory and others that last the entire lifetime of the
system’s execution. Systems executing across multiple CPUs allow for truly
concurrent threads of control, whereas system running on a single CPU can only
achieve the illusion of concurrent threads of control.
Concurrency allows different objects to act at the same time. A
heavyweight process is one that is typically independently managed by the
target operating system and so encompasses its own address space. A
lightweight process usually lives within a single operating system process along
with other lightweight processes, which share the same address space.
Communication among heavyweight processes is generally expensive, involving
some form of interprocess communication; communication among lightweight
process is less expensive and often involves shared data.
Concurrency is the property that distinguishes an active object from one that is
not active.
Persistence
An object in software takes up some amount of space and exists for a
particular amount of time. The spectrum of object persistence encompasses the
following:
Transient results in expression evaluation
Local variables in procedure activations
Own variables, global variables and heap items whose extent is different
from their scope
Data that exists between executions of a program
Data that exists between various versions of a program
Data that outlives the program
Persistence deals with more than just the lifetime of data. In object-oriented
databases, not only does the state of an object persist, but its class must also
transcend any individual program, so that every program interprets this saved
state in the same way. This clearly makes it challenging to maintain the integrity
of a database as it grows, particularly if we must change the class of an object.
To summarize, persistence is defined as follows:
Persistence is the property of an object through which its existence transcends
time (i.e. the object continues to exist after its creator ceases to exist) and/or space (i.e. the
object’s location moves from the address space in which it was created).
State
The state of an object encompasses all of the (usually static) properties of the object plus
the current (usually dynamic) values of each of these properties.
A property is an inherent or distinctive characteristics, trait, quality or feature
that contributes to making an object uniquely that object. All properties have some
value. This value might be a simple quantity or it might denote another object. The
objects exist in time are changeable, have state are instantiated and can be created,
destroyed and shared.
The fact that every object has state implies that every object takes up some
amount of space, be it in the physical world or in computer memory.
Behavior
Behavior is how an object acts and reacts, in terms of its state changes and message
passing.
The behavior of an object represents its outwardly visible and testable activity.
An operation is some action that one object performs upon another in order to elicit a
reaction. In most object-oriented programming languages, operations that clients may
perform upon an object are typically declared as methods, which are part of the class’s
declaration.
Message passing is one part of the equation that defines the behavior of an
object. The behavior of an object is a function of its state as well as the operation
performed upon it with certain operations having the side effect of altering the
object’s state.
The state of an object represents the cumulative results of its behavior.
Operations
An operation denotes a service that a class offers to its clients. A client performs
five kinds of operations:
Modifier An operation that alters the state of an object
Selector An operation that accesses the state of an object, but does
not alter the state
Iterator An operation that permits all parts of an object to be
accessed in some well-defined order
Constructor An operation that creates an object and/or initializes its
state
Destructor An operation that frees the state of an object and/or
destroys the object itself
In pure object-oriented programming languages, operations may only be
declared as methods, since the language does not allow us to declare procedures or
functions separate from any class.
All methods are operations, but not all operations are methods: some
operations may be expressed as free subprograms.
Identity
Identity is that property of an object which distinguishes it from all other objects.
Most programming and database languages use variable names to distinguish
temporary objects, mixing addressability and identity.
Links
It is defined as a physical or conceptual connection between objects. An object
collaborates with other objects through its links to these objects. Stated another way, a
link denotes the specific association through which one object(the client) applies the
services of another object(the supplier) or through which one object may navigate to
another.
Message passing between two objects is typically unidirectional, although it
may occasionally be bidirectional. As a participant in a link, an object may play one of
three roles:
Actor An object that can operate upon other objects but is
never operated upon by other objects; in some
contexts, the terms active object and actor are
interchangeable.
Server An object that never operates upon other objects; it
is only operated upon by other objects.
Agent An object that can both operate upon other objects
and be operated upon by other objects; an agent is
usually created to do some work on behalf of an
actor or another agent.
Visibility
Consider two objects, A and B, with a link between the two. In order for A to
send a message to B, B must be visible to A in some manner. There are four different
ways that one object may have visibility to another:
The supplier object is global to the client
The supplier object is a parameter to some operation of the client
The supplier object is a part of the client object
The supplier object is a locally declared object in some operation of the
client.
Synchronization
Whenever one object passes a message to another across a link, the two objects
are said to be synchronized. However, in the presence of multiple threads of control,
objects require more sophisticated message passing in order to deal with the problems
of mutual exclusion that can occur in concurrent systems.
There are three approaches to synchronization:
Sequential The semantics of the passive object are
guaranteed only in the presence of a single
active object at a time.
Guarded The semantics of the passive object are
guaranteed in the presence of multiple
threads of control but the active clients
must collaborate to achieve mutual exclusion.
Synchronous The semantics of the passive object are
guaranteed in the presence of multiple
threads of control, and the supplier
guarantees mutual exclusion.
Aggregation
Whereas links denote peer-to-peer or client/supplier relationships, aggregation
denotes a whole/part hierarchy with the ability to navigate from the whole(also called
the aggregate) to its parts(also known as its attributes). Aggregation is a specialized
kind of association.
Aggregation may or may not denote physical containment. The relationship
between shareholder and her shares is an aggregation relationship that does not
require physical containment. The shareholder uniquely owns shares, but the shares
are by no means a physical part of the shareholder.
There are clear trade-offs between links and aggregation. Aggregation is
sometimes better because it encapsulates parts as secrets of the whole. Links are
sometimes better because they permit looser coupling among objects.
By implication, an object that is an attribute of another has a link to its
aggregate. Across this link, the aggregate may send messages to its parts.