go - www - omdb api key free
¿Hay alguna forma preferida de diseñar API de señal o evento en Go? (5)
Estoy diseñando un paquete en el que deseo proporcionar una API basada en el patrón de observador: es decir, hay puntos en los que me gustaría emitir una señal que activará cero o más partes interesadas. Esas partes interesadas no necesariamente deben saber unos de otros.
Sé que puedo implementar una API como esta desde cero (por ejemplo, utilizando una colección de canales o funciones de devolución de llamada), pero me preguntaba si había una forma preferida de estructurar dichas API.
En muchos de los lenguajes o marcos con los que he jugado, ha habido formas estándar de crear estas API para que se comporten de la manera que los usuarios esperan: por ejemplo, las funciones g_signal_*
para aplicaciones basadas en glib, eventos y addEventListener()
para aplicaciones DOM de JavaScript. , o delegados de multidifusión para .NET.
¿Hay algo similar para Go? Si no es así, ¿hay alguna otra forma de estructurar este tipo de API que sea más idiomática en Go?
Go te da muchas herramientas para diseñar una api de señal.
Primero tienes que decidir algunas cosas:
¿Quieres un modelo push o pull? p.ej. ¿El editor envía eventos a los suscriptores o los suscriptores obtienen eventos del editor?
Si desea un sistema de inserción, que los suscriptores le den al editor un canal para enviar mensajes funcionaría realmente bien. Si desea un método de extracción, solo funcionará un cuadro de mensaje protegido con un mutex. Aparte de eso, sin saber más sobre sus requisitos, es difícil dar mucho más detalle.
Hay una versión básica de Golang de Node EventEmitter en https://github.com/chuckpreslar/emission
Consulte http://itjumpstart.wordpress.com/2014/11/21/eventemitter-in-go/
Necesitaba un tipo de "patrón de observador" en un par de proyectos. Aquí hay un ejemplo reutilizable de un proyecto reciente.
Tiene una prueba correspondiente que muestra cómo usarlo.
La teoría básica es que un emisor de eventos llama Submit
con algún dato cuando ocurre algo interesante. Cualquier cliente que quiera estar al tanto de ese evento Register
un canal del cual lee los datos del evento. Este canal que registró se puede usar en un bucle de select
, o puede leerlo directamente (o almacenarlo en búfer y sondearlo).
Cuando termines, te Unregister
.
No es perfecto para todos los casos (por ejemplo, es posible que desee un tipo de evento de anulación del registro de la fuerza para observadores lentos), pero funciona donde lo uso.
Yo diría que no hay una forma estándar de hacer esto porque los canales están integrados en el idioma. No hay una biblioteca de canales con formas estándar de hacer cosas con los canales, simplemente hay canales. Tener canales como objetos de primera clase integrados le libera de tener que trabajar con técnicas estándar y le permite resolver problemas de la manera más simple y natural.
Yo diría que un goroutine que recibe de un canal es un análogo de un observador hasta cierto punto. Una forma idiomática de exponer eventos en Go sería, por lo tanto, IMHO para devolver canales desde un paquete (función). Otra observación es que las devoluciones de llamada no se utilizan con demasiada frecuencia en los programas Go. Una de las razones es la existencia de la select statement
gran alcance.
Como nota final: algunas personas (yo también) consideran los patrones GoF como antipatrones Go.