[RESUELTO] Crear una sola instancia
Comenzado por
Rolphy Reyes
, ene 24 2010 11:08
10 respuestas en este tema
#1
Escrito 24 enero 2010 - 11:08
Saludos.
Compañeros en estos días he estado trabajando en crear mis propias acciones predefinidas en el ActionList para que queden de manera persistente. Este proceso es parecido al de crear componentes, cabe aclarar que no soy dado a crear componentes simplemente me fajo con mis clases.
Con lo anterior prácticamente no tengo problemas, la situación o problema surge en que tengo unos Datos guardados en la Base de Datos, entonces tengo un DataModule solo para esa tabla con una serie de métodos y propiedades que me devuelven la informaciones necesarias.
Veo que la única opción que tengo (hasta donde puedo percibir) es crear el DataModule cada vez por cada acción y ando buscando es crear el DataModule y que las acciones accedan a este sin tener que crear cada vez y que al final de la aplicación dicha instancia se destruya.
Espero ser claro.
Compañeros en estos días he estado trabajando en crear mis propias acciones predefinidas en el ActionList para que queden de manera persistente. Este proceso es parecido al de crear componentes, cabe aclarar que no soy dado a crear componentes simplemente me fajo con mis clases.
Con lo anterior prácticamente no tengo problemas, la situación o problema surge en que tengo unos Datos guardados en la Base de Datos, entonces tengo un DataModule solo para esa tabla con una serie de métodos y propiedades que me devuelven la informaciones necesarias.
Veo que la única opción que tengo (hasta donde puedo percibir) es crear el DataModule cada vez por cada acción y ando buscando es crear el DataModule y que las acciones accedan a este sin tener que crear cada vez y que al final de la aplicación dicha instancia se destruya.
Espero ser claro.
#2
Escrito 24 enero 2010 - 01:14
Hola Rolphy.
Creo que no acabo de entender el problema. Cada datamodule (al igual que los formularios) tiene asignada por defecto una variable global (que yo siempre elimino manualmente), y también por defecto Delphi lo añade para crear durante el arranque de la aplicación. Lo único que tienes que hacer es que al cerrar la aplicación se haga el cierre de esos datamodules (a los que puedes acceder mediante su variable global).
Si el problema está en que no quieres que se creen a menos que se necesiten, entonces elimínalos de la creación durante el arranque de la aplicación, y cuando vayas a utilizarlos, simplemente haz la siguiente comprobación :
if Assigned dmMiDataModule then Application.CreateForm(TdmMiDataModule, dmMiDataModule);
De la misma forma, al cerrar la aplicación solo tienes que hacer la misma comprobación :
if Assigned dmMiDataModule then dmMiDataModule.Free;
¿ Te refieres a esto ?.
Creo que no acabo de entender el problema. Cada datamodule (al igual que los formularios) tiene asignada por defecto una variable global (que yo siempre elimino manualmente), y también por defecto Delphi lo añade para crear durante el arranque de la aplicación. Lo único que tienes que hacer es que al cerrar la aplicación se haga el cierre de esos datamodules (a los que puedes acceder mediante su variable global).
Si el problema está en que no quieres que se creen a menos que se necesiten, entonces elimínalos de la creación durante el arranque de la aplicación, y cuando vayas a utilizarlos, simplemente haz la siguiente comprobación :
if Assigned dmMiDataModule then Application.CreateForm(TdmMiDataModule, dmMiDataModule);
De la misma forma, al cerrar la aplicación solo tienes que hacer la misma comprobación :
if Assigned dmMiDataModule then dmMiDataModule.Free;
¿ Te refieres a esto ?.
#3
Escrito 24 enero 2010 - 01:19
Saludos.
Disculpa, pero veo que en absoluto no comprendiste mi mensaje.
No tengo ese inconveniente, eso lo manejo a la perfección. Mi problema consiste en que estoy creando Acciones predefinidas y en una de ella necesito acceder a datos que están en la BD a través de un DataModule.
Como dije en mi mensaje anterior, por lo pronto visualizo que tengo que crear el DataModule cada vez que se instancia una acción y lo que quiero es crear una sola instancia del DataModule y que mis Acciones accedan a esta instancia y hagan lo que deben de hacer.
Espero ser más claro.
Disculpa, pero veo que en absoluto no comprendiste mi mensaje.
No tengo ese inconveniente, eso lo manejo a la perfección. Mi problema consiste en que estoy creando Acciones predefinidas y en una de ella necesito acceder a datos que están en la BD a través de un DataModule.
Como dije en mi mensaje anterior, por lo pronto visualizo que tengo que crear el DataModule cada vez que se instancia una acción y lo que quiero es crear una sola instancia del DataModule y que mis Acciones accedan a esta instancia y hagan lo que deben de hacer.
Espero ser más claro.
#4
Escrito 24 enero 2010 - 01:26
Hola Rolphy,
No termino de comprender.
¿Dices que por cada acción te ves obligado a crear un datamodule, y tu quieres evitarte esto y que accedan a un único datamodule?
Yo a decir verdad no le veo demasiado complicaciones invocando simplemente a dicha variable que por defecto define Delphi.
Quisiera en lo posible que seas un poco más gráfico. ¿Podemos ver un poco del código?
Te agradecería que nos comentes con más detalles porque no comprendo.
Saludos,
No termino de comprender.
¿Dices que por cada acción te ves obligado a crear un datamodule, y tu quieres evitarte esto y que accedan a un único datamodule?
Yo a decir verdad no le veo demasiado complicaciones invocando simplemente a dicha variable que por defecto define Delphi.
Quisiera en lo posible que seas un poco más gráfico. ¿Podemos ver un poco del código?
Te agradecería que nos comentes con más detalles porque no comprendo.
Saludos,
#5
Escrito 24 enero 2010 - 02:00
Saludos.
Si Delphius, me veo obligado a tener que crear una instancia de ese DataModule por cada acción, porque cada acción debe de buscar su correspondiente Registro en la Base de Datos.
Te muestro el código:
Esta unidad contiene la acción básica de donde las demás heredan.
Esta unidad es la que hace el trabajo.
Fíjense en el constructor TFwCallFormMDIAction.Create donde instancio el DataModule cada vez que se crea la Acción a eso es que me refiero.
Pero he optado por publicar unas propiedades a la acción y yo llenar desde el inicio de la aplicación esas propiedades, además analice que es más efectivo de este otra manera.
Si Delphius, me veo obligado a tener que crear una instancia de ese DataModule por cada acción, porque cada acción debe de buscar su correspondiente Registro en la Base de Datos.
Te muestro el código:
Esta unidad contiene la acción básica de donde las demás heredan.
delphi
unit UFWCustomAction; interface uses ActnList, Controls; type TFwClickModalResult = procedure (Sender: TObject; ModalResult: TModalResult) of object; TFwCustomAction = Class(TAction) private protected public function HandlesTarget(Target: TObject): Boolean; override; procedure UpdateTarget(Target: TObject); override; End; implementation { TFwCustomAction } function TFwCustomAction.HandlesTarget(Target: TObject): Boolean; begin Result := True; end; procedure TFwCustomAction.UpdateTarget(Target: TObject); begin if Target <> Nil then Enabled := True Else Enabled := False; end; end.
Esta unidad es la que hace el trabajo.
delphi
unit UFWCallFormAction; interface uses UFWCustomAction, Classes, Forms, SysUtils, UDmCustomConnDB, UFrmCustomViewMDIData, UFrmCustomViewModalData, UFrmCustomViewMantenimiento, UDmFormApplication, UTiposFW; type { TTipoVista = (tvMantenimiento, tvBusqueda, tvConsulta, tvReporte, tvProceso); TTipoOperacion = (toAgregar, toModificar, toBuscar, toConsultar, toMultiAgregar); //} TFwCustomCallFormAction = class(TFwCustomAction) private { private declarations } FFormId: Integer; FTipoVista: TTipoVista; FTipoOperacion: TTipoOperacion; FDmConnection: TDmCustomConnDB; procedure SetFormId(const Value: Integer); procedure SetTipoVista(const Value: TTipoVista); procedure SetTipoOperacion(const Value: TTipoOperacion); procedure SetDmConnection(const Value: TDmCustomConnDB); protected { protected declarations } property FormId : Integer read FFormId write SetFormId; property TipoVista : TTipoVista read FTipoVista write SetTipoVista; property TipoOperacion : TTipoOperacion read FTipoOperacion write SetTipoOperacion; property DmConnection : TDmCustomConnDB read FDmConnection write SetDmConnection; procedure Notification(AComponent: TComponent; Operation: TOperation); override; public { public declarations } constructor Create(AOwner: TComponent); override; end; TFwCallFormMDIAction = class(TFwCustomCallFormAction) private { private declarations } function IsActive(const AClassName : String) : Boolean; protected { protected declarations } FMyDmForm : TDmFormApplication; FMyFormMDI : TFrmCustomViewMDIData; FMyFormModal : TFrmCustomViewModalData; FMyFormMDIClass : TFrmCustomViewMDIDataClass; FMyFormModalClass : TFrmCustomViewModalDataClass; FMyFormMDIMantClass : TFrmCustomViewMantenimientoClass; public { public declarations } constructor Create(AOwner : TComponent); override; destructor Destroy; override; procedure ExecuteTarget(Target: TObject); override; published { published declarations } property FormId; property TipoVista default tvMantenimiento; property DmConnection; end; implementation uses UInstanciaMenu, StrUtil, UResourceFrameWork; { TFwCustomCallFormAction } constructor TFwCustomCallFormAction.Create(AOwner: TComponent); begin inherited Create(AOwner); FFormId := 0; FTipoVista := tvMantenimiento; FTipoOperacion := toAgregar; end; procedure TFwCustomCallFormAction.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (AComponent = FDmConnection) and (Operation = opRemove) then FDmConnection := Nil; end; procedure TFwCustomCallFormAction.SetDmConnection(const Value: TDmCustomConnDB); begin if FDmConnection <> Value then FDmConnection := Value; end; procedure TFwCustomCallFormAction.SetFormId(const Value: Integer); begin if FFormId <> Value then FFormId := Value; end; procedure TFwCustomCallFormAction.SetTipoOperacion(const Value: TTipoOperacion); begin if FTipoOperacion <> Value then FTipoOperacion := Value; end; procedure TFwCustomCallFormAction.SetTipoVista(const Value: TTipoVista); begin if FTipoVista <> Value then FTipoVista := Value; end; { TFwCallFormMDIAction } constructor TFwCallFormMDIAction.Create(AOwner: TComponent); begin inherited Create(AOwner); if not (csDesigning in ComponentState) then begin FMyDmForm := TDmFormApplication.Create(Self, DmConnection); end; end; destructor TFwCallFormMDIAction.Destroy; begin if not (csDesigning in ComponentState) then begin FMyDmForm.Free; FMyDmForm := Nil; end; inherited Destroy; end; procedure TFwCallFormMDIAction.ExecuteTarget(Target: TObject); begin FMyDmForm.SetLocate(FFormId); if not IsActive(FMyDmForm.FormClass) then begin Try case TipoVista of tvMantenimiento: begin FMyFormMDIMantClass := TFrmCustomViewMantenimientoClass(GetClass(FMyDmForm.FormClass)); FMyFormMDI := FMyFormMDIMantClass.Create(GetInstanciaMenuPrincipal, DmConnection, FMyDmForm.DataModuleClass, FMyDmForm.DialogClass); end; tvBusqueda, tvConsulta, tvReporte, tvProceso: begin FMyFormMDIClass := TFrmCustomViewMDIDataClass(GetClass(FMyDmForm.FormClass)); FMyFormMDI := FMyFormMDIClass.Create(GetInstanciaMenuPrincipal, DmConnection, FMyDmForm.DataModuleClass, TipoVista); end; end; FMyFormMDI.Show; Except on E : Exception do begin FMyFormMDI.Free; raise Exception.Create(E.Message + CLRF + StrFormNoRegistro); end; End; end; end; function TFwCallFormMDIAction.IsActive(const AClassName: String): Boolean; var I : Integer; begin Result := False; with GetInstanciaMenuPrincipal do begin for I := 0 to MDIChildCount -1 do begin if CompareText(MDIChildren[I].ClassName, AClassName) = 0 then begin If MdiChildren[i].WindowState = wsMinimized then MdiChildren[i].WindowState := wsNormal; MdiChildren[i].BringToFront; Result := True; Break; end; end; end; end; end.
Fíjense en el constructor TFwCallFormMDIAction.Create donde instancio el DataModule cada vez que se crea la Acción a eso es que me refiero.
Pero he optado por publicar unas propiedades a la acción y yo llenar desde el inicio de la aplicación esas propiedades, además analice que es más efectivo de este otra manera.
#6
Escrito 24 enero 2010 - 03:47
Permíteme que insista, ¿ porqué no puedes utilizar la variable global que declara Delphi en la clase del DataModule ?. De esta forma te aseguras que solo habrá una instancia del DataModule, la que esté asociada a esa variable global.
Si no quieres crear el DataModule en el momento de arrancar la aplicación, puedes hacer lo que te sugerí de comprobar si está creado en el momento de usarlo. Es decir, en el constructor TFwCallFormMDIAction.Create.
De esta forma, la primera vez que se use la acción de creará una instancia del DataModule, y cualquier uso posterior de la acción ya podrá reutilizar esa instancia.
Si no quieres crear el DataModule en el momento de arrancar la aplicación, puedes hacer lo que te sugerí de comprobar si está creado en el momento de usarlo. Es decir, en el constructor TFwCallFormMDIAction.Create.
De esta forma, la primera vez que se use la acción de creará una instancia del DataModule, y cualquier uso posterior de la acción ya podrá reutilizar esa instancia.
#7
Escrito 24 enero 2010 - 04:11
Saludos.
Gracias Marc por su interés. Pero no puedo crear el DataModule al arrancar la aplicación debido a como tengo codificado los mismos, de la manera en que están se le tiene que enviar a DataModule de conexión el debe de conectarse.
Hago esto porque con gano la posibilidad de que mis DataModule se puedan conectar a más de una BD.
Gracias Marc por su interés. Pero no puedo crear el DataModule al arrancar la aplicación debido a como tengo codificado los mismos, de la manera en que están se le tiene que enviar a DataModule de conexión el debe de conectarse.
Hago esto porque con gano la posibilidad de que mis DataModule se puedan conectar a más de una BD.
#8
Escrito 24 enero 2010 - 09:52
Hola Rolphy ahorita entiendo mejor, aunque me mareo un poquito con tanto código.
De lo entiendo lo que buscas es que cuando se crea la primer acción que se cree el correspondiente DataModule. En las siguientes creaciones de acciones buscas que éstas "apunten" y referencien al mismo DataMododule creado en la primera.
Si es eso tengo dos puntos de vistas:
1. Optar por la singletonmanía. Es decir que el DataModule a crear tenga el comportamiento de un singleton. Debo decir que al comienzo estaba pensado que podría tratarse de un caso viable de este patrón, pero necesitaba asegurarme si así lo fuera.
El patron singleton básicamente lo que establece es que exista y sólo se permita una instancia de una clase dada.
Espero que no ven malas intenciones en esto, pero una buena discusión, debate, análisis y ejemplos de como implementar un singleton puede verse en este hilo de CD.
2. Es posible, y entendible, que exista una pequeña anomalía y defecto en tu diseño. No cuadra totalmente la idea de que una "Acción" deba asumir la responsabilidad de crear un DataModule. Se le está atribuyendo una responsabilidad que, visto conceptualmente, no es deseable ya que se está acoplando dos clases que conceptualmente no tienen demasiada vinculación (es más, es un vínculo casual, débil) y perdiendo un poco de cohesión.
En principio (si bien hay sus excepciones) quien crea, es quien destruye. Y Esto lleva a la idea de un vínculo fuerte. De hecho, sería un escenario particular de agregación por composición 1-1.
El objetivo que tu planteas, a mi humilde punto de vista, va en contra. Observo una vinculación débil, que exista una referencia o visibilidad de atributo.
Simplemente se desliga la responsabilidad a la Acción de crear. Quien debe crear el DataModule es posible que sea otra clase (muy posiblemente quien administra y controla al grupo de las acciones).
Es decir el escenario sugiere que ni bien se crea la Acción se le asocia la instancia del DataModule.
Algo como esto:
o esto:
Obviamente en este escenario la Clase Accion debe ofrecer un campo o atributo que permite tener referencia al DataModule. Luego cuando esta Acción deba enviar un mensaje al DataModule al que está relacionada hace algo como:
Cuando se libera la Acción simplemente se asocia el puntero nulo y no se libera al DataModule al que estaba asociada.
Nota que los dos escenarios que he descripto no son mutuamente excluyentes. Si se opta por hacer al DataModule un singleton, las nuevas creaciones apuntarán a una único y mismo objeto.
Por otra parte si no se opta por hacerlo singleton bastará con hacer que cada Acción se asocie con el DataModule que se cree oportunamente y he aquí que incluso se puede aprovechar la tan cuestionada variable que nos ofrece Delphi.
Espero que se me entienda.
Me gustaría saber que opinan los demás. Es posible que hay algo que no esté viendo bien.
Saludos,
De lo entiendo lo que buscas es que cuando se crea la primer acción que se cree el correspondiente DataModule. En las siguientes creaciones de acciones buscas que éstas "apunten" y referencien al mismo DataMododule creado en la primera.
Si es eso tengo dos puntos de vistas:
1. Optar por la singletonmanía. Es decir que el DataModule a crear tenga el comportamiento de un singleton. Debo decir que al comienzo estaba pensado que podría tratarse de un caso viable de este patrón, pero necesitaba asegurarme si así lo fuera.
El patron singleton básicamente lo que establece es que exista y sólo se permita una instancia de una clase dada.
Espero que no ven malas intenciones en esto, pero una buena discusión, debate, análisis y ejemplos de como implementar un singleton puede verse en este hilo de CD.
2. Es posible, y entendible, que exista una pequeña anomalía y defecto en tu diseño. No cuadra totalmente la idea de que una "Acción" deba asumir la responsabilidad de crear un DataModule. Se le está atribuyendo una responsabilidad que, visto conceptualmente, no es deseable ya que se está acoplando dos clases que conceptualmente no tienen demasiada vinculación (es más, es un vínculo casual, débil) y perdiendo un poco de cohesión.
En principio (si bien hay sus excepciones) quien crea, es quien destruye. Y Esto lleva a la idea de un vínculo fuerte. De hecho, sería un escenario particular de agregación por composición 1-1.
El objetivo que tu planteas, a mi humilde punto de vista, va en contra. Observo una vinculación débil, que exista una referencia o visibilidad de atributo.
Simplemente se desliga la responsabilidad a la Acción de crear. Quien debe crear el DataModule es posible que sea otra clase (muy posiblemente quien administra y controla al grupo de las acciones).
Es decir el escenario sugiere que ni bien se crea la Acción se le asocia la instancia del DataModule.
Algo como esto:
delphi
Accion.ModuloDatos := MiDataModule;
o esto:
delphi
Accion.AsociarCon(MiDataModule);
Obviamente en este escenario la Clase Accion debe ofrecer un campo o atributo que permite tener referencia al DataModule. Luego cuando esta Acción deba enviar un mensaje al DataModule al que está relacionada hace algo como:
delphi
procedure Accion.ModuloDatosHacerEsto; begin FModuloDatos.HazEsto; end;
Cuando se libera la Acción simplemente se asocia el puntero nulo y no se libera al DataModule al que estaba asociada.
Nota que los dos escenarios que he descripto no son mutuamente excluyentes. Si se opta por hacer al DataModule un singleton, las nuevas creaciones apuntarán a una único y mismo objeto.
Por otra parte si no se opta por hacerlo singleton bastará con hacer que cada Acción se asocie con el DataModule que se cree oportunamente y he aquí que incluso se puede aprovechar la tan cuestionada variable que nos ofrece Delphi.
Espero que se me entienda.
Me gustaría saber que opinan los demás. Es posible que hay algo que no esté viendo bien.
Saludos,
#9
Escrito 25 enero 2010 - 03:12
Hola Rolphy.
Siento insistir, pero es que aún no entiendo donde está el inconveniente. Dices que no puedes crear los DataModule en el arranque de la aplicación por tal como están codificados, ¿ pero porqué no puedes crearlos al usarlos la primera vez ?.
Lo que te sugerí anteriormente es que en tu constructor TFwCallFormMDIAction.Create hagas esta comprobación :
if not Assigned(DmFormApplication) then DmFormApplication := TDmFormApplication.Create(Self, DmConnection);
Siendo DmFormApplication la variable global que crea Delphi con cada DataModule, y que por tanto apunta a una instancia única del DataModule.
NOTA: Por cierto, en el arranque de la aplicación también puedes hacer las llamadas a crear los DataModules, pasando por parámetro la conexión. Simplemente habrás tenido que crear antes el DataModule donde reside la conexión.
PD : Delphius tiene toda la razón cuando dice que la Acción no es lugar más elegante donde crear los DataModules.
Siento insistir, pero es que aún no entiendo donde está el inconveniente. Dices que no puedes crear los DataModule en el arranque de la aplicación por tal como están codificados, ¿ pero porqué no puedes crearlos al usarlos la primera vez ?.
Lo que te sugerí anteriormente es que en tu constructor TFwCallFormMDIAction.Create hagas esta comprobación :
if not Assigned(DmFormApplication) then DmFormApplication := TDmFormApplication.Create(Self, DmConnection);
Siendo DmFormApplication la variable global que crea Delphi con cada DataModule, y que por tanto apunta a una instancia única del DataModule.
NOTA: Por cierto, en el arranque de la aplicación también puedes hacer las llamadas a crear los DataModules, pasando por parámetro la conexión. Simplemente habrás tenido que crear antes el DataModule donde reside la conexión.
PD : Delphius tiene toda la razón cuando dice que la Acción no es lugar más elegante donde crear los DataModules.
#10
Escrito 25 enero 2010 - 07:04
Saludos.
Gracias Delphius y Marc por su interés en responder.
Después de un largo análisis he optado por publicar un par de propiedades a las acciones y realizar la asignación de valores al crearse la aplicación en vez de crear un DataModule desde la acción, creando dicho DataModule al inicio de la aplicación y su destrucción una vez terminada la asignación de valores.
Como bien mencionas Delphius no existe ese enlace fuerte entre ambas clases, además de ser ineficiente porque la acción tiene un solo registro en la BD y como lo planteaba al inicio cada vez que una acción se ejecutara se iba a buscar sus datos, tomando más tiempo y realizando request innecesarios.
El tema del singleton lo utilizo salvo que no sabía como se llamaba propiamente, ambos artículos que citaste están muy buenos e interesantes se le puede sacar gran provecho.
Gracias.
Gracias Delphius y Marc por su interés en responder.
Después de un largo análisis he optado por publicar un par de propiedades a las acciones y realizar la asignación de valores al crearse la aplicación en vez de crear un DataModule desde la acción, creando dicho DataModule al inicio de la aplicación y su destrucción una vez terminada la asignación de valores.
Como bien mencionas Delphius no existe ese enlace fuerte entre ambas clases, además de ser ineficiente porque la acción tiene un solo registro en la BD y como lo planteaba al inicio cada vez que una acción se ejecutara se iba a buscar sus datos, tomando más tiempo y realizando request innecesarios.
El tema del singleton lo utilizo salvo que no sabía como se llamaba propiamente, ambos artículos que citaste están muy buenos e interesantes se le puede sacar gran provecho.
Gracias.
#11
Escrito 25 enero 2010 - 09:05
Me alegro que se me haya entendido y haber ayudado a que encontraras la solución.
Si el tema de los patrones te interesa, yo en lo poco de experiencia que tengo, puedo recomendarte ampliamente el libro "UML y Patrones. Una Introducción al Análisis y Diseño Orientado a Objetos y al Proceso Unificado" De Craig Larman.
Es un libro excelente, relativamente sencillo de entender, y ofrece una mirada extra de lo que es y puede dar este maravilloso paradigma.
Como complemento a este el "UML Gota a Gota" de Marin Fowler y Kendall Scott. Este es más simple y menos técnico. Como contra, por querer ser simple se ha dejado muchas cosas al vuelo (a mi entender)
Zarko, en delphi.about.com elaboró unos artículos de excelente calidad (como lo acostumbrado) sobre algunos patrones. A mi me ayudaron a comprender mejor los patrones que he estado estudiando y analizando.
Recuerdo que había un sitio, en inglés por supuesto, que tiene una amplia recopilación de patrones ¡son cientos! Creo que tengo entre mis fuentes bibliográficas una referencia al sitio. Déjame buscar.
Saludos,
Si el tema de los patrones te interesa, yo en lo poco de experiencia que tengo, puedo recomendarte ampliamente el libro "UML y Patrones. Una Introducción al Análisis y Diseño Orientado a Objetos y al Proceso Unificado" De Craig Larman.
Es un libro excelente, relativamente sencillo de entender, y ofrece una mirada extra de lo que es y puede dar este maravilloso paradigma.
Como complemento a este el "UML Gota a Gota" de Marin Fowler y Kendall Scott. Este es más simple y menos técnico. Como contra, por querer ser simple se ha dejado muchas cosas al vuelo (a mi entender)
Zarko, en delphi.about.com elaboró unos artículos de excelente calidad (como lo acostumbrado) sobre algunos patrones. A mi me ayudaron a comprender mejor los patrones que he estado estudiando y analizando.
Recuerdo que había un sitio, en inglés por supuesto, que tiene una amplia recopilación de patrones ¡son cientos! Creo que tengo entre mis fuentes bibliográficas una referencia al sitio. Déjame buscar.
Saludos,