##### 8.1.5.2 Distributed Object

If we want to implement the notification feature proposed in the previous section, we have to derive Term_Type. Such a derivation is possible in a remote types unit like NewTerminal (see below). Any object of type New_Term_Type becomes a distributed object and any reference to such an object becomes a fat pointer or a reference to a distributed object (see Term_Access declaration in Remote Access to Class Wide Types (RACW)).

         with Types, Terminal; use Types, Terminal;
         package NewTerminal is
            pragma Remote_Types;

            type New_Term_Type is
               new Term_Type with null record;

            procedure Notify
              (MyTerm   : access New_Term_Type;
               Payer    : in Customer_Type;
               Amount   : in Integer);

            function Current return Term_Access;
         end NewTerminal;

In the code below, a client registers his name and his terminal with RACWBank. Therefore, when any payer transfers some money to him, RACWBank is able to notify the client of the transfer of funds.

         with NewTerminal, RACWBank, Types; use NewTerminal, RACWBank, Types;
         procedure Term1Client is
            MyTerm   : Term_Access   := Current;
            Customer : Customer_Type := "poor";
            Password : Password_Type := "yyyy";
         begin
            Register (MyTerm, Customer, Password);
            --  [...] Execute other things
         end Term1Client;

In the code below, a second client, the payer, registers his terminal to the bank and executes a transfer to the first client.

         with NewTerminal, RACWBank, Types; use NewTerminal, RACWBank, Types;
         procedure Term2Client is
            MyTerm   : Term_Access   := Current;
            Payer    : Customer_Type := "rich";
            Password : Password_Type := "xxxx";
            Payee    : Customer_Type := "poor";
         begin
            Register (MyTerm, Payer, Password);
            Transfer (Payer, Password, 100, Payee);
         end Term2Client;

In the code below, we describe the general design of Transfer. Classical operations of Withdraw and Deposit are performed. Then, RACWBank retrieves the terminal of the payee (if present) and invokes a dispatching operation by dereferencing a distributed object Term. The reference is examined at run-time, and the execution of this operation takes place on the partition on which the distributed object resides.

         with Types; use Types;
         package body RACWBank is
            procedure Register
              (MyTerm   : in Term_Access;
               Customer : in Customer_Type;
               Password : in Password_Type) is
            begin
               Insert_In_Local_Table (MyTerm, Customer);
            end Register;

            procedure Transfer
              (Payer    : in Customer_Type;
               Password : in Password_Type;
               Amount   : in Positive;
               Payee    : in Customer_Type)
            is
               --  Find Customer terminal.
               Term : Term_Access
                 := Find_In_Local_Table (Payee);
            begin
               Withdraw (Payer, Amount);
               Deposit  (Payee, Amount);
               if Term /= null then
                  --  Notify on Payee terminal.
                  Notify (Term, Payer, Amount);
               end if;
            end Transfer;

            --  [...] Other services
         end RACWBank;