Table of Contents

State of the Art

  • Object Orientation (1980)
  • What is OO ?
  • Finding Data Types
  • Objects
  • Classes
  • Inheritance
  • Dynamic Binding
  • Design with classes
  • Relations between datatypes implemented in languages:
  • How to Design Classes
  • Rules for working with class libraries
  • Design Patterns(1995)

  • State of the Art


    Object Orientation

    What is OO ?

    Information Hiding
    leads to minimal interfaces and a distinction of user and implementor view
    Abstract Datentyps (Encapsulation) Data and operations are packed tobether.
    Way for Reuse

    Finding Data Types

    Let us do an example. Imagine you are writing software for banks and bookkeepers and want to start developing an "data type library". One very basic data type is an account. What do we expect an account has 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 payed to the owner.
    Add
    The amount added to the account can later be subtracted if no other bookings (subtractions) are done inbetween.
    Subtract
    The amount will be given to the owner, if its available on the account.
    Print log
    The internal data of the account will be displaed 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 (Axiome)                                                         
                                                                                    
         Subtract ( Add(account1,b),b)=account1                                    
    

    Abover the View of the user of an account is described.

    1. no data defined
    2. no algorithms for operations
    3. no implementation structures
    Another easi 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,                                                    
            lam :  -> stack   ( NEW: -> stack  ?)                                   
                                                                                    
            lam = empty stack                                                       
                                                                                    
            FULL : stack -> bool ?                                                  
                                                                                    
                                                                                    
       Examples (Axiome)                                                         
                                                                                    
            POP(PUSH(e,s)) = e,s                                                    
            EMPTY(lam) = true                                                       
            EMPTY(PUSH( , ))= false                                                 
            POP(lam) = lam oder error ?                                             
    

    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 hard condition not always to archieve. But at least on "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 ? There can be done a lot with big discipline of the programmers. But this is of no more use if software has a long lifecycle. The programmers change often and a lot of changes are done. Example where it was done: Building Blocks at IBM Lab Boeblingen. But there are limits:

    Objects

    ABSTRACT DATA TYPE = EXTERNAL DESCRIPTION OF AN OBJECT

    OBJECT = COMPLETE IMPLEMENTED ABSTRACT DATA TYPE READY TO RECEIVE MESSAGES.

    An object has two sides:

    1. consumer side (user)
    2. implementor side

    How to use an Object ?

    Every object has methods to be executed when receeiving 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
    2. C++

    Example

    1. Smalltalk
                                                            
         5 square 
      
    2. C++
       MyDouble f=5,r;
       r= f.square; 
    There are three ways to look on an object:
    implemented Data Type
    piece of storage to be altered only by predefined operations.
    doughnuts
    objects have two parts enclosed: Implementor side around: User 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 - f.e. inline methods). A good idea would have been to put into the header file only the external r consumer side description of a class. In C++ even some internal or implementation parts of the description (protected members, internal methods) has to be included in the H-file.

    The implementor side of a class consists of the coded methods and the specificaton 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 infomation hiding. The consumer knows the behaviour 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 similiar objects.
    2. A class is a template ('cookie cutter') for a 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 clalled data members. They may fully be included into an object and not only be 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 he class and are accessible by them. A class variable is instantiated only once for the entire cass.
    methods
    coded method for every operation defined for the class.

    Example :

    Realisation 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;                                                         
            retrn TRUE; 
         }
      } // end class Konto
    

    How classes are 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 destroed explicitely in Smalltalk. This is done by the garbage collector. In C++ no garbage collector exist.
    instance methods
    Receivers of messages calling a 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

                                                                               
                                                                                    
     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 constuctor method for class Konto.

    Inheritance

    Dynamic Binding

    Design


    Design Patterns(1995)


    Even when object oriented methodology is used black box reuse seem to be not possible in every case. At least subclassing 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 (12) 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. Beside 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
    describes when to apply this pattern and differences to similiar patterns.
    solution
    describes general arrangemants of objects and classes but no concrete design. Here only a template for a design is given. Sample code/designs might be added.
    consequences
    list additional behaviour of a pattern. F.e. space/time trade-offs, extensibility, etc.

    An example of a design pattern is a Model-View-Controler (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.

    Literature