Sunday, October 16, 2022

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.

No comments:

Post a Comment