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:
TAbstractFactory, TMySimpleFactory y TMyExtendedFactory:
Ejemplo de utilización:
Como resultado del ejemplo obtendremos:
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:
Comments
Post a Comment