Table of Contents

State of the Art


State of the Art


Object Orientation

Finding Data Types

Let us do an example. Imagine you are writing software for banks and bookkeepers and want to start developing a "data type library". One very basic data type is an account. What do we expect an account to do?

Used Types:

Account, owner (person/company), Deposit (money or papers), Character, Bool, ... .

What has to be done by the account?
Create the account
An account will be created for the owner with an initial deposit.
Delete the account
After deleting the account the deposit will be paid to the owner.
Add
Add the specified deposit item to the account.
Subtract
The amount will be given to the owner, if it is available on the account.
Print log
The internal data of the account will be displayed in a manner readable by a human being (character string).
                                                                           
   Types = (Account,Owner,Deposit (currency),                                     
             Character, Bool, ...)                                                          
                                                                                
                                                                                
   Operations                                                                  
                                                                                
        Create: Owner x Deposit -> Account,                                   
        Remove: Account -> Deposit,                                             
        Add : Account x Deposit -> Account,                                    
        Subtract: Account x Deposit -> Account,                                       
        Log : Account -> Character,                                       
        + : Account x Account -> Deposit,                                            
        = : Account x Account -> Bool,                                              
        ....                                                                    
                                                                                
                                                                                
   Equations (Axioms)                                                         
                                                                                
     Subtract (Add (account1,b),b)=account1                                    

The view of the user of an account is described above. This description therefore contains:

  1. no data definitions
  2. no algorithms for operations
  3. no implementation structures

Another easy example is the stack:

                                                                          
                                                                                
                                                                                
   Types = (entry,stack,bool) or                                              
           (stack(entry),bool)                                                  
                                                                                
                                                                                
   Operations                                                                  
                                                                                
        PUSH: entry x stack -> stack,                                           
        POP: stack -> entry x stack,                                            
        EMPTY: stack-> bool,                                                    
        l:  -> stack   ( equivalent to NEW: -> stack  ?)                                   
                                                                                
  l is an empty stack                                                       
                                                                                
        FULL : stack -> bool ?                                                  
                                                                                
                                                                                
   Examples (Axioms)                                                         
                                                                                
        POP(PUSH(e,s)) = e,s                                                    
        EMPTY(l) = true                                                       
        EMPTY(PUSH( , ))= false                                                 
        POP(l) = l  (or error object)                                             

Definition used by B. Meyer:

                                                                           
                                                                                
        POP: stack -> stack                                                     
        TOP: stack -> entry                                                     
                                                                                
        POP(PUSH(e,s)) = s                                                      
        TOP(PUSH(e,s)) = e                                                      

The target is to get simple interfaces and general useable data types. The principles we used here already are:

Encapsulation:
Internal data of a data type is only readable or changeable via operations.
Information hiding:
Interfaces of operations should not depend on implementation. This is a very difficult condition not always possible to achieve. But at least on the "abstract" level this should be realized. We come again to this point when we speak about class relations.

Discussion

Is it possible to implement abstract data types in classical languages? A lot can be done provided programmers are very disciplined. But this is of no more use if software has a long lifecycle. The programmers change often and a lot of code changes are required. But there are limits:

Objects

An abstract data type is the external description of an object. The specification of the data type defines the external interface and its behavior to be provided by the object. As mentioned in the chapter about abstract data types an object normally has additional axioms added to the specification. These additional axioms are necessary to provide the implementation selected. The object can be viewed as the real implementation of an abstract data type which is ready in storage to receive messages of the defined signature.

An object has two sides:

  1. Consumer side or user side defined by the abstract data type.
  2. Implementers side consisting of the internals of the object. This side is the implementation not visible by the user of an object.

How to use an object ?

Every object has methods to be executed when receiving a message.

                                                                             
 METHOD = PROGRAM executing an OPERATION of an abstract data type            

 MESSAGE = CALL of a METHOD. 

Methods and messages in different languages:

  1. Smalltalk
  1. C++

Example

  1. Smalltalk
                                                      
   5 square 
  1. C++
 MyDouble f=5,r;
 r= f.square; 

There are three ways to look on an object:

Implemented Data Type
The object is viewed as a piece of storage to be altered only by predefined operations.
Doughnuts
Objects have two parts enclosed: Implementers side around the user's side.
Persons
Objects are persons with predefined responsibilities.

Classes

In C++ a class consists of its declaration part (H-file) and its definition part (C-file). Unfortunately these two parts can be merged into one: i.e. all may be included to the H-file (and sometimes must be - for example inline methods). A good idea would have been to put into the header file only the external consumer side description of a class. In C++ even some internal or implementation parts of the description (protected members, internal methods) have to be included in the H-file.

The implementer's side of a class consists of the coded methods and the specification of internal variables. Here it is told how things are to be done. But this side is invisible from the consumer side. This is called information hiding. The consumer knows the behavior of a class - the interface. But he/she does not know how the class obtains the results returned by its methods and how the data is internally represented.

A class can be viewed in the following ways:

  1. A class is a collection of similar objects.
  2. A class is a template ('cookie cutter') for an object.
  3. An object is the realization of a class in the computer.

Classes can be ordered hierarchically. This is explained in the section about inheritance . A class contains:

Instance variables
In Smalltalk instance variables are pointers to objects describing the internal state of an object. In C++ instance variables are called data members. They may fully be included into an object and are not necessarily pointers. Whenever an object is created it gets its own copy of every instance variable defined.
Class variables
In C++ class variables do not exist as a concept of the language. But any static data member of a C++ class has the properties of a class variable. In Smalltalk class variables point to objects known to all objects of the class and are accessible by them. A class variable is instantiated only once for the entire class.
Methods
Coded methods for every operation are defined for the class and auxiliary internal operations.

Example :

Realization of the class Account in a classical language:

                                                                    
                                                                                
  DCL 1 KONTO BASED(*),                                                         
        2 KONTOID CHAR(8),                                                      
        2 BETRAG BIN FIXED(31),                                                 
        2 INHABER CHAR(240),                                                    
        2 ...;                                                                  
                                                                                
  EINZAHLE: PROCEDURE(KPOINTER,EBETRAG,KID);                                    
        ...                                                                     
    END;                                                                        

Usage:

                                                                           
                                                                                
   DCL KONTO1 CHAR(LENGTH(KONTO));                                              
   ...                                                                          
   CALL EINZAHLE (ADDR(KONTO1),200,'K147I');                                    

Realisation of class Account in Smalltalk:

                                                                      
  Object subclass: #Konto                                                       
     instanceVariableNames:'kontoid betrag inhaber ...'                         
     classVariableNames:'Bankleitzahllist'                                      
                                                                                
  einzahle: einBetrag                                                           
  " der uebergebene Betrag wird auf den Empfaenger eingezahlt "                 
  betrag := betrag + einBetrag. 

Class Account in C++

                                                                           
  class Konto {                                                           
  protected:                                                                              
     Int Kontoid;                                             
     Waehrung Stand;                                             
     Person* Inhaber; 
  public:                                             
     static Array Bankleitzahllist;                                         
                                                               
  public:                                                                             
     int Einzahle (const Waehrung & Betrag){
         Stand+=Betrag;
     }
                                        
     int Eroeffne (Person* cc, const Waehrung & Betrag){
        if (! cc-check()) return FALSE;
        Stand  = Betrag;                                                         
        Inhaber= cc;                                                         
        return TRUE; 
     }
  } // end class Konto

How are classes used?

There exist two types of methods:

Class methods
In Smalltalk the receiver of messages calling class methods is always a class. In C++ classes can never be the receiver of a message. Therefore most static methods are class methods. Class methods never operate on objects (exception is creation of an object) but on static class data. Constructors and destructors can be also viewed as class methods. In Smalltalk the method new creating a new object is a class method. Objects are never destroyed explicitly in Smalltalk. This is done by the garbage collector. In C++ no garbage collector exist.
Instance methods
Receivers of messages calling an instance method are always objects. Instance methods may alter the state of an object.

Example

Usage of Smalltalk class Account:

                                                                    
 k1 := Konto new .                                                              
 k1 einzahle: (DM new:200 ).  "DM subclass of Waehrung"

The method new allocates storage to the instance variables of k1. These instance variables still point to undefined objects. Therefore the method 'einzahle' will fail.

Instance method init

In most languages the constructor of an object will only allocate the storage needed for the object. The state data will normally be in an undefined state after creation. To initialize an object with valid default data an initialization method has to be included.

 
                                                                                
 init: einBetrag                                                                
    betrag := einBetrag.                                                        

class method eroeffne

                                                                           
                                                                                
 eroeffne: einBetrag                                                            
  ^(self new) init: einBetrag                                                  

Usage in C++

                                                                           
                                                                                
   Konto K1 ;                                                      
   /* similiar to K1:= Konto new */                                              
                                
   Person Person1;                                                     
   DM Betrag(200) ;  // DM subclass of Waehrung                                                 
                                                                            
   ....                                                                         
   K1.Eroeffne(&Person1,Betrag); //initialize state of K1    

   DM Betrag2(150);                                          
   K1.einzahle(Betrag2);                                                       

The declaration of K1 operates as new in Smalltalk. The state of the object K1 is undefined if no initialization is defined in the constructor method for class 'Konto'.

How To Build Classes

There exist to construction elements to build a new class from others. These are Aggregation and Inheritance. Inheritance will be described in the next chapter.

Aggregation

Aggregation means that an object A is part of another object B. B uses the object A. It can be used to describe the internal state of A, for identification of A (f.e. the database key of a business object) or other purposes. Aggregation is also called Client-Server relationship. The Client B is the user of the class A (the server). The client sent messages to objects of the used classes. By this the client 'delegates' responsibilities to its servers. There exist different aggregation types:

  1. Life time of server
    1. Permanent aggregation: all instance and class variables
    2. Temporary aggregation: all method parameters.
  2. Number of server
    1. 1:1- A client uses one object of the server class.
    2. 1:m - A client uses a collection of the server class (to be implemented by using collection classes).
    3. n:m - normally needs an own relation class.
  3. Visibility
    1. Internal - is the standard case in Smalltalk. In C++ all protected and private data members are internal.
    2. External- is equivalent to multiple inheritance. In Smalltalk an instance variable can only be made known external by coding getter/setter methods. In C++ every public data member is external. The server interface becomes part of the external interface of the client class.

Inheritance

Dynamic Binding

Design


Design Patterns(1995)


Even when object oriented methodology is used black box reuse seemed to be not possible in every case. At least sub classing with overwriting methods is often necessary. In the end object orientation brought software engineering a big step forward but did not reach all. So the question of reusability of designs arises.

As described in (13) in architecture 'patterns' are used to describe elements solving problems occurring again and again when designing a building. Such patterns can also be collected for software elements. Besides cataloging design ideas solving frequently arising problems patterns define a language in which we can explain and communicate designs.

Target of design patterns is:

  1. Communicate design techniques
  2. Catalog of reusable designs. This can be used to find a appropriate design for an akute problem to be solved without mixing several patterns which would limit reusability.
  3. Documenting design

Elements of patterns are

Name
The name should describe the purpose of the pattern. Factory is a pattern creating objects. Strategy is a pattern describing an algorithm.
Problem
This element describes when to apply this pattern and differences to similar patterns.
Solution
This element describes general arrangements of objects and classes but no concrete design. Here only a template for a design is given. Sample code/designs might be added.
Consequences
This is a list of additional behavior of a pattern. For example space/time tradeoffs, extensibility, etc.

An example of a design pattern is a Model-View-Controller (MVC). In a concrete Design the model would represent one or several business objects (f.e. figures in our graphical editor), the views would be the different presentations of figures (star character on printer page or graphical view on screen ...). A controller would be added if user interactions are defined.

For a further study of this matter have a look into (13). Own experience in OO design is recommended when studying this book.

Literature

_