Implementando un Abstract Factory
Continuando con mi aplicación Thundax Geometry Link, necesito implementar un patrón Abstract Factory. Mediante éste patrón crearé diferentes familias sin especificar su clase concreta. Éste patrón es ideal cuando queremos aislar nuestra aplicación de la implementación de clases concretas. En el siguiente ejemplo podréis ver como genero la TAbstractFactory, que es la que me permitirá poder crear los objetos que yo quiero, una TBox, una TConnector y una TEllipse, pero que éstas haré que deriven de la TAbstractBox, TAbstractConnector y TAbstractEllipse, porqué quiero poder implementar varias familias por debajo de TAbstractBox sin que la factoría tenga que saberlo. Luego crearé 2 factorías, una simple y una extendida, donde configuraré la creación de mis clases. De ésta manera, en cada constructor de la factoría especificamos el objeto a devolver, sin especificar la clase concreta. En los ejemplos lo veréis más claro.El diagrama UML de mi ejemplo es el siguiente (Esquematizado):
Como podéis comprobar, antes solo existía la clase TBox, y ahora el diseño ha cambiado un poco. Ahora dispongo de mi TAbstractBox de la cuál hago heredar para conseguir diversos tipos de caja, en éste caso la TBox genérica y la TBoxExtended, la cuál dispondrá de más opciones y propiedades. Lo mismo pasa con las 2 otras clases. Pensad que el diseño de la aplicación va cambiado día a día y que ésto puede no ser algo definitivo.Bien, ahora para el diseño de la factoría tenemos:
Como podéis comprobar, las 2 factorías devuelven el mismo tipo de componente, pero en cada una se definen clases diferentes, aquí la poténcia de la Abstract Factory.Mi diagrama vendría a ser algo parecido, en el diagrama UML de ejemplo que hay en la web de A&P Web Consulting:

Queda bastante detallado en el diagrama, y en la wikipedia también encontraréis más información. Mirad también en los enlaces de interés, que he dejado también algún link.
El código fuente del ejemplo es el siguiente:
TAbstractBox, TAbstractConnector y TAbstractEllipse:
type
TAbstractBox = class(TObject)
function ToString(): string; virtual; abstract;
end;
TBox = class(TAbstractBox)
function ToString(): string; override;
end;
TBoxExtended = class(TAbstractBox)
function ToString(): string; override;
end;
TAbstractConnector = class(TObject)
function ToString(): string; virtual; abstract;
end;
TConnector = class(TAbstractConnector)
function ToString(): string; override;
end;
TConnectorExtended = class(TAbstractConnector)
function ToString(): string; override;
end;
TAbstractEllipse = class(TObject)
function ToString(): string; virtual; abstract;
end;
TEllipse = class(TAbstractEllipse)
function ToString(): string; override;
end;
TEllipseExtended = class(TAbstractEllipse)
function ToString(): string; override;
end;
{ TBox }
function TBox.ToString: string;
begin
result := 'This is a ' + Self.ClassName;
end;
{ TConnector }
function TConnector.ToString: string;
begin
result := 'This is a ' + Self.ClassName;
end;
{ TEllipse }
function TEllipse.ToString: string;
begin
result := 'This is a ' + Self.ClassName;
end;
{ TEllipseExtended }
function TEllipseExtended.ToString: string;
begin
result := 'This is a ' + Self.ClassName;
end;
{ TConnectorExtended }
function TConnectorExtended.ToString: string;
begin
result := 'This is a ' + Self.ClassName;
end;
{ TBoxExtended }
function TBoxExtended.ToString: string;
begin
result := 'This is a ' + Self.ClassName;
end;
TAbstractFactory, TMySimpleFactory y TMyExtendedFactory:
type
TAbstractFactory = class(TObject)
public
constructor Create;
destructor Destroy; override;
function GetBox(): TAbstractBox; virtual; abstract;
function GetConnector(): TAbstractConnector; virtual; abstract;
function GetEllipse(): TAbstractEllipse; virtual; abstract;
end;
TMySimpleFactory = class(TAbstractFactory)
public
constructor Create;
destructor Destroy; override;
function GetBox(): TAbstractBox; override;
function GetConnector(): TAbstractConnector; override;
function GetEllipse(): TAbstractEllipse; override;
end;
TMyExtendedFactory = class(TAbstractFactory)
public
constructor Create;
destructor Destroy; override;
function GetBox(): TAbstractBox; override;
function GetConnector(): TAbstractConnector; override;
function GetEllipse(): TAbstractEllipse; override;
end;
{ TAbstractFactory }
constructor TAbstractFactory.Create;
begin
end;
destructor TAbstractFactory.Destroy;
begin
inherited;
end;
{ TMySimpleFactory }
constructor TMySimpleFactory.Create;
begin
end;
destructor TMySimpleFactory.Destroy;
begin
inherited;
end;
function TMySimpleFactory.GetBox: TAbstractBox;
begin
result := TBox.Create;
end;
function TMySimpleFactory.GetConnector: TAbstractConnector;
begin
result := TConnector.Create;
end;
function TMySimpleFactory.GetEllipse: TAbstractEllipse;
begin
result := TEllipse.Create;
end;
{ TMyExtendedFactory }
constructor TMyExtendedFactory.Create;
begin
end;
destructor TMyExtendedFactory.Destroy;
begin
inherited;
end;
function TMyExtendedFactory.GetBox: TAbstractBox;
begin
result := TBoxExtended.Create;
end;
function TMyExtendedFactory.GetConnector: TAbstractConnector;
begin
result := TConnectorExtended.Create;
end;
function TMyExtendedFactory.GetEllipse: TAbstractEllipse;
begin
result := TEllipseExtended.Create;
end;
Ejemplo de utilización:
procedure TForm1.Button1Click(Sender: TObject);
begin
Factory := TMySimpleFactory.Create;
Memo1.Lines.add(Factory.GetBox.ToString);
Memo1.Lines.add(Factory.GetConnector.ToString);
Memo1.Lines.add(Factory.GetEllipse.ToString);
FactoryExtended := TMyExtendedFactory.Create;
Memo1.Lines.add(FactoryExtended.GetBox.ToString);
Memo1.Lines.add(FactoryExtended.GetConnector.ToString);
Memo1.Lines.add(FactoryExtended.GetEllipse.ToString);
end;
Como resultado del ejemplo obtendremos:

- Enlaces de interés:
%20applied%20to%20Transformer%20models%20in%20machine%20learning.%20The%20image%20shows%20a%20neural%20networ.webp)

Comments
Post a Comment