Wenn es aufgeteilt werden soll und sich dann nicht alle Klassen gegenseitig kennen können, dann muß man sich einfach auf eine gemeinsame Basis beschränken, welche sich kennt und wovon dann alles Andere/Unbekannte abgeleitet wird.
Ich denka mal das letze Beispiel dürfte eher dem Pattern entsprechen.
Da gibt es dann passende Visitor, die wissen was zu machen ist
und welche über einer gemeinsame Basis aufrufbar sind.
Delphi-Quellcode:
unit BaseUnit;
interface
type
Visitor =
class;
Base =
class
public
procedure Accept(v : Visitor);
virtual;
abstract;
function Visit(v : Visitor) : Integer;
virtual;
abstract;
end;
Visitor =
class
public
procedure Visit(b : Base);
end;
implementation
{ Visitor }
procedure Visitor.Visit(b : Base);
begin
WriteLn(b.Visit(self));
end;
//...
end.
////////////////////////////////////
Schiff =
class(Base)
public
procedure Accept(v : Visitor);
override;
function Visit(v : Visitor) : Integer;
override;
// ...
property Kabinen : Integer
read Kabinenanzahl;
end;
function Schiff.Visit(v : Visitor) : Integer;
begin
if v
is Base
then
Result := Kabinen
else
...
end;
Wobei man auch auf Seiten des Visitors aufsplitten könnte, aber das wäre dann weniger flexibel.
Delphi-Quellcode:
unit BaseUnit;
interface
type
Visitor =
class;
Base =
class
public
procedure Accept(v : Visitor);
virtual;
abstract;
end;
StrBase =
class(Base)
public
function StrVisit() :
String;
virtual;
abstract;
end;
IntBase =
class(Base)
public
function IntVisit() : Integer;
virtual;
abstract;
end;
Visitor =
class
public
procedure Visit(b : Base);
end;
implementation
{ Visitor }
procedure Visitor.Visit(b: Base);
begin
if b
is StrBase
then
WriteLn(b.StrVisit);
else if b
is IntBase
then
WriteLn(b.IntVisit);
end;
//...
end.
oder
Delphi-Quellcode:
unit BaseUnit;
interface
type
TVisitType = (vtInt, vtStr);
Visitor =
class;
Base =
class
public
procedure Accept(v : Visitor);
virtual;
abstract;
funktion GetVisitType: TVisitType;
virtual;
abstract;
function IntVisit() : Integer;
virtual;
{abstract;}
function StrVisit() :
String;
virtual;
{abstract;}
// {...} vielleicht einen leeren Dummy verwenden,
// damit man nicht überall alles überschreiben muß
end;
Visitor =
class
public
procedure Visit(b : Base);
end;
implementation
{ Visitor }
procedure Visitor.Visit(b: Base);
begin
case b.GetVisitType
of
vtInt: WriteLn(b.IntVisit);
vtStr: WriteLn(b.StrVisit);
else ...
end;
end;
//...
end.
Eventuell kannst du auch den Visitor aufteilen.
Da kennt dann jeder Visitornachfahre seine Base-Class und weiß was mit ihr zu machen ist.
Delphi-Quellcode:
unit BaseUnit;
interface
type
Visitor =
class;
Base =
class
public
procedure Accept(v : Visitor);
virtual;
abstract;
procedure Visit(v : Visitor);
virtual;
abstract;
end;
Visitor =
class
public
procedure Visit(b : Base);
end;
implementation
{ Visitor }
procedure Visitor.Visit(b : Base);
begin
b.Visit(self);
end;
//...
end.
///////////////////////////////////////////////////////
unit StrBaseUnit;
interface
uses
BaseUnit;
type
StrBase =
class()Base
public
procedure Accept(v : Visitor);
override;
procedure StrVisit;
virtual;
abstract;
end;
StrVisitor =
class(Visitor)
public
procedure StrVisit(b : Base);
end;
implementation
{ Visitor }
procedure StrVisitor.StrVisit(b : Base);
begin
WriteLn((b
as StrBase).StrVisit);
end;
//...
end.