Sunday, October 16, 2022

Fundamentals of Object Oriented Analysis and Design - Classifications - Part 04

 The following are the notes from Object Oriented Analysis and Design 3rd edition.

In object-oriented design recognizing sameness among things allows us to expose commonality among within key abstractions and mechanisms leading to smaller applications and simplified architectures.

Identification of classes and objects is challenging part in object-oriented analysis and design as this involves both discovery and invention. Through discovery key abstraction and mechanisms are found that form vocabulary of problem domain. Through invention new generalized abstractions and mechanisms that define how objects collaborate are found. Both are the tools of classification and the purpose is to group things that have common structures and exhibit common behavior.

Classification helps us find generalization/specialization/aggregation hierarchies among classes. By recognizing common pattern of interaction among objects, mechanisms are discovered that serve as blueprint of implementation. Classification also guides about modularization. Certain classes and objects might be placed in same or different module based on sameness found in the declarations.

The boundaries that distinguish one object from other is not always crisply defined but fuzzy. The Parallels of Classification is also found in the disciplines of biology. For example, The most general category in a biological taxonomy is the kingdom, followed in order of increasing specialization, by phylum, subphylum, class, order, family, genus, and, finally, species.

Classification is the means whereby we order knowledge.

Different criteria for classifying same animal yield different results. Therefore, results of classification are highly dependent on the reason for classification.

Incremental and iterative classification affects creation class and object hierarchies in complex systems. It’s practical to assert a class structure early during the design and later revise it over time. The quality of the classification can be seen only after the clients use it.


Different observers will classify the same object in different ways.

There is no perfect classification – it depends on the perspective of the observer. Also intelligent classification requires a tremendous insight.

There are three types of classification theories:

  1. Classical categorization
  2. Conceptual Clustering
  3. Prototype Theory

Classical categorization

Classical approach uses related properties as criteria for sameness among objects. Specifically, one can divide objects into disjoint sets depending on presence or absence of the property. Example, married or unmarried people.   Not applicable are tall or skinny people.

The most useful set of properties are those that don’t interact much. For example, color, size, style etc. a dress can be of any style/color/size. Properties may include also observable behavior. Example, birds fly, fish swim etc.

Particular property that should be considered is highly domain specific. For example, make of a car may be important for a car showroom inventory control software but not for traffic light control software. Therefore, there is no absolute measure of classification for a given system.

Classic Classification may not work in every case. For example, some birds like emu or ostrich cannot fly. Chairs may not have 4 legs, a table may be square, round, rectangle etc. Therefore, it’s almost impossible to make a list of properties for a natural category that excludes some examples and includes some for the same category.

Conceptual Clustering

Is a variation of classical categorization where classes (clusters of entities) are first generated formulating conceptual description of these classes and then classifying the entities on the basis of description. For example, take the concept of “happy song” which is more than a property. It’s difficult to measure “happiness” of a song empirically. However, if a song is indeed happy then it needs to be placed under this category. Therefore, conceptual clustering is probabilistic clustering of objects.

Conceptual clustering is closely related to fuzzy(multivalued) set theory where objects belong to more than one group in varying levels of fitness. Conceptual clustering makes best judgement of classification based on best fit.

The diagram below contains ten items, labeled A to J, each of which represents a train. Each train includes an engine (on the right) and from two to four cars, each shaped differently and holding different loads. Before reading further, spend the next few minutes arranging these trains into any number of groups you deem meaningful. For example, you might create three groups: one for trains whose engines have all black wheels, one for trains whose engines have all white wheels, and one for trains whose engines have black and white wheels.

A Problem of Classification

Prototype Theory

There are abstractions that are not bound by a set of properties or concepts. A class of objects is represented by a prototypical object and an object can belong to this category only if it resembles this prototype in significant ways. For example, “game” in general is not bound by properties that applies to all games. However, there are category of games exists that are united by family of resemblance. Yet this category is not fixed and can be extended as new games can be developed and added to this category as long as they resemble other games in this category.

Similarly different type of chair such as wheelchair, beanbag are called chairs not because they share some properties with the prototype rather they bear sufficient family resemblance to the prototype. In fact, there need not exist fixed properties for the prototype chair at all.

Interactional properties are significant in determining family resemblance to a prototype and are central to the idea of prototype theory.

Application

In practice for object-oriented design all the three practices are relevant.

First start off with classical categorization where classes and objects are scooped per properties relevant to the problem domain; here structures and behaviors are identified. Next, objects are clustered based on concepts by focusing on the behavior of collaborating objects. Further, classification of objects is considered based on association where clusters of objects are defined based on their similarities with a prototype object.

Therefore, object-oriented analysis uses all the three classification methods that instills theoretical foundation by providing pragmatic practices and rules of thumb to identify classes and objects in problem domain.

Object oriented analysis

The difference between object-oriented analysis and design are quite fuzzy even though their focusses are quite distinct. The purpose of object-oriented analysis is to create a model analyzing the problem domain and discovering classes and objects from its vocabulary. In object-oriented design abstractions and mechanisms are invented from the model to provide blueprint for the implementation.


Classical Approaches
Following approaches use classical approach for deriving classes and objects from problem domain:

Candidate classes and objects come from one of the following sources:

Sources

Examples

Tangible things

Cars, telemetry data, pressure sensors

Roles

Mother, teacher, politician

Events

Landing, interrupt, request

Interactions

Loan, meeting, intersection

Database Modeling:

Sources

Examples

People

Humans who carry out some function

Places

Areas set aside for people or things

Things

Physical objects, or groups of objects, that are tangible

Organizations

Formally organized collections of people, resources, facilities, and capabilities having a defined mission, whose existence is largely independent of individuals

Concepts

Principles or ideas not tangible per se; used to organize or keep track of business activities and/or communications

Events

Things that happen, usually to something else at a given date and time, or as steps in an ordered sequence

 Another set of sources of potential objects:

Sources

Examples

Structure

Is a and part of relationships

Other systems

External systems with which the application interacts

Devices

Devices with which the application interacts

Events remembered

A historical event that must be recorded

Roles played

The different roles users play in interacting with the application

Locations

Physical locations, offices, and sites important to the application

Organizational units

Physical locations, offices, and sites important to the application

 At a higher level of abstraction, the subject areas are a group of classes that relate to higher level system function.

Behavior Analysis
Dynamic behavior can be used as source of classes and objects. This is similar to conceptual clustering. Classes are formed from group of objects that exhibit similar behavior.

Responsibilities convey purpose of an object and its place in the system. In other words, responsibility of an object is all the services it provides for all the contract it supports. Therefore, hierarchy of classes are formed based common responsibilities from entities. Base classes are formed to have general responsibilities and derived classes are formed to have specialized responsibilities.

Another method is to derive a set of classes and objects from system functions. In this approach a study of the system is made and system behaviors are understood. Next, these behaviors are applied to the parts of the system. The Initiator and participants are made as objects. The behavioral responsibilities are made as roles of the objects.

This resembles closely to the concept of function points. It’s defined as one end user business function. A function point is any relevant outwardly visible or testable behavior of the system.

Domain Analysis

Domain analysis attempts to discover classes and objects that are common to all application within a given domain such as patient record tracking, bond trading etc. Domain analysis can be defined as an attempt to identify objects, functions, relationships that domain experts believe important to the domain.

Following steps can be used during domain analysis:

  • Construct a strawman generic model of the domain by consulting with domain experts.
  • Examine the current system under the domain and represent it in a common format.
  • Understand similarities and differences between the systems by consulting domain experts.
  • Refine the generic model to accommodate the existing system.

A domain expert has immense experience with the problem domain and can speaks vocabulary of the problem domain.

Use Case Analysis

An use case can be defined as behaviorally related set of transactions performed by an actor in dialog with the system to provide some measurable value to the actor.

Use case analysis can be performed during early requirement analysis phase where end users, domain experts and development team enumerate the scenarios that are fundamental to the systems operation. (No elaboration needed). These scenarios collectively describe the system functions of the application.  Analysis then proceeds with the study of each scenario using storyboarding technique. As each scenario is studied, objects that participates in the scenario are identified, their responsibilities and how they collaborate with another objects in terms of invoking actions on each other. In this manner the team is forced to craft a clear separation of concerns among all abstractions. As the development continues, these scenarios are expanded to consider exceptional situations and secondary system behaviors. These secondary system behaviors introduce new abstractions or add/modify/reassign responsibilities in the existing abstractions. Scenarios also serve as basis for tests.

CRC Cards

CRC stands for Class/Responsibilities/Collaborators. CRC cards have proven to be useful development tool that facilitates brainstorming and enhance communication among developers. A CRC card is 3x5 card where name of the class is written on the top, responsibilities are written top half and collaborators on the bottom half. Each card is Ilustre one class. As the team walks through the scenario, add new responsibilities to an existing class, group a set of responsibilities to form a new class, divide the responsibilities into fine grained ones and perhaps distribute it to a new class.

CRC Cards can be spatially arranged to represent patterns of collaborations. As seen from the dynamic semantics of the scenario, the cards are arranged to show flow of the messages among prototypical instances of the class; from the static semantic of the scenario, the cards are arranged to represent generalization/specialization and aggregation hierarchies among classes.

Informal English Description

An alternative is to write English description of the problem or part of the problem where nouns and verbs are underlined. The nouns form the candidate objects and verbs form the candidate operations on the object. One important advantage is that it works in the vocabulary of the problem domain but it has language set limitations.

Structured Analysis

Some organizations have tried to use CASE tools as for front end of object-oriented analysis and design but it’s not recommended.

Key Abstractions and Mechanisms

A key abstraction is a class or object that forms part of the vocabulary of the problem domain. The primary value of finding such abstractions is that they give boundaries to our problem. They highlight the things that are in the system and therefore are relevant to the design and suppress things that are outside to the system.

The term mechanism is used to describe any structure whereby objects collaborate to perform some behavior that satisfy the requirement of a problem. While design of a class embodies the knowledge how an individual object should behave, mechanism is a design decision on how a group of objects should cooperate. Mechanism therefore represents patterns of behavior.

The following discuss identification and refinement of key abstractions and behavior.

Identifying key abstractions

Identification of key abstractions is highly domain specific. It involves two processes: discovery and invention. Through discovery, abstraction used by domain experts are recognized. Through invention new classes are created that are not necessarily part of problem domain but are useful artifacts in the design or implementation. For example, for an accountant key abstraction could be general ledger, account receivables, account payables etc. these words are part of the vocabulary of the problem domain. A developer of the system should also introduce new ones such as database, schema etc. These key abstractions are artifacts of the particular design, not of the problem domain.

The candidate key abstractions should be evaluated according to the metrics.

How are objects of this class are created?

Can objects of this class be copied/destroyed?
What operations can be done on such objects?

If there are no good answers, probably the concept was not clean to start with.

Given a new abstraction, it must be placed in context of existing class or object hierarchies. Practically speaking this neither top down or bottom-up activity. Classes are not created with hierarchy in mind. In practice, several unrelated classes are created and grouped together by commonality. Common attributes are placed in a base class. After several iterations hierarchy is created. For example, we may find general sub class and move it up in the hierarchy thus increasing degree of sharing. This is called class promotion. On other hand, there could be another class which is too general to make it a base class because of big semantic gap. This is called grain size conflict. The goal is to find cohesive yet loosely coupled abstractions.

Following should be considered while naming abstractions:

  • The object names should be taken from problem domain recognized by domain users.
  • Object names should be made with proper noun phrases such as thesensor.
  • Class names should be made with common noun phrase such as sensor
  • Modifier operations should be made with active verb such as moveLeft
  • Selector operations should imply query or should be verbed such as tobe. Isopen,  extentof
  • Use of underscore (_) is personal choice
Classes and objects should be at the right level of abstraction: neither too high nor too low.

Identifying Mechanisms

In a  four wheeler automobile, the requirement is when brake pedal is pushed the car should stop and when not pushed car should  move. How it’s implemented is not driver’s concern. In other words which mechanism is used is purely a design decision. It’s also illegal for an object to deviate outside the boundaries of a mechanism. For example, pushing gas pedal for example turn on the lights.

Key abstractions reflect the vocabulary of the problem domain and mechanisms reflect the soul of the design. During design process a developer should not only consider how the individual classes are designed but also how the instances of these work with each other. The use of these scenarios drives this analysis process.

Mechanisms are the means whereby objects collaborate to provide some higher-level behavior

Once developer decides a pattern of collaboration, work is distributed among many objects by defining methods in their respectable classes. The protocol of a class encompasses all the methods to satisfy all the behavior and all the mechanisms of its instances.

Summary

The identification of classes and objects is a fundamental issue in object-oriented analysis and design; identification involves both discovery and invention.
Classification is fundamentally a problem of clustering.
Classification is an incremental and iterative process, made difficult because a given set of objects may be classified in many equally proper ways.
The three approaches to classification include classical categorization (classification by properties), conceptual clustering (classification by concepts),and prototype theory (classification by association with a prototype).
Scenarios are a powerful tool of object-oriented analysis and can be used in approaches such as classical analysis, behavior analysis, domain analysis, and use case analysis.
Key abstractions reflect the vocabulary of the problem domain and may either be discovered from the problem domain or invented as part of the design.
Mechanisms denote strategic design decisions regarding the collaborative activity of many different kinds of objects.

Fundamentals of Object Oriented Analysis and Design - Classes and Objects - Part 03

 The following are the notes from Object Oriented Analysis and Design 3rd edition.

When object-oriented methods are used to design a complex system, the most essential building blocks are classes and objects. An object is a tangible entity with well-defined behavior. From human cognition an object can be defined as any of the below:
  • Something that is visible or tangible
  • Something that may be comprehended intellectually
  • Something toward which thought or action can be directed
Apart from this, the objects are invented during design process whose collaboration with other such objects serve as mechanism that provide high level behavior. Thus object can be defined as an independent, identifiable, item/unit /entity either real or abstract with well-defined role in problem domain. For example, a bicycle handle is separate from the cell that produces it in a factory.

Some objects may have crisp conceptual boundaries yet represent intangible boundaries or events. For example, a chemical process in a plant has crisp boundaries and well-defined behavior.

Some objects may be tangible yet have fuzzy boundaries. For example, rivers.

Attributes such as colors or emotions such as love or anger don’t qualify to be objects however, they can be properties of the object. For example, a man (an object) has a cat (an object) whose color is gray (a property of cat).

Even though the candidates for objects may have crisply defined boundaries, it may not be sufficient to distinguish one object from other or judge quality of abstraction. Therefore, an object is an entity that has a state, behavior and identity. The structure and behavior of similar objects are defined in their class.

An object has state, exhibits some well-defined behavior, and has a unique identity.

State

In a vending machine for example, the behavior depends purely on the history of previous actions. The reason for this event dependent and time dependent behavior is due to existence of the state with in the object. Some of the state can be money on hand before a drink selection, inventory of drinks, change due after drink selection etc.

State of an object encompasses values of all the static and current (dynamic) values of all the properties of the object. Static values can be serial number; dynamic can be money on hand. A property can be inherent or distinctive characteristic, trait, quality or feature that contributes to make that object unique. For example, an elevator is inherently constrained to move only up and down. Properties such as these usually static because they are unchanging and fundamental to the nature of the object. Sometimes they can change. For example, size of the produce change depending on sun light.

All the properties have some value. Some can be quantity and others can be another object. Quantities such as 3 can be atemporal, unchangeable or non-instantiated whereas objects exist in time, can be instantiated, have a state and can be changed.  Can be created, destroyed and shared.

The fact that an object has state means they take up space in real world or memory. It can be said that an object encapsulates some state and state of the system is encapsulated by all the objects in the system. Encapsulating the state of an object is the start but it’s not enough to capture full intent of abstraction of objects found in the design process. For this reason, behavior is important.

Behavior

No object is an island rather it’s acts upon or acted upon by other objects. Behavior represents outwardly visible activity of the object. An action of an object on another may or may not alter the state of that object. Behavior of an object is function of its state and action performed on it. Therefore, the state of an object is the effect of cumulative results its behavior. The state of interesting objects doesn’t stay fixed. They are changed and retrieved upon actions. The behavior of an object is embodied in sum of its actions.

Operations

In practice, a client typically performs five kinds of operations on an object. The three most common kinds of operations are the following:
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

Two other kinds of operations are common; they represent the infrastructure necessary to create and destroy instances of a class.

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 C++, constructors and destructors are declared as part of the definition of a class.

Rules and responsibility

Collectively all the methods comprised in an object is its protocol. Therefore, protocol defines the envelope of allowable behavior of an object including static and dynamic views of the object. A large protocol can be divided into logical groups that denotes roles an object can play. A role is a hat that objects wear so defines the contract between an object and the client.

In other words, state and roles of an object define the roles the object plays in turn fulfill the abstraction’s responsibilities. For example, same person can play roles of homemaker, mother, doctor etc. The roles played are dynamic yet mutually exclusive.

Objects can be autonomous where they have thread of control where as passive objects don’t. Also active objects are autonomous they act upon themselves where as passive wait to be acted upon.

Identity

Identity of an object is that property that distinguishes itself from others. Programming languages use variable names and databases uses keys to identify objects. Failure to recognize the difference between name of the object and the object itself is source of error in object-oriented programming.

For example, from below row c, item1 and item2 point to same state but are different objects. Also state of the object pointed by item3 is changed indirectly by action from item4. This is called structural sharing meaning an object can have aliases. The side effects are memory leaks and dangling references.

Relationship among objects

Collaborations among objects results in high level behavior of the system. For example, an aircraft fly only when all he objects such as engine, gyroscopes etc. collaborate. Two types of relationships between objects are noticeable: Links and Aggregation.

Links

An object collaborates with other objects via its links to other objects.

Below diagram illustrates MVC design pattern and several different links can be seen. In this figure, a line between two object icons represents the existence of a link between the two and means that messages may pass along this path. Messages are shown as small directed lines representing the direction of the message, with a label naming the message itself.

In order to send messages from Object A to object B, Object B should be visible to Object A.

When an object sends a message to another, they are said to be synchronized. In a single threaded system, it’s just method invocation; in multi-threaded scenario, mutual exclusion is needed. In case of active to active, this mechanism is built in. In case of active to passive there are three possibilities that guarantees semantics of the passive object.


Sequential: Only one active object is present
Guarded: multiple active objects should collaborate mutually exclusion
Concurrent: The supplier guarantees mutual exclusion

Aggregation

Links represent peer to peer or client/server relationship whereas aggregation represent whole/part hierarchy with the ability to navigate from whole  to parts hence aggregation is a kind specialized association. Agrégation may not always be physical containment. For example, a bell (part) on the bicycle handle(whole). It’s just adorned to the handle but not welded to it. Hence whole/part relationship is more conceptual and different from physical aggregation.

Advantage of aggregation is that it encapsulates part as the secret of the whole. Advantage of link is looser coupling.

Nature of Class

An object is a concrete entity that exists in time and space, a class is an abstraction and essence of that object. A class is a set of objects that share common structure, behavior and semantics. As it’s applicable to any “car” class. Also, a single object is an instance of a class. As it’s applicable to an “Alto Vxi” class.

An object is not a class. Similarly, a set of objects that don’t share common structure or behavior are class.

Programming can be viewed as contracting where a larger problem can be decomposed to smaller problems and subcontracted to different entities of the design.

An object as an instance of a class may have a limited role whereas a class is responsible for capturing structure and behavior of all its instances in the system. Thus, a class serves as a binding contract between an abstraction and its clients.

The view of contract leads to outside view and inside view of a class. The interface provides the outside view and emphasizes on the abstraction. This interface consists of all the methods as well as declaration of other classes, variables, constants, and exceptions as needed by the abstraction. The scope of an access to an interface can be categorized as public, private, protected and package. C++ has additional friend access. The variables and constants are known as data members in C++ serves as the internal state of its instance. The state is made as protected or private part of the interface. Thus, it’s encapsulated and changes to its representation should not affect the interface’s outside view.

The implementation is the inside view of the class hides the details of the implementation of the interface operations.


Relationships among Classes

Consider for a moment the similarities and differences among the following classes of objects:
A daisy is a kind of flower.
A rose is a (different) kind of flower.
Red roses and yellow roses are both kinds of roses.
A petal is a part of both kinds of flowers.
Ladybugs eat certain pests such as aphids, which may be infesting certain kinds of flowers.

The classes don’t exist in isolation. Relationship between classes can be established for two reasons:

First, class relationship might indicate some sort of sharing. For example, daisy and rose are some kinds of flower. This is a generalization/specialization, denoting “is a” relationship. Second, it might mean some kind of semantic relation. For example, red and yellow roses are more alike than daisies.

There is also whole/part of relationship between flowers and petals. Similarly, there is also a symbolic relationship between ladybug and flowers.

Association is a most general but semantically weak relationship among classes.

Another example for semantic dependency.

In practice, there are three common kinds of multiplicity across an association: One-to-one, One-to-many and Many-to-many.

Inheritance is used to express generalization/specialization relationships. . In inheritance a derived class shares behavior and structure from one (single inheritance) or multiple (multiple inheritance) base classes. An alternate is delegation where an object delegates their behavior to alternate objects.

During analysis and early stage of the design, a developer has two primary tasks:
  1. Identify classes from the vocal bury of the problem
  2. Invent structures whereby set of objects working together provide the function needed by the problem domain.

Collectively classes and objects are called key abstractions of the problem. The cooperative structures are called mechanism of implementation of the problem.

During early stages of development developer should focus on outside view of the key abstractions that provide class structure and object structures that represent logical framework. Later stages developer should focus on inner view that involves implementation of the key abstraction and implementation that makes physical representation.

Quality of an abstraction can be measured using five metrics:

Coupling measure of strength of association between modules from a connection. Strong coupling makes maintenance and understanding harder therefore weaker coupling is preferred. In classes and objects weaker coupling is needed however inheritance introduces strong coupling that helps commonality between abstractions.

Cohesion measures degree of connectivity between classes/objects in a single module. Coincidental cohesion is least desired as it mixes unrelated abstractions. Example, dogs and spacecraft as their behaviors are unrelated. Functional cohesion is desired where all the elements of a class or module come together to provide desired functionality. For example, a dog class is functionally cohesive if it addresses only dog’s behavior.

Sufficient means a class should capture enough characteristics of abstraction to permit meaningful and efficient interaction. For example, when designing a stack class, ignoring push or pop method would be a blunder.

Completeness means a class should capture meaningful characteristics of abstraction. For example, the stack class should return number of elements in the stack. Sufficiency means minimal interface. Completeness means all the aspects.

Primitivities means those operations that can be efficiently implemented if they are given access to the internal data structures. For example, push method for one element require access to the internal structure as it needs to be efficient. However, push method for 4 elements need not.

Creating interface is iterative process. After the first take, clients are created. The interface is further refined. Patterns of operations or patterns of abstraction can be discovered which leads to more classes and realignment of relationships.

We often can identify patterns of abstraction, structure, or behavior.

In a class, primitive methods are called as fine-grained methods. By separating out the methods that do not communicate with each other, it’s easier to construct derived classes that meaningfully redefine behavior of the base class The decision to implement a behavior in one method instead of breaking into multiple methods leads to simple interface but complicated method vs complicated interface with simple methods.

It's common to design methods of a class as a whole as all these methods cooperate to from entire protocol of the abstraction. Thus, given a desired behavior, following criteria can be used in which class to keep it.


Reusability: is the behavior applicable in another context
Complexity: how complex to implement
Applicability: how relevant to the class
Implementation knowledge: Internal details of the class needed

Once functional semantics are determined, time (performance) and storage (memory) semantics needs to be fixed. They are specified in big O and Omega notation as best, average and worst values. In multi-threaded applications, concurrency is also very important.

The law of Demeter says that a method should depend on the internal structure of its class or its base class. Also, messages should be sent to the objects of limited set of classes. As a result of this law, loosely coupled classes are created whose implementation details are encapsulated. They are also unencumbered meaning to understand these classes, knowledge of many other classes is not required. In terms of hierarchical class structures, wide and shallow represent forest of free-standing classes that can be mixed matched whereas narrow and deep represent trees of classes that are related by an ancestor. Forest classes are loosely coupled but they cannot exploit commonality. Trees of classes exploit commonality and smaller than forests.

The behavior of an object is more than sum of its parts hence aggregation of classes is better than inheritance.

Functionally cohesive, loosely coupled modules are desired. Factors such as reusability, security and documentation also influence this.

Summary

An object has state, behavior, and identity.
The structure and behavior of similar objects are defined in their common class.
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.
Behavior is how an object acts and reacts in terms of its state changes and message passing.
Identity is the property of an object that distinguishes it from all other objects.
A class is a set of objects that share a common structure and a common behavior.
The three kinds of relationships include association, inheritance, and aggregation.
Key abstractions are the classes and objects that form the vocabulary of the problem domain.
A mechanism is a structure whereby a set of objects work together to provide a behavior that satisfies some requirement of the problem.
The quality of an abstraction may be measured by its coupling, cohesion, sufficiency, completeness, and primitiveness.

Saturday, October 15, 2022

Fundamentals of Object Oriented Analysis and Design - Object Model - Part 02

 The following are the notes from Object Oriented Analysis and Design 3rd edition. 

Object oriented technology is built upon foundation of elements collectively known as object model.
Object model consists of abstraction, encapsulation, modularity, inheritance, type, concurrency, and persistence.  

The physical building block of a programming language is a module which consists of a logical collection of classes and objects. If procedures and functions are verbs and data is noun, object-oriented program is organized around noun. Thus, medium software applications look like graph with minimum global data.


A complex system consists of clusters of abstraction consisting of classes, objects and modules built on top of each other.  At each layer objects are collaborating to deliver high level behavior. Inside each cluster, yet another set of cooperative abstractions can be found.


Object oriented programming is a method of implementation where modules consist of a set of collaborating objects (“part of”) to deliver higher behavior; each object is based on a class (“is a”) which might be a member of a hierarchy of  classes.

Objects have integrity that cannot be violated. in other words, object’s invariant property cannot be altered. For example, an elevator can travel up and down.

Object oriented analysis focuses on the building real world models from object-oriented view of the world by examining the requirements to identify classes and objects in the vocabulary of the problem domain. The models will be the input for object-oriented design whose output will be blueprint for implementing the application using object-oriented programming languages.


Elements of the Object Model

An object model consists of 4 essential elements:
  • Abstraction
  • Encapsulation
  • Modularity
  • Hierarchy
and three non-essential elements:
  • Type
  • Concurrency
  • Persistence

Abstraction

Abstraction is the fundamental way to cope with the complexity.

Abstraction means identifying and focusing on similarities between objects, processes and situations in problem domain ignoring differences for time being. A concept is called abstraction only if it can be described, understood and analyzed independently of the mechanism that will be used to realize it. An abstraction denotes essential characteristics of the object and provides crisply defined conceptual boundaries from other objects focusing only on the perspective of the viewer.

Abstraction focusses only on outside view of its behavior so serves to separate an objects essential behavior from its implementation.

 

Deciding on the right set of abstractions for a given domain is the central problem in object-oriented design.

Abstraction Type

Description

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 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

 In contract mode programming, a server object exposes a contract or outer view that client objects depend on. The inner view of the server object implements it perhaps also collaborating with other objects. Each Operation in the contract has a unique signature with formal parameters and a return type.  The entire set of operations and the order in which a client calls the contract is called protocol. Thus, a contract dictates the static and dynamic outside views of a abstraction.

In abstractions, state invariants should be preserved pre and post operation. All abstractions have static and dynamic properties.

No object stands alone; they collaborate with others to achieve higher behavior. The design decisions decide boundaries, behaviors and protocols of each object.

Encapsulation

Abstraction should precede implementation and implementation details should be hidden from clients.

Abstraction and encapsulation are complimentary. Encapsulation is achieved through information hiding apart from data hiding. Information hiding is the process of hiding non-essential characteristics of an object.

By providing explicit barriers to abstractions, encapsulation ensures clear separation of concerns.

For abstraction to work in a class, its implementation should be encapsulated. In other words, a class should have two parts – an interface and implementation.

Abstraction is comprised of only outside view of a class common to all instances whereas implementation includes both abstraction and its implementation.

Modularization

Dividing a program into components attempts to reduce its complexity and also creates well defined and documented boundaries within the program. Modules comprises of a set of classes thus are multiple abstractions, to create an application’s physical architecture. In a large application comprising of hundreds of classes, modules are necessary.

Modularization means dividing an application into multiple modules that can be compiled separately but modules will have interconnections. 

Modules serve as physical containers of classes and objects of our logical design.

The goal of modular decomposition is to save cost where each module can be designed and revised independently such that it will not alter the abstraction upon which other modules are dependent. The cost of compiling a single module is less but the cost is high if its abstraction is changed as it will affect dependent module as well.

In other words, modules should be cohesive by grouping logically related abstraction and loosely coupled by reducing inter module dependency. The concepts of abstraction, encapsulation and modularity are synergistic.

Hierarchy

Often abstractions form hierarchy. Identifying these greatly during design simplifies understanding the problem domain. Hierarchy is basically ranking or ranking of abstractions.

Single Inheritance

Inheritance implies a generalization / specialization of hierarchy where derived classes inherit structures and behavior of base classes and often redefines certain behaviors.  The litmus test is if the class B is not type of class A, it should not inherit from class A.

Base classes are generalized abstraction and derived classes are specialization where members of the base classes are added, modified, and hidden. Therefore ignoring “is a” hierarchy leads to inelegant and bloated designs.

There is a healthy tension between abstraction, encapsulation and hierarchy. Abstraction creates an opaque barrier where data and methods are hidden; inheritance tries to open this interface and may allow accessing these without abstraction.  Thus, for a class there are two kinds of clints – an external object consuming its methods or its derived class.

Inheritance can violate encapsulation in three ways – access base class’s fields or methods, access base class’s base class directly. In C++ access to base class’s member in its derived class can be configured flexibly.

Multiple Inheritance

Multiple inheritance is the better way to express abstractions to eliminate redundancy. For example, two standalone base classes are created to capture unique properties of flowering plants as well as fruits and vegetables. These are called mixin classes as they are used to create derived classes by mixing together.

The Rose Class, Which Inherits from Multiple base classes

The Carrot Class, Which Inherits from Multiple base classes

 

The CherryTree Class, Which Inherits from Multiple Base classes

Multiple inheritance is straight forward but it introduces two practical problems:

  1. Clash when the same names are used for methods and fields in multiple base classes.
  2. Repeated inheritance of same base class where the inheritance lattice will be diamond shaped.
In C++, virtual bases class are used to overcome this.


The Repeated Inheritance Problem

 Ill formed inheritance lattices should be consolidated into one base class and other classes should be aggregated in derived classes.

Aggregation

“Is a” hierarchies   denote Generalization / specialization relationships whereas “part of” hierarchy denotes aggregation relationship. The combination of aggregation and inheritance is powerful. Aggregation lets grouping of logically related classes whereas inheritance allows of easy reuse of these classes in various abstractions.

In case of “is a” hierarchy, higher level abstraction is generalized and lower-level abstraction is specialized. Example, Flower class is at higher level of abstraction than the plant class. Similarly, in “part of” hierarchy, a class is at higher level of abstraction than the classes that makes it up its implementation. Example, Garden is at higher level than plants.

Aggregation introduces issues of ownership and lifetime. For example, when a car’s tires are changed, car’s identity is not changed. Similarly, when a car is recycled its tires are removed so that their lifetimes are not tied or tires can exist independent of the car. Whereas, lifetime of the chassis of the car is tied to it. In other words, chassis cannot exist independent of the car.

Typing

The concept of types originates from abstract types. Although concepts of type and classes are similar in nature, it’s included in object model because of it exerts different emphasis on abstraction.  Typing means enforcement of a class on an object such that it cannot be interchanged with other objects or done in a restricted way.

Typing lets expression of abstractions such that the programming used for implementation can make design decisions. A programming language can be strongly typed, weakly typed or even untyped. The idea of conformance is central to the notion of typing.  In strong typed languages may allow only certain combination of abstractions. In other words, strong typing restricts mixing of abstractions. However strong typing introduces semantic restrictions where single change in the base class require recompilation of the derived classes.


Advantages of strong type are:
  • Without type checking most application would crash 
  • Better documentation
  • Better code generation
  • Value of type in Safety offered is more than flexibility from untyped languages
Strong and Weak typing refers to type consistency. Static and dynamic typing refers to time when types are bound. In static binding types are known at compilation time; in dynamic binding runtimes are known only during runtime.

Polymorphism is a concept where dynamic binding and inheritance meet. In C++, polymorphism enables the methods decorated as virtual in derived classes to override base class implementation of the same method. It uses vtables to achieve it.

Opposite of polymorphism is monomorphism. Polymorphism is central to object-oriented design.

Concurrency

An automated systems such as a webserver may have to handle multiple requests at the same time. The solutions vary from use of distributed computers to multithreaded system for handling requests. An application has at least one thread of control, but a system having concurrency may have multiple threads- some transitory others exist for application’s lifetime.

A multithreaded application suffers from livelock, deadlock, thread starvation mutual exclusion and race condition. Concurrency can be avoided by hiding it in reusable abstraction in most cases.

While Object oriented programming focusses on data abstraction, encapsulation and inheritance, concurrency focusses on process abstraction and concurrency. An object concept unifies two viewpoints: an object drawn from abstraction of the real-world acts as a thread control (process abstraction.)  such objects are called as active objects.

Thus, world can be viewed as set of cooperative objects where some of them are active and serve as center of independent activity. Concurrency is the property that distinguishes active from non-active.

Once concurrency is introduced, key point is how two active objects synchronize with each other as well as sequential objects. For example, when two objects are sending message to a third object concurrency ensures mutual exclusion such that the state of the object is not corrupted.

This is where ideas of concurrency, abstraction, encapsulation interact. The semantics of defined methods should be preserved in presence of multiple threads of control.

The synergy between objects and concurrency leads to concurrent object-oriented programming languages.

Persistence

An object takes certain amount of space and lives for certain about of time. The duration can vary from transitionary in an expression to durable in a database.

This spectrum of object persistence encompasses the following:

Transient results in expression evaluation

Local variables in procedure activations
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 

The first three are addressed by programming languages and the last three are the domain of the database that can lead to clash of cultures. There is also a hybrid model such as ADO.NET where an application can stay disconnected from database.

The synergy between object-oriented programming and persistence leads to object-oriented databases. These are based on exiting database technologies such as relational database but provide object-oriented interface through which database queries are performed in terms of objects whose lifetime transcend its application’s life time. This allows same design methods to database and non-database segments of an applications. EJB and ORM software support object-oriented databases.


 Persistence saves the state and class of an object across time or space.

 Persistence deals with more than lifetime of the data. In object-oriented database, not only an object’s state must persist, but it’s class should transcend the application such that any application should interpret the state the same way. Thus, it will be difficult to maintain the integrity of the object-oriented database if the classes change often. In distributed computing scenario, the possibility of the object moving from system to system should be considered.

Persistency is the characteristic of an object where it transcends time (i.e., it continues to live after its host application terminates) and/or space (i.e., moves to another address space on the same machine or different machine).

Benefits of object model

First, the object model helps exploit the expressive power of object-oriented languages. Significant improvement in productivity and code quality has been achieved by applying data abstraction where it’s needed. Further improvements are achieved by using inheritance. Therefore, without using the elements of the object model, the powerful features of the object-oriented language are ignored or misused.

Second, the object model enables reuse of the software but also entire designs leading to creation of software frameworks. Thus, the code in object-oriented model will be less than non-object-oriented model.

Third, object model creates systems that are based on stable intermediate stable forms that are resilient to changes. Thus, they evolve over time instead of abandoned or completely redesigned when major changes are needed.

Finally, object mode appeals to human cognition.

Summary

The maturation of software engineering has led to the development of object-oriented analysis, design, and programming methods, all of which address the issues of programming-in-the-large.

There are several different programming paradigms: procedure-oriented, object-oriented, logic-oriented, rule-oriented, and constraint-oriented.
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.
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 is the property of a system that has been decomposed into a set of cohesive and loosely coupled modules.
Hierarchy is a ranking or ordering of abstractions.
Typing is the enforcement of the class of an object, such that objects of different types may not be interchanged or, at the most, may be interchanged only in very restricted ways.
Concurrency is the property that distinguishes an active object from one that is not active.
Persistence is the property of an object through which its existence transcends time and/or space.