Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing the Mediator pattern in Delphi without getting circular references

For those that are familiar with the Mediator pattern...

I want to implement the Mediator pattern in Delphi, but the Delphi compiler can't handle the circular references required.

Looking at the original GOF diagram from 'Design Patterns', the Mediator has a reference to each Colleague, but many of the Colleague objects have a reference back to the Mediator.

This is not a problem in most languages, but my Delphi compiler is giving me 'F2047 Circular unit reference to ...'

Would this approach, using interfaces, be any use? (seems complicated)

I am using Delphi 2010

[Summary of solution]

Just to summarise the accepted answer: In languages that allow circular references, you can omit the abstract Mediator class (as discussed in the "Implementation" section of GoF on page 278). The only way you can implement Mediator in Delphi without an abstract Mediator class is to have all your Classes in one Unit.

Otherwise, you need an extra abstract Mediator base class in addition to the concrete subclass.

Your Uses clauses for the three Units would look like this:

ConcreteColleage1 Uses Mediator
ConcreteMediator Uses Mediator, ConcreateColleague1
Mediator (Doesn't use either)

No circular references!

like image 286
awmross Avatar asked Jan 25 '11 05:01

awmross


3 Answers

Using interfaces can certainly help to decrease the dependencies between units. Another approach is to have abstract base classes which define the interaction methods between the classes and then put concrete descendants in separate units.

See: How to avoid circular unit reference? for more information on how to avoid circulare references in Delphi.

like image 126
Marjan Venema Avatar answered Nov 16 '22 22:11

Marjan Venema


I don't see where the circular dependencies arise. If you implement your classes following this diagram, no such thing should happen.

To implement this diagram in Delphi, you will indeed need to write

  • either a Mediator interface (and have your ConcreteMediator class implement this interface)
  • or a base Mediator class with virtual methods, (and have your ConcreteMediator class derive from Mediator and override these methods).
like image 5
LeGEC Avatar answered Nov 16 '22 21:11

LeGEC


Another option to consider is to place Mediator and Colleague in the same unit. In many situations that is the idiomatic Delphi way to avoid circular references.

Using interfaces is often a good approach to this sort of problem but sometimes it can result in extra complexity for no real gain.

It's hard to know where the tradeoffs would fall for your code so I wouldn't like to state that one approach is better than the other as a general rule.

like image 2
David Heffernan Avatar answered Nov 16 '22 21:11

David Heffernan