Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-10-2015
doctorhd doctorhd is offline
Miembro
NULL
 
Registrado: abr 2013
Posts: 48
Poder: 0
doctorhd Va por buen camino
Gracias a todos por sus consejos y comentarios, la verdad no he investigado profundamente el tema de ORM y he ido construyendo el modelo que tengo en la medida que la necesidad a ido surgiendo, actualmente tengo un modelo de varias capas, una capa de negocios que se encarga de las validaciones y restricciones propias del negocio para con los datos, mas abajo una capa pivot que se encarga de direccionar los datos a la capa que interactua con la BD. Esta capa pivot la construí con el objetivo de permitir cambiar de proveedor de datos si así fuera necesario, por ahora trabajo con Firefird, pero la idea es extenderlo a SqlServer y Postgress. La capa que interactua con la BD recibe de la capa pivot los datos y los envía a BD, principalmente a través de procedimientos almacenados. Todo el manejo de inserciones, eliminación, update, select y demás se lo dejo a la BD (como dijo Mamcx para algo existe SQL). Solo llamo los store procedure que se encargan de realizar las tareas. Todo esto del lado del servidor y montado sobre datasnap. Por el lado del cliente la visualización de los datos a través de ClientDataSet y TDSProviderConexion.

Cita:
Lo que hace un micro-ORM es solo mapear una tabla a una clase, y ojala una clase "plana": Osea= Sin métodos, funciones ni propiedades complejas.
Efectivamente así lo realizo una clase plana que se envía del cliente al servidor, inicialmente lo contrui con record por su simpleza, pero tuve que cambiar a una clase porque datasnap no soporta el tipo record como intercambio de datos entre servidor y cliente.

Las clases Tfield y TDomain, me sirven de apoyo para configurar tanto del lado del cliente como del servidor las especificaciones de cada campo, como su longitud, tipo, valores permitidos, etc. Esto me es muy útil para el ingreso y validación de los datos que suministra el usuario.

Hasta ahora mi modelo a funcionado, no digo que sea perfecto y obviamente se puede mejorar, mas aun con la experiencia de otros que ya han construido modelos con el mismo objetivo. Y como alguien dijo por ahí, para que inventar la rueda de
nuevo.

mancx, voy a revisar los enlaces y temas que me has propuesto, para expandir mis conocimientos.

Gracias a todos, un saludo...
Responder Con Cita
  #2  
Antiguo 07-10-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
No "ensucies" tus clases con ese tipo de validaciones estilo "Length > 30, error, el maximo es 30". Tus clases solamente hacen su trabajo, el cual es hacer negocios.

Es muy molesto tener que, en cada setter acordarse de poner el "aqui solamente aceptamos numeros enteros!". Y de pronto como decis, no es un modelo muy flexible para andar cambiando. Incluso si queres desactivarlo seria terminar comentando medio codigo fuente. No es la tecnica mas efectiva. Y eso es, porque como se comenta en el otro hilo que hablamos este tema, OO no es la solucion a todo. Simplemente hay cosas que se resuelven mejor usando otro paradigma.

De la misma manera que cuando empiezas a ver las estructuras de datos en los primeros años que estudias programacion, te enseñan primero los simples loops iterativos, luego te dan recursion, y te das cuenta de que algunos problemas son triviales de resolver usando una u otra tecnica (ejemplo clasico de los arboles, a quien se le ocurriria usar un for para recorrer un arbol binario??).

Aca hay un ejemplo de como hacerlo usando atributos: Using attributes in Delphi

Tambien hay otra forma que es muy interesante y por lejos la mas flexible de todas, es utilizando Aspect Oriented Programming (AOP). En este video se explica como hacerlo en Delphi. AOP te permitiria, en una unit separada tener toda tu logica de validacion de datos. Solamente tocando aca, tuneas todas las validaciones que se te antojen. Esto quiere decir que tu sistema en general "no se va a dar cuenta nunca" de que alguien esta monitoreando los valores permitidos y los que no. Esto es bueno porque simplemente sacas la unit, recompilas y tadá! Ahora los nombres pueden tener todos los caracteres que de la gana.

Tambien quiere decir que seria trivial serializar los parametros de configuracion de las validaciones hasta en un tonto fichero ini y con solo unos toques ahi ya podrias por ejemplo permitir, ahora 31 caracteres en el nombre de los clientes porque al jefe de turno le parece lo mas adecuado

AOP es una tecnica sumamente poderosa, y como se explica en el video, es muy bueno para implemtentar este tipo de cosas de forma horizontal en todo el sistema, pero a la vez "transparentemente"; notar tambien los otros casos que menciona que son buenos para atacar con AOP: el Loggin. Si uno quiere andar guardando registro de todo lo que pasa, es muy molesto el tener que andar acordandose de hacerlo en cada metodo. Ademas de que molesta, porque uno cuando esta programando cierto metodo quiere concentrarse solo en lo que hace el metodo, no de avisarle a la clase logger "hey mira, entre al metodo IncrementarExistenciaProudcto, son las 3 AM del dia Martes xx/xx/xxxx, el usuario que disparo la accion se llama juan, tiene nivel de acceso modo-dios, los parametros son: [...]"
Responder Con Cita
  #3  
Antiguo 07-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Ahora entiendo por donde van los tiros...

Como lo menciona mamcx, existe casi un punto de inflexión entre la OPP y las tecnologías de bases de datos relacionales. Son paradigmas diferentes y las soluciones que tratan de conciliarlas son pobres e ineficientes. (Object Relational Impedance Mismatch)

No es que no se pueda poner un clavo con una pinza... Es sólo que para eso, es mejor el martillo.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo 07-10-2015
elrayo76 elrayo76 is offline
Miembro
 
Registrado: ene 2004
Ubicación: En la tierra, por eso mis archivos en la tierra y no en la nuebe...
Posts: 290
Poder: 21
elrayo76 Va por buen camino
Este tema me intereso mucho, ya que intento hacer algo similar y no se por donde comenzar.

Lo que en mi caso pretendo es hacer un especie de framework para la conexión con la base de datos para luego poder cambiarlo si es que cambia el motor de base de datos. Luego tendría como dijeron las clases con las propiedades que serían cada uno de los campos de la base.

Las distintas clases las usaría no solo para acualizaciónde datos, sino para consulta de los datos de las tablas, etc.

Para los tipos, tamaño etc de los campos de la base yo implementaria un diccionario de datos donde guardar esta información, así sería configurable por cada pantalla, ya que un mismo dato puede que en alguna pantalla necesite mostrarlo con un tamaño y en otra con otro (digo por no entrar en esa pantalla).

Lo que quisiera es que me orienten en como armar ese mini framework que quiero. También si saben de donde se puede sacar algún códio fuene de un mini-ORM para estudiarlo se los agradecería.

Saludos,
El Rayo
__________________
Si tienes una función o procedimiento con diez parámetros, probablemente hayas olvidado uno
Responder Con Cita
  #5  
Antiguo 08-10-2015
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.913
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por elrayo76 Ver Mensaje
Lo que quisiera es que me orienten en como armar ese mini framework que quiero. También si saben de donde se puede sacar algún códio fuene de un mini-ORM para estudiarlo se los agradecería.
Dapper, el que puse, es el mas "famoso" de esa categoria, al menos en lo que he visto. Si buscar en google veras muchos mas.

P,D: Me acorde que escribi sobre eso hace años:

http://edn.embarcadero.com/article/32388
http://blog.elmalabarista.com/post/4...h-un-mejor-rad

Que pueden verse como un micro-ORM, en pocas lineas de delphi

Cita:
hacer un especie de framework para la conexión con la base de datos para luego poder cambiarlo si es que cambia el motor de base de datos.
Un punto para ambos: Programar para el caso incierto, futuro de *si es que a lo mejor quien sabe, yo realmente se es X pero y que pasa si la luna se pone roja y toca usar Y???* es una de las formas mas *populares* entre nosotros los programadores de perder el tiempo.

Que tan igual es Firebird a Sql Server? Superficialmente, mucho, pero en la *practica*? A parte de los mas elementales SELECTs no hay mucho que se pueda compartir entre motores, Asi que piensen: Que es mas productivo, practico y realista: Hacer decenas de clases que intenten abstraer (aun mas de lo que el estandar SQL mas elemental + librerias de acceso a datos *ya hacen*) y todo el esfuerzo que eso implica VS hacer asi:

Código Delphi [-]

if Engine='sqlServer' then
   return 'SELECT sqlServer'
.....
.....

Chequen estas librerias:

https://github.com/krisajenkins/yesql
https://bitbucket.org/rick/jasql

El truco que tienen, muy obvio (y que en mis articulos apunte de una forma menos practica!) es que puedes convertir el SQL en "constantes". Usando jasql, uno tiene un archivo asi:

Código SQL [-]
-- name: create-user
INSERT INTO users (name, email) VALUES(@name, @email)

-- name: find-one-user-by-email
SELECT id,name,email FROM users WHERE email = @email LIMIT 1

"name: create-user" es un llave al sql, que desde el codigo se invoca asi:

Código PHP:
var jaSql JaSql.FromFile("queries.sql");
using (var cn = new SQLiteConnection("<your connection string here>"))
using (var jaRunner jaSql.CreateRunner(cn))
{
  
jaRunner.Execute("create-users-table");

  
jaRunner.Execute("create-user", new {name "John Doe"email "j.doe@verymuchnotalive.com"});
  var 
user jaRunner.Query<User>("find-one-user-by-email", new {Email "j.doe@verymuchnotalive.com"}).First();


Cita:
Las clases Tfield y TDomain, me sirven de apoyo para configurar tanto del lado del cliente como del servidor las especificaciones de cada campo, como su longitud, tipo, valores permitidos, etc. Esto me es muy útil para el ingreso y validación de los datos que suministra el usuario.
Ok, ya veo que lo que buscan tiene que ver con ORM, pero es mas acerca de como soportar el escenario de dejar configurable la app/tablas/formularios/etc.

Ahora es popular usar JSON en blob de una tabla para guardar arboles de objetos/configuraciones, pero antes que los hipsters entraran en escena uno simplemente usaba tablas con campos y ya. Por ejemplo, digamos que uno tiene:

Código PHP:
FormLogin =
  
user Num check notEmpty
  pwd 
Num check notEmpty
check user 
pwd 
Pues uno puede aceptar que eso exactamente, puede hacerlo la BD y generar el sql que construye esa tabla con esos checks. Si el formulario cambia, pues se hace DROP a la tabla y se recrea. Es ideal tener una BD de usuario dinamico separada de la estatica del sistema, que es muy facil en la mayoria de los motores, o usar SQLITE que se invento especificamente para esto: Para ser un excelente sistema de creacion de formatos de archivos personalizados (que reemplace .INI, .XML, etc)

Usando introspeccion se puede extraer mucho de una BD. Si el asunto se pone complejo es porque realmente se esta intentando re-crear un sistema de datos personalizado, y eso si que es complejo.

FoxPro efectivamente guardaba proyectos, formularios, reportes, tablas y base datos en tablas .dbf. Eso significaba que uno podia abrir un formulario y hacer el insert con un nuevo campo si se respetaba las reglas de como debe ser la informacion.

Pero eso tambien signfica que mientras mas personalizado quieras que el usuario haga sus formularios, informes, menus, etc mas cerca estas de re-inventar foxpro o acces.

Si ese es su objetivo, les digo que estoy haciendo eso, creando ese tipo de herramienta, y no me chocaria tener mas brazos El punto es que lo estoy haciendo en .NET + F#
__________________
El malabarista.

Última edición por mamcx fecha: 08-10-2015 a las 00:19:04.
Responder Con Cita
  #6  
Antiguo 08-10-2015
elrayo76 elrayo76 is offline
Miembro
 
Registrado: ene 2004
Ubicación: En la tierra, por eso mis archivos en la tierra y no en la nuebe...
Posts: 290
Poder: 21
elrayo76 Va por buen camino
Gracias por la respuesta.

De todo lo que escribiste, te puedo decir que no pretendo hacer un ORM. Lo que pretendo es hacer alguna forma de que los desarrolladores no tengan que escribir código SQL en las aplicaciones y solo llamen a métodos de las distintas clases para ejecutar alguna consulta

Lo que tengo en mente es algo como lo siguiente:

1) Se tiene una clase que solo contiene los campos de las tablas como propiedades con sus respectivos read y write. Ejemplo: TCliente.
2) Otra clase que hace uso de la anterior contendría todos los métodos necesarios para Listar, Cargar, insertar, actualizar, eliminar. Podría luego el desarrollador en estas clases crear métodos si se necesita haceer algo mas específico de lo que ya exista. Ejemplo: TClienteServicios.
3) Tener otra clase que solo sirva para hacer la conexión con las distintas bases de datos que sean necesarias (dentro del mismo motor de base de datos). Esta clase podría ser llamada en el constructor o de alguna forma por la clase anterior. Ejemplo: TConexion
4) Si se quiere y se necesita se tendría una clase para armar la condición (WHERE), pasando solamente el nombre del campo, el tipo de condición (=, <>, IN, >, <) y el valor a comparar contra el campo. Esta condición se pasaría por ejemplo al método Listar de la clase TClienteServicio para filtrar los resultados que trae.
5) Igual que el punto 4 se podría crear otra clase para hacer el ordenamiento de los datos devueltos por el Listar.

En principio lo pense con tablas, pero podría usarse con vistas. Y algo que deje de lado pero que hay que tener en cuenta es un método para ejecutar Store Procedures, pasando el nombre del mismo y los parámetros (puede haber mas cosas para evaluar pero eso es lo básico).

Saludos,
El Rayo
__________________
Si tienes una función o procedimiento con diez parámetros, probablemente hayas olvidado uno
Responder Con Cita
  #7  
Antiguo 08-10-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
[ Antes que nada quiero avisar que escribi un porron de post ]

Hola El Rayo

Vas encaminado, solamente me gustaria puntualizar unas cosas

Sigo pensando que el diseño no es lo mas flexible que podria ser. Yo no pensaria en un TCliente como una "clase que tiene los campos de las tablas con sus read y write". Vuelvo a remarcar lo que ya dije antes. Que representa para ti un cliente en tu negocio?. Recuerda lo que dijo Mario mas arriba: es como si fuera un simple y tonto record del Pascal antiguo. Simplemente contiene valores, y solo lo puede hacer en memoria. No sabe NADA de persistencia. A lo sumo podra hacer algun tipo de calculo sencillo pero nada mas.

El trabajo de persistencia es trabajo de otra clase. Porque? Sencillo, hay un "mantra" (principios SOLID) que dice que las clases deben tener solo una responsabilidad. Solo una mision. Nada mas. Si tienen que ocuparse de otra cosa, tenes en un 99% algo mal.

No hay que asustarse por tener un monton de clases (o mejor aun, clases implementando interfaces). Es un "error" comun en nosotros los desarrolladores mas nuevos; yo mismo a veces me pregunto a mi mismo: "tiene sentido crear la clase TPersona? si lo unico que tiene es una propiedad Nombre". La respuesta es SI, siempre. Hay que pensar en las clases como adolescentes vagos. Adolescentes tan o mas vagos como los de hoy en dia que no quieren ser responsables de nada, hacer lo minimo posible y lo mas facil y sencillo posible. Si tus clases son asi:

- El mantenimiento es mas sencillo. El impacto de cambiar algo es menor en todo tu sistema. Porque? Recuerda la simple clase TPersona de arriba que solo tiene un nombre, nada mas. Pues bien, las clases que usan a TPersona confian ciega y absolutamente que TPersona va a resolver un problema por ellos: darle el nombre de una persona!!!!!!!!. Y ese nombre puede venir de cualquier lado, puede haber un monton de codigo, complejos algoritmos de cifrado, etc detras de todo eso, pero no importa porque TPersona sabe hacerlo muy bien, verdad?

- Las clases son facilmente testeables. Imaginate tener que montar todo lo que necesita el framework solo para probar el funcionamiento "verdadero" del sistema. Ej, quiero probar una factura para ver como se imprime y resulta que: tengo que montar y configurar el gestor bd, montar la bd, cargar informacion de prueba. No seria mas sencillo poder hacer todo esto desde una app de consola? Si tu TCliente conoce una TABLA y los CAMPOS de esa tabla, como haces para separarlo de la tabla y poder probarlo? No hay manera

- Quiere decir que no solo podrias cambiar de motor de BD que estas usando; tu TCliente es tan poderoso que NO le importa de donde venga la data. Es algo muy sencillo que asusta. Tenes un servidor REST al que le pedis la data en formato JSON? A TCliente no le interesa. Eso es problema de una clase que se va a encargar de meter en TCliente la informacion correspondiente. Pero, una ves TCliente tenga su data, el va a saber calcular el Saldo o su Edad como lo hace siempre.

Otra cuestion interesante es el uso de interfaces. Hasta que uno no empieza a usarlas, no se da cuenta de su verdadero poder

La pregunta que todos nos hacemos en ese camino es: "pero cual es la diferencia??"

Código Delphi [-]
type
  TPersona = class
  private
    FNombre: string;
    procedure SetNombre(const Value: string);
  public
    property Nombre: string read FNombre write SetNombre;
  end;

Código Delphi [-]
type
  IPersona = interface
    function GetNombre: string;
    procedure SetNombre(const Value: string);
    property Nombre: string read GetNombre write SetNombre;
  end;

  TPersona = class(TInterfacedObject, IPersona)
  private
    FNombre: string;
    function GetNombre: string;
    procedure SetNombre(const Value: string);
  public
    property Nombre: string read GetNombre write SetNombre;

Repito, cual es la diferencia? El efecto logrado es el mismo, si. Bueno, al ahora descender de TInterfacedObject y no de TObject ganamos el reference counting y no tenemos que andar preocupandonos por manejar la memoria. Punto interesante.

El tema aca es el siguiente: hay, a grandes rasgos (no quiero hablar de patrones por ahora..) 3 formas basicas de crear un ecosistema de objetos

1. La clasica cadena de herencia. La herencia establece una relacion de "es un". Es decir, te dice de que tipo es el objeto

2. Composicion. Hay casos en los que usar herencia complica demasiado las cosas o no es deseable. Basicamente los casos en los que lo unico que cambia es "el tipo" pero en realidad estamos hablando de "lo mismo pero hecho con otras cosas". Un ejemplo muy clasico es el de la fabrica de pizzas: Imaginate tener, por cada combinacion de ingredientes, la clase de pizza que representa..

TPizzaBase, TPizzaQueso, TPizzaQuesoConSalchichas, TPizzaQuesoMantecosoConPapasFritas...

Entonces usamos composicion:

Código Delphi [-]
TPizza = class
private
  FListaIngredientes: TObjectList;
  FListaCondimentos: [...]

La composicion es como decir: este objeto esta hecho de estos otros objetos...es decir, agrupa a ciertos objetos que entre todos colaboran y hacen a la pizza

3. Interfaces. El caso de las interfaces, lo que cuesta tanto asimilar es, que demonios te dice una interface. El "problema" (mayor fortaleza) es que las interfaces es que no saben hacer nada. Solas no sirven para nada. Hasta que alguna clase las implementa, y puede ser una clase que cae dentro de los dos puntos anteriores. Entonces decimos: "vaya, aca tenemos un caso de herencia" porque vemos una implementacion PARTICULAR de esa interface. Lo que te dice una interface es que es lo que puede hacer una instancia.

No hay visibilidad (todo es publico). No hay "campos" (se pueden declarar propiedades pero nunca un atributo/variable). Cuando uno explora la declaracion de una interface lo primero que debe venirsele a la mente es: "Vaya, asi que esto es lo que puede hacer esta interface, que cool". No la nocion de su tipo, su herencia, etc.

De pronto, el ejempo anterior, en lugar de un IPerson deberiamos tener un INamed.. ya que esta interface sabe decirte tu nombre y nada mas. Que mas da que sea un TPerro, un TForm, un TColisionadorDeHadrones: Vos solamente vas a tener una referencia a INamed y solamente vas a poder llamar a su propiedad Nombre.

- Usa y abusa de Dependecy Injection. Que diablos es esto? Facil, nunca jamas dentro de una clase crees otra. Nunca. Jamas. En el 90 % es una muy mala idea. Si la clase que estas creando es una clase de tu dominio (es decir, no viene con Delphi) es en un 100% una mala idea. Porque? Porque eso quiere decir (dicho de la manera mas burda que se me ocurre) que si vas a la unit de la clase a la que creas, y borras la unit, o quitas la clase basicamente no podes compilar. Es decir, que la clase que crea a otra, tiene una dependencia FUERTE de otra clase. Esto es malo por varios motivos:

a) Como ya vimos antes, si alguien toca la clase en cuestion, puede afectar sobre tu clase
b) Que dijimos, que las clases solo tienen una responsabilidad? Crear una clase no es algo trivial. Y si el constructor falla? Y que es lo que sucede cuando se ejecuta el constructor? Se come un tocho de ram? Accede a disco? A un webservice? A una base de datos?
c) Complica el testing. Ya que siempre dependes de una implementacion (no de una abstraccion). Volvemos al ejemplo de montar el framework para probar

Dependecy Injection (DI de ahora en mas) es una sencillisima tecnica que soluciona los 3 problemas anteriores en un segundo: La clase en cuestion en vez de crear por si misma lo que necesita para funcionar (sus dependencias) lo pide de afuera. Muy facil de implementar. La mejor manera (y a mi gusto personal es la unica que le veo sentido, service locator me parece un anti patron en casi cualquier aplicacion y property/setter injection es incomodo) es mediante lo que se conoce como constructor injection. Es decir, tu clase pide en su constructor Create lo que necesita para trabajar. Ya que a ella solo le interesa unos pocos metodos de su dependencia. Tip: si lo que pides es una interface MEJOR.

Resumen DI:

a. No creas tus dependencias
b. Si necesitas algo PIDELO
c. Si pides una interface MEJOR
d. El constructor en el 90% de los casos debe ser simples asignaciones (lo que te enviaron para que uses mas adelante). Tambien es valido validar lo que te mandaron (si es nil lanzo una excepcion, etc)

Ejemplo practico

Código Delphi [-]
type
  IEncriptor = interface
    function Enctypt(const Value: string): string;
    function Decrypt(const Value: string): string;
  end;

  TXorEncriptor = class(TInterfacedObject, IEncriptor)
  public
    function Enctypt(const Value: string): string;
    function Decrypt(const Value: string): string;
  end;

  TGodModeEncriptor = class(TInterfacedObject, IEncriptor)
  public
    function Enctypt(const Value: string): string;
    function Decrypt(const Value: string): string;
  end;

Código Delphi [-]
  TPersona = class(TInterfacedObject, INamed)
  private
    FNombre: string;
    function GetNombre: string;
    procedure SetNombre(const Value: string);
  public
    constructor Create(const AName: string; AEncriptor: IEncriptor);
    property Nombre: string read GetNombre write SetNombre;

Bien, seguimos con la persona, y ahora vamos a encriptar su clave. Como lo hacemos: se lo pedmos a una interface. De esta forma en tiempo de ejecucion podemos incluso alterar facilmente el funcionamiento

Código Delphi [-]
var
  APerson: INamed;
begin
  if CheckBoxMaximumSecurity.Checked then
  begin
     APerson := TPerson.Create('Agustin', TGodModeEncriptor.Create);
  end
  else
  begin
    APerson := TPerson.Create('Agustin', TXorEncriptor.Create);
  end;

Imaginate como seria unit testing. Cuanto tiempo tardas en crear una clase TNotEncript que devuelva el mismo valor que se le manda (siempre y cuando en ese momento no te interese que el nombre este encriptado). A TPersona le importa? No, el va a llamar y confiar ciegamente en el metodo Encrypt

Con esto creo que si bien me fui mucho por las ramas te di un par de tips que te ayudan en algo (espero)

Saludos

Última edición por AgustinOrtu fecha: 08-10-2015 a las 03:46:46.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Class Helpers sobre Genericos.. yapt OOP 1 24-04-2011 16:06:17
Procedures Genericos con Parametros de Controles.... Kenobi Varios 23 21-11-2007 00:42:41
Listbox con items genericos ANG4L Varios 2 11-05-2006 03:54:37
Parametros sql genericos AbcXxx Conexión con bases de datos 2 10-11-2005 00:31:59
... 100 tipos... Jure Humor 0 18-03-2004 14:24:30


La franja horaria es GMT +2. Ahora son las 05:20:36.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi