Archive for the '7339' Category

Resoluciones del Nuevo Mes: Septiembre 2013

Wednesday, September 4th, 2013

Tiempo de revisar mis resoluciones del pasado mes:

– Actualizar SimpleProlog [complete] ver repo

– Actualizar Mass [pendiente] 
– Actualizar AjTalkJs [complete] ver repo

– Actualizar AjTalk [complete] ver repo

– Actualizar SimpleLisp [pendiente]

– SimpleLisp ejemplo web server [pendiente] 
– Nuevo Google Hangout usando Ruby con TDD [completo] ver post 
– Nuevo Google Hangout usando C# con TDD [completo] ver post

Otros items:

– Otro Google Hangout usando C# y TDD [completo] ver post

– Google Hangout using JavaScript and TDD [completo] ver post
– Google Hangout about Exploring MongoDB [completo] ver post
– Google Hangout about Code generation with AjGenesis for Ruby [completo] ver post

– Actualizar AjGenesis para Ruby [completo] ver repo     
– Actualizar AjGenesis para Node.js [completo] ver repo

– Nuevo módulo AjGenesisNode para Entities [completo] ver repo

– Comenzar nuevo módulo AjGenesisNode para Express [completo] ver repo

– Nuevo módulo Node SimpleUnit para testing [completo] ver repo

– Comenzar ScalaSharp, intérprete tipo Scala en C# [completo] ver repo

– Mejorar la left recursion en GrammGen [completo] ver repo

– Actualizar SimpleMongo [completo] ver repo

– Dar una charla sobre generación de código en AjGenesis para Ruby [completo] ver talks

y varios refactors de módulos node, usando SimpleUnit

Las resoluciones para el nuevo mes:

– Actualizar SimpleForth

– Dar una charla sobre SimpleMongo, SharpMongo

– Actualizar SimpleMongo

– Actualizar SharpMongo

– Actualizar PageJs

– Actualizar ScalaSharp

– Actualizar JPyScript

– Actualizar AjTalkJs

– Actualizar Mass scopes

– Empezar ejemplo Web Server usando AjTalkJs 
– Actualizar AjTalk

– Actualizar AjLispJs

– Ejemplo Web Server con AjLispJs

– Preparar charla sobre Scala

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Introducción a IoC y DI: Hello, world, flexible

Tuesday, July 13th, 2010

Dentro del Proyecto Hogwarts, estamos produciendo material para un curso de Inversion of Control y Dependency Injection, que quedará en línea (además de preparar alguna charla o taller presencial). No voy a explicar todavía los términos, sino que quisiera seguir otro camino: tomando la aplicación más simple, ir viendo de flexibilizarla, hasta llegar en algún momento a usar IoC y DI (siglas de los términos en inglés para Inversión de Control e Inyección de Dependencias).

¿Cuál es la aplicación más simple? Tomemos un clásico “Hello, world” en C# (espero publicar más adelante una serie de versiones en Java, que culmine con el uso de Spring Framework, como hago en mis cursos sobre el tema):

 class Program
 {
 static void Main(string[] args)
 {
 Console.WriteLine("Hello, world");
 }
 }

¿Qué podemos querer cambiar de esa aplicación? Se me ocurren dos cosas:

– El mensaje

– La forma de procesarlo

Son dos responsabilidades, que podemos asignarlas a dos clases nuevas, digamos, MessageProvider:

 public class MessageProvider
 {
 public string Message { get; set; }
 }

y a MessageProcessor:

 public class MessageProcessor
 {
 public MessageProvider Provider { get; set; }
 public void Process()
 {
 Console.WriteLine(this.Provider.Message);
 }
 }

Nuestro Hello World puede quedar ahora de esta forma:

 static void Main(string[] args)
 {
 MessageProvider provider = new MessageProvider() { Message = "Hello, World" };
 MessageProcessor processor = new MessageProcessor() { Provider = provider };
 processor.Process();
 }

Vean que creamos los dos objetos de dos clases concretas, y los “conectamos”: como el MessageProcessor necesita de un MessageProvider, se lo proveemos mediante una propiedad (podríamos haberlo hecho mediante un parámetro en el constructor). Lo que estamos haciendo es construir un grafo de objetos, y dada la forma en que colaboran entre ellos, el grafo lo armamos nosotros. La alternativa sería: DENTRO de MessageProcessor crear un MessageProvider y usarlo. Pero eso dejaría acoplada la responsabilidad de cuál mensaje procesar al propio MessageProcessor. De la forma adoptada arriba, si queremos cambiar el mensaje, NO ALTERAMOS el código de MessageProcessor. A este objeto “le llueve del cielo” su colaborador. Vemos la aparición de un camino a seguir: los “new” de los objetos colaboradores, no están en el código de los consumidores de esos colaboradores. Más adelante, pasaremos a ejemplos más de la vida real. Pero por ahora, exploremos estos temas con ejemplo sencillo. Luego, el problema (armar el grafo de objetos) y la solución (lo armamos “por fuera” de los objetos) será la misma, con variantes, en ejemplos medios y complejos.

Próximo paso: ahora que tenemos objetos que se hacen cargo de las responsabilidades que descubrimos, podemos refinar el ejemplo: ahora, MessageProcessor está acoplado a una clase concreta MessageProvider. Pero ¿qué necesita realmente MessageProcessor? En lugar de consumir un objeto de una clase concreta, ahora que tenemos un mini caso de uso codificado, podemos extraer, “descubrir” la interface que necesita consumir MessageProcessor. Y ya que estamos, también extraer, descubrir la interface, la conducta expuesta de cualquier MessageProcessor que se nos ocurra mañana. Pueden hacerlo a mano, o apelar a las capacidades de Refactoring, Extract Interface de Visual Studio. Tenemos IMessageProvider:

 public interface IMessageProvider
 {
 string Message { get; set; }
 }

IMessageProcessor:

 public interface IMessageProcessor
 {
 void Process();
 IMessageProvider Provider { get; set; }
 }

Y nuestras clases ahora implementan y esperan esas interfaces:

 public class MessageProvider : HelloWorldInterfacesExample.IMessageProvider
 {
 public string Message { get; set; }
 }
 public class MessageProcessor : HelloWorldInterfacesExample.IMessageProcessor
 {
 public IMessageProvider Provider { get; set; }
 public void Process()
 {
 Console.WriteLine(this.Provider.Message);
 }
 }

Vemos que MessageProcessor es UNA implementación de IMessageProcessor, y que no espera un MessageProvider, sino que se las arregla con cualquier implementación, actual o futura, de IMessageProvider. Como antes, él no se preocupa de crear esa instancia ayudante, sino que alguien proveerá.

Nuestra invocación queda:

 static void Main(string[] args)
 {
 IMessageProvider provider = new MessageProvider() { Message = "Hello, World" };
 IMessageProcessor processor = new MessageProcessor() { Provider = provider };
 processor.Process();
 }

Por ahora, no parece que ganemos mucho (para este ejemplo simple). Si tenemos que cambiar el proveedor del mensaje, el mensaje, o la forma de procesarlo (por ejemplo, que genere, en lugar de un mensaje en pantalla, otra cosa, como un archivo PDF o una página web), tenemos que tocar el código de nuestra rutina de inicio. Exploraremos cómo, ayudados por algún framework, conseguir que ese armado y esos datos se deleguen a configuración.

Código de los ejemplos en HelloWorldObjectsExample.zip y HelloWorldInterfacesExample.zip

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Agentes usando Concurrency and Coordination Runtime (CCR)

Friday, October 19th, 2007

En estos días, escribí un ejemplo mínimo, para explorar algunas ideas, usando el Concurrency and Coordination Runtime, la librería de Microsoft library que viene en su Robotics Studio. Más sobre CCR en el artículo:

Concurrent Affairs: Concurrency and Coordination Runtime

Mi idea es implementar el pase de mensajes entre componentes, de manera asincrónica. El código de ejemplo puede bajarse de AjAgentsCCR-0.1.zip

El agente

En el ejemplo, la interfaz a implementar por cada componente, que llamamos agente, es:

public delegate void ReturnHandler<T>(T t); public interface IAgent { void Post(Message msg); void Post(string action, params object[] parameters); void Post<T>(string action, ReturnHandler<T> handler, params object[] parameters); }

El agente puede recibir mensajes (que son objetos de una clase Message, ver más abajo). En el mensaje viene un texto con la Action a ejecutar (como si fuera un nombre de método) y una lista variable de parámetros.

El tercer método Post implementa un delegado, un método a ejecutar cuando el envío del mensaje produce una respuesta, un valor de retorno. Esa vuelta se produce en el futuro, no se queda esperando la respuesta. Podemos enviar un mensaje a otro agente, sin esperar la respuesta, o podemos escribir el delegado para procesar esa respuesta cuando llegue.

El mensaje

Es una clase con

action: un nombre que identifica la acción asociada al mensaje

body: el contenido del mensaje

response port: la puerta CCR donde enviar el valor de retorno, si es necesario

He aquí el código de esta clase:

 

public class Message { private string action; public string Action { get { return action; } set { action = value; } } private object body; public object Body { get { return body; } set { body = value; } } private Port<object> returnport; internal Port<object> ReturnPort { get { return returnport; } set { returnport = value; } } public Message() { } public Message(string action) { this.action = action; } public Message(string action, object body) { this.action = action; this.body = body; } public Message(string action, object[] bodyvalues) { this.action = action; if (bodyvalues != null && bodyvalues.Length == 1) this.body = bodyvalues[0]; else this.body = bodyvalues; } }

Notemos que el mensaje tiene puede manejar un arreglo de valores en el body, y que puede enviar un objeto dentro de su contenido.

La implementación

En este ejemplo inicial, la interfaz IAgent tiene una implementación basado en Invoke, via Reflection, que termina invocando un método en el agente, que tiene el mismo nombre que la acción recibida. Se pueden pensar otras formas de manejar el mensaje, pero esta manera permite codificar el agente como una clase más, con métodos normales.

El mensaje, una vez recibido, se coloca en una puerta CCR, para que se pueda manejar de manera asincrónica. Hay un Receive arbiter de CCR para atender los mensajes entrantes, que son ruteados al correspondiente método en el objeto.

Creo que es una solución interesante: se puede escribir una clase con métodos normales, y convertirla en agente, heredando de la clase Agent.

Podemos enviar un mensaje con

agent1.Post("Decrement",20);

Puede “consultar” algún valor con:

agent1.Post<int>("GetCounter", PrintCounter);

Próximos pasos

Estoy trabajando en:

  • Escribir un Enviroment, o clase Host, donde los agentes “vivan”. El Host sería responsable de mantener una lista de agentes por nombre.
  • Escribir un archivo de configuración donde pueda especificar qué agentes crear y cargar a comenzar a funcionar el Environment o Host, y que los relacione usando alguna implementación de inyección de dependencias. Me imagino servidores de agentes que pueda cargar un agente remoto de assemblies que se encuentren en otros servidores de la red.
  • Usar estos agentes en forma distribuida, con Windows Communication Foundation (WCF), o con Decentralized System Services (DSS). En este último caso, un servicio DSS podría ser un agente o podría representar la entrada a un Environment
  • Implementar algún patrón Subscribe/Notify entre agentes.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com/