Mirror

The 5 Relationships between Classes (Views: 706)


Problem/Question/Abstract:

How do we find related classes with the right UML-Notation, means which relationship belongs to which code ?

Answer:

Despite the fact that several advanced languages have come out of the OO Revolution, such as Java, C++, OP  a lot of people are still designing their code with minimal design in mind.
UML was formed in attempt to unify the best (or most popular in this case) modelling methods in Object-Oriented Analysis and Design. Let's focus on the Class Diagram and learn the 5 Relationships with OP (ObjectPascal).
So good up design will actually shorten the development cycle, give you an idea of the resources you need, and how to end the project.
The 5 Relationships are:

Inheritance
Association
Aggregation
Composition
Dependency
Realisation new UML 1.4  

The Class Diagram is the static architectural representation of your software and capable with a CASE-Tool to generate Code.  It allows you to see the overall object structure of the system.
Let's start with the Inheritance (Generalization). All Relations are represented by Fig.1, (download cd_busobj.tif) but also by Code:

1) Inheritance is represented by a triangle and TBusinessObj is a subclass of TDataModule1, inheriting all of the members (Attributes and Operations) of the superclass.

TBusinessObj = class(TDataModule1)
private
  function calcSalary(salary: double): Double;
  procedure changeGrade(amount: integer);
public
  constructor Create(aOwner: TComponent); override;
  destructor destroy; override;
  procedure changeSalary(amount: double);
  function getFullName: string;
  function getOldSalary: Double;
  function open_QueryAll: Boolean;
  function open_QuerySalary(qryID: integer): Boolean;
end;
  
2) Association is represented by a line, means a relationship at runtime. In Fig.1 seen by from TDataToXML. Association is not a tight coupling between objects, you call it and free it at runtime with local instances:

procedure TForm1.btnToXMLClick(Sender: TObject);
begin
  with TDataToXML.create do
  begin
    try
      dataSetToXML(datEmployee.query1, 'salaryXport.xml');
    finally
      free;
    end
  end;
end;

3) Aggregation is a whole-part relationship. A TDataModule1 has Queries from TQuery, so the white diamond is positioned near the container to represent the Queries are the parts of the DataModule. It means also a relationship at designtime, Query1 is a steady member of TDataModule1:

TDataModule1 = class(TDataModule)
  Database1: TDatabase;
  DataSource1: TDataSource;
  Query1: TQuery;
public
  procedure loadTree(myTree: TTreeView; fromFile: string);
  procedure storeTree(myTree: TTreeView; toFile: string);
end;

4) Composition is a stronger form of Aggregation. Composition is represented by a black diamond. For example in the VCL you can often find constructs like this: memo1.lines.add, so memo1 is TMemo and lines is TStrings. Means in our example if a class TForm1 has an instance and needs another instance too, there we have a composition:

procedure TForm1.fillEmployees;
begin
  with datEmployee.dataSource1 do
  begin
    while not dataSet.EOF do
    begin
      cmxEmployee.items.add(intToStr(dataSet.fieldValues['EMP_NO']));
      dataSet.next;
    end;
  end;
end;

5) Dependency is a dotted arrow and not shown in our diagram.  It is used to show that one UML Element depends upon another. Dependencies can be used to describe the relationship not only between classes, also packages, or components. In a Class Diagram you find it for ex. that one class depends on a type of another class and the class is part of a Library, like the VCL. In our case TDataModule1 depends upon TTreeView (TreeView uses ComCtrls). But it's TForm1 which really depends on TTreeView, cause the instance TTreeView1 is a member of the Form:

TForm1 = class(TForm)
TreeView1: TTreeView;

procedure TDataModule1.storeTree(myTree: TTreeView; toFile: string);
begin
  with TFileStream.create(toFile, fmcreate) do
  begin
    try
      writeComponent(myTree);
    finally
      free;
    end;
  end
end;

6) Interface support is like inheritance but there is a strict interface-specification and a class which supports the interface, marked in UML like a lollipop in the diagram or a dotted arrow from implement to interface:

IIncomeInt = interface(IUnknown)
  ['{DBB42A04-E60F-41EC-870A-314D68B6913C}']
  function GetIncome(const aNetto: Currency): Currency; stdcall;
  function GetRate: Real; stdcall;
  {.....}
  TIncomeRealSuper = class(TInterfacedObject, IIncomeInt)
  private
    FRate: Real;
    function Power(X: Real; Y: Integer): Real;
  protected
    function GetRate: Real;
  public
    constructor Create;

Interfaces works the same way in CLX or Kylix, as long as you don't use IDispatch from COM! So you don't need a MS-specific library to use interfaces.


Component Download: http://max.kleiner.com/download/businessobj.zip

<< Back to main page