Mega Code Archive

 
Categories / Delphi / Examples
 

The 5 Relationships between Classes

Title: The 5 Relationships between Classes Question: 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 (1) - Association (2) - Aggregation (3) - Composition (4) - Dependency (5) - Realisation (6) 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; 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. There is much more details that can be described with the Class Diagram, but with a Tool ,e.g. ModelMaker or my book "UML mit Delphi, 2000", you'll get into touch ;) Update 26.4.03: New Book "Patterns konkret" or patterns in practice will be published at 3.Q. 2003 and shows a continuous use of patterns in model-driven projects.