Software Implementation

From EUDP
Jump to: navigation, search

What

Realising the classes into code

How

Implementation issues in software

Generally, we expect the developer to know the syntax and semantics of the selected language of implementation. This is not ment to be a tutorial in programming, but we will provide a few examples that hopefully will give a clearer understanding of how to implement the UML class diagram in code. Quite a number of the UML tools available on the market support code generation, so for those using such tools the set of advice below can be ignored.

Class Implementation

It is quite an easy task to implement classes. Take a look on the example below:

Tx oodocs 38a1a9c6d4.gif

The code shown here is in C++.

 class Example
 {
 public:
    Example () { Val = 0; };
    int getVal () { return Val; };
    void setVal (int val) { Val = val; };
    int Add (int val) { return Val + val;) };
 private:
    int Val;
 };

Please note that in the diagram there was no constructor nor setter nor getter for Val. The functions are implicitly implemented.

If the language of implementation is C, the code could look like this:

 typedef struct Example Example;
 struct Example
 {
    int Val = 0;
    int (*getVal) (Example* const this);
    void (*setVal) (Example* const this, int val);
    int (*Add) (Example* const this, int val);
 };
 int getVal (Example *this)
 {
    return this->Val;
 };
 void setVal (Example *this, int val)
 {
    this->Val = val;
 };
 int Add (Example *this, int val)
 {
    return this->Val + val;
 }

By embedding the class members into the struct , we get the closest implementation of the class/object thinking in a non class-oriented language.

Finally an example in Java:

 public class Example {
    private int Val = 0;
    public int getVal() {
        return Val;
    }
    public void setVal(int _Val) {
        Val = _Val;
    }
    public int Add(int val) {
        return Val + val;
    }
 }

Implementation of Associations

Associations can be implemented in different ways. The simplest is the uni-directional association.

Tx oodocs 0e371774c0.gif

In the above figure a directed association has been established to the class Assoc. An association can be implemented using a pointer. In C++ code like the following could be used:

 class Example
 {
 public:
    Example ()
    {
        Val = 0;
        assoc = new Assoc;
    };
    ~Example ()
    {
        if (assoc)
        {
            delete assoc;
        }
    }
    int getVal () { return Val; };
    void setVal (int val) { Val = val; };
    int Add (int val)
    {
        if (assoc)
        {
            return assoc->getX () + Val + val;)
        }
        else
        {
            return Val + val;
        }
    };
 private:
    int Val;
    Assoc *assoc;
 };

In this example the associated object Assoc is created by the constructor, but it can be done anywhere in the code. Remember that associations are "loose" relations, so the object could be created at anytime. In fact the implementation here is an aggregation - the object is created at the same time as the Example object and lives as long as the Example object does. Also please note that because of the creation of the Assoc object in the constructor, a destructor is needed to free the memory that the object occupied.

In C the association could look like this:

 typedef struct Example Example;
 typedef struct Assoc Assoc;
 struct Assoc
 {
    int x;
    int (*getX) (Assoc* const this);
 }
 int getX (Assoc* this)
 {
    return this->x;
 }
 struct Example
 {
    int Val = 0;
    Assoc assoc;
    int (*getVal) (Example* const this);
    void (*setVal) (Example* const this, int val);
 };
 int getVal (Example *this)
 {
    return this->Val;
 };
 void setVal (Example *this, int val)
 {
    this->Val = val;
 };
 int Add (Example *this, int val)
 {
    if (assoc)
    {
        return assoc->getX () + this->Val + val;
    }
    else
    {
        return this->Val + val;
    }
 }

In Java the association could be implemented like this:

 public class Example {
    private int Val = 0;
    public Assoc assoc;
    public int Add(int val) {
        return assoc.getX() + Val + val;
    }
    public int getVal() {
        return Val;
    }
    public void setVal(int val) {
        Val = val;
    }
 }

Aggregations and Compositions

Aggregations and compositions are longer time relations, which typically are implemented in the same way as shown for the association above.

Tx oodocs 5ae382dcfa.gif

I C++ an aggregation can be implemented inline.

 class Example
 {
   class Assoc
    {
    public:
        int getX () { return x; };
        void setX (int val) { x = val; };
    private:
        int x;
    }
 public:
    Example () { Val = 0; };
    int getVal () { return Val; };
    void setVal (int val) { Val = val; };
    int Add (int val)
    {
        return assoc.getX () + Val + val;)
    };
 private:
    int Val;
    Assoc assoc;
 };

Please note that the definition of the class Assoc is done inside the class Example. By instantiating the Assoc object within the Example object, the construct is in fact a composition. Use the pointer-based version shown previously, if the aggregated object does not have to be created at the same time as the "parent" object.

Bi-directional relations

If it is necessay to have a bi-directional association, aggregation or composition, it is typically implemented using pointers.

Tx oodocs 37a6d8472d.gif

In some situations the two associated objects are created by a third object. Consequently, methods for establishing the relation should be implemented. In C++ it could be implemented like this:

 class Assoc
 {
 public:
    int getX () { return x; };
    void setX (int val) { x = val; };
    void setExample (Example *p) { example = p; };
 private:
    int x;
    Example *example;
 }
 class Example
 {
 public:
    Example () { Val = 0; };
    int getVal () { return Val; };
    void setVal (int val) { Val = val; };
    int Add (int val)
    {
        if (assoc)
        {
            return assoc->getX () + Val + val;)
        }
        else
        {
            return Val + val;
        }
    };
    void setAssoc (Assoc *p) { assoc = p; };
 private:
    int Val;
    Assoc *assoc;
 };

It is the creating codes' responsibility to establish the association.

Relations with a multiplicity higher than 1

When the multiplicity exceeds 1 an extra class is often needed, rather than implementing the handling of the relation within the class cluttering up the code. The extra class handles the multiplicity. The extra class can be inherited from a general list class. In C++ the Standard Template Library has a number of lists available - likewise has other languages.

Why

After the thorough and carefully accomplished analysis and design, it is time to realise/convert the work into real code. In this task there should not be any surprises as to how the system should work albeit there is still work left to do.

As described earlier, there are still a number of things to consider in the implementation. We have recommended to disregard constructors, destructors, getters and setters . Thereby, it is still left to the developer to decide which methods to implement.

The EUDP method is not a tutorial in programming, hence only a few basic examples on how to implement the classes are shown. There are a great number of books focusing on this issue especially aimed at the implementation language of choice.