¿Cuántas veces hemos pensado que el diseño de nuestra aplicación, que en un principio era cojonudo, ahora no lo es tanto? ¿Cuántas otras nos hemos dado cuenta que después de un tiempo sin tocar nuestros desarrollos es complicado su entendimiento y mantenimiento?
Dependiendo del tipo de aplicación o componente Software que estemos diseñando, debemos tener en cuenta qué prima en el desarrollo del mismo. Por un lado tenemos el crear un buen diseño que permita desarrollos futuros sin desestabilizar lo ya realizado. Por otro está el siempre desquiciante tema de las optimizaciones que todo programador "tunea" de forma continua para hacer el algoritmo más rápido o el sistema más eficiente. Ésto es especialmente notable en tecnología gráfica y Networking.
El tema del rendimiento normalmente implica un pequeño caos en el desarrollo debido a que se tiende a concentrar mucho las operaciones que realiza una tarea determinada. Cuantas menos llamadas a funciones mejor; cuantas menos capas de clases mejor, etc. Prefiero tratar directamente con tipos primitivos locales que con Wrappers o adaptadores que no hacen otra cosa que llamar y llamar a otros de su calaña para obtener un mismo resultado a costa de una pérdida de rendimiento... Bien, todo esto está muy bien para secciones críticas del código y/o pequeños programitas pero no es muy recomendable en desarrollos de cierta envergadura.
Sólo hay que pensar un poco en el desarrollo en equipo de cualquier empresa del negocio del Software para darse cuenta que se precisa el trabajo coordinado de muchos para que cada parte/componente del sistema se integre correctamente y sea fácilmente mantenible por cualquier otro que esté especializado en ese área de desarrollo concreto. Aún así, sobrediseñar tampoco es bueno pues tiende a complicar un sistema que podría resolverse con menos abstracciones/subclasificaciones y yendo al grano en ciertas partes del mismo.
¿Dónde está el umbral entre un buen diseño y un código eficiente? Las mejores armas que tenemos a nuestro alcance es la experiencia y el profundo conocimiento de las herramientas utilizadas para lograrlo.
Ahí va una pildorita.
domingo, 25 de noviembre de 2007
domingo, 18 de noviembre de 2007
Singleton: el Gentleman
También conocido en mi ambiente de trabajo como chicletón :-D es quizá uno de los patrones de diseño más utilizados. Como muchos sabréis, asegura que una clase tenga una única instancia además de poseer la característica de ser un punto global de acceso a ella para toda la aplicación. Todo un caballero, sí señor...
En C# la forma más eficiente y segura de aplicar este patrón es la siguiente:
Es segura porque es el propio compilador el encargado de asegurar el Thread-Safe en la inicialización de la clase. Es eficiente porque evitamos la pérdida de rendimiento si utilizáramos una implementación mediante la cláusula volatile aplicando, por ejemplo, otro patrón interesante: Double Checked Lock. Veamos cómo:
Otra implementación podría aplicarse en genéricos a partir de Framework 2.0, ya que versiones anteriores no soportan esta característica en el lenguaje.
En C# la forma más eficiente y segura de aplicar este patrón es la siguiente:
public sealed class Singleton
{ private Singleton() {}public static readonly Singleton Instance = new Singleton();
}
Es segura porque es el propio compilador el encargado de asegurar el Thread-Safe en la inicialización de la clase. Es eficiente porque evitamos la pérdida de rendimiento si utilizáramos una implementación mediante la cláusula volatile aplicando, por ejemplo, otro patrón interesante: Double Checked Lock. Veamos cómo:
public sealed class Singleton
{ private Singleton() {}private static volatile Singleton instance;
private static object syncRoot = new object();
public static Singleton Instance
{get
{if (Singleton.instance == null)
{ lock (syncRoot) {if (Singleton.instance== null)
{ Singleton.instance= new Singleton();}
}
}
return Singleton.instance;}
}
}
Otra implementación podría aplicarse en genéricos a partir de Framework 2.0, ya que versiones anteriores no soportan esta característica en el lenguaje.
martes, 13 de noviembre de 2007
PagedGeometry: poderoso Add-on para Ogre3D
Echando un ojo hace unos días a la actualidad del motor gráfico OGRE3D se anunciaba la v1.0 de PagedGeometry, un espectacular plugin que renderiza zonas abiertas endiabladamente rápido.
La cantidad de árboles y hierba que representa en pantalla, incluyendo animación, es impresionante. Soporta LOD, geometría paginada (incluso dinámicamente), diferentes capas de texturas para el terreno...

Podéis ampliar más información aquí.
La cantidad de árboles y hierba que representa en pantalla, incluyendo animación, es impresionante. Soporta LOD, geometría paginada (incluso dinámicamente), diferentes capas de texturas para el terreno...
Podéis ampliar más información aquí.
miércoles, 7 de noviembre de 2007
Brainstorming de Game Engine
Estoy dedicando esfuerzos en mi tiempo libre (que no es mucho) en la creación de un "modesto" motor de juegos para prototipado rápido. Cogiendo ideas de aquí y allá he decidido basar el Core del sistema en servicios; muy similar a como está diseñado XNA pero yendo un poco más allá en aspectos como la abstracción o la multitarea. Cada servicio gestionará un aspecto concreto del motor (servicio gráfico, red, dispositivos de entrada, etc.). Lo interesante y desafiante desde mi punto de vista, del diseño de una arquitectura orientada a servicios, es el desacoplamiento de cada uno de ellos en el sistema pero con una posible interacción entre ellos de manera "transparente" (léase Interfaces conocidas evitando así la reflexión en la medida de lo posible).
Además, el Framework tiene que ser flexible y cómodo de extender para poder correr cada servicio implementado dentro del hilo principal de la aplicación (el juego) o en hilos adicionales. Todo ello sin que el programador (en principio yo mismo) requiera de conocimientos extensos sobre procesamiento en paralelo y demás hierbas. Un servicio implementado para la física del juego, por ejemplo, puede ser interesante que corra en un hilo aparte, de igual modo que el servicio de red.
Para que el código del juego en sí sea totalmente independiente de la implementación de cada servicio, será necesario crear adaptadores mínimos para los diferentes servicios que utilice el juego. Este punto tiene el inconveniente que nuevos servicios levantados "en caliente" en principio no podrán ser utilizados por el juego ya que no se ha definido el adaptador apropiado para él en tiempo de compilación ni código que lo gestione. Esto me lleva a pensar que toda la arquitectura orientada a servicios podría no tener mucho sentido pues cada uno de ellos debe ser conocido por el código del juego en sí. De todos modos, le daré vueltas a este asunto con más calma.
Para los servicios de gráficos y físicas tengo pensado utilizar Ogre3D y Newton (en concreto mediante los Wrappers de Mogre para .NET). En principio el de red lo intentaré implementar yo mismo (hay temas muy interesantes ahí como la latencia, dead reckoning ...) si tengo tiempo y buen ritmo de desarrollo.
Según avance iré desembuchando acerca de cómo llevo este asunto.
Además, el Framework tiene que ser flexible y cómodo de extender para poder correr cada servicio implementado dentro del hilo principal de la aplicación (el juego) o en hilos adicionales. Todo ello sin que el programador (en principio yo mismo) requiera de conocimientos extensos sobre procesamiento en paralelo y demás hierbas. Un servicio implementado para la física del juego, por ejemplo, puede ser interesante que corra en un hilo aparte, de igual modo que el servicio de red.
Para que el código del juego en sí sea totalmente independiente de la implementación de cada servicio, será necesario crear adaptadores mínimos para los diferentes servicios que utilice el juego. Este punto tiene el inconveniente que nuevos servicios levantados "en caliente" en principio no podrán ser utilizados por el juego ya que no se ha definido el adaptador apropiado para él en tiempo de compilación ni código que lo gestione. Esto me lleva a pensar que toda la arquitectura orientada a servicios podría no tener mucho sentido pues cada uno de ellos debe ser conocido por el código del juego en sí. De todos modos, le daré vueltas a este asunto con más calma.
Para los servicios de gráficos y físicas tengo pensado utilizar Ogre3D y Newton (en concreto mediante los Wrappers de Mogre para .NET). En principio el de red lo intentaré implementar yo mismo (hay temas muy interesantes ahí como la latencia, dead reckoning ...) si tengo tiempo y buen ritmo de desarrollo.
Según avance iré desembuchando acerca de cómo llevo este asunto.
Suscribirse a:
Entradas (Atom)
