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.

No comments:

Post a Comment