Ryan,

Reading through your post, I hope that you are aware that most circular dependencies can be avoided by referencing other units from the "uses" clause in the "implementation" section and keeping the "uses" clauses in "interfaces" down to those references strictly necessary for the unit's interface.

Having probably told you something you already know, i do sometimes get circular reference problems and usually because a program has evolved rather than having been designed properly. Sometimes it's better just to take as a hint to structure your program better but, otherwise, the techniques available are:

1. Abstract classes (as you suggest)

2. Interfaces

3. Dynamic casts.

Of the three, dynamic casts are often the quick and dirty way of fixing the problem as they can allow you to move a problematic unit reference from the "interface uses" to the "implementation uses", replacing the class reference in the unit interface to something generic like "TObject" and them coercing it to the required class when you actually use it.

I hope this helps.

Regards

Tony Whyman
MWA

On 14/04/16 05:29, Ryan Joseph wrote:
The most annoying problem I have with Pascal currently is with circular unit 
dependanices and “global” classes that need to be referenced from many units. In 
other languages I would make a forward declaration of the class in  one file then 
implement it in another file so that all files could reference the class. It’s maybe 
a symptom of a “bad" design but sometimes it’s just faster and easier so it’s a 
problem I have to fight Pascal to make it work.

When I moved to FPC the solution I started using was this pattern below where I 
make an abstract class then override the methods I need in the global namespace 
within in the “main unit”. This is a bad hack to workaround a feature of the 
language but I wonder if there’s a better way. Does anyone have any ideas I 
could try?

========

"global” unit shared by many other units:

type
   TSomeClassAbstract = class (TObject)
     procedure DoSomething; virtual; abstract;
   end;
“main” unit which implements the class: type
   TSomeClass = class (TSomeClassAbstract)
     procedure DoSomething; override;
   end;


Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to