Uso del patrón de estrategia para controlar la agrupación de datos
Por Allen Fung y Ajay Lakshminarayanarao
Un producto ShareThis importante es el feed de datos sociales, que nuestros clientes utilizan para acceder a las señales sociales a través de Internet y consumir datos a nivel de país sobre eventos sociales generados en todo el mundo. El feed de datos sociales es un archivo que contiene un evento para cada página web que nuestros usuarios han visto. Este archivo contiene alrededor de 500 millones eventos diarios. Un evento contiene información, como URL, geo y timestamp. Un cliente solicitó recientemente que pongamos los eventos en varios archivos, basándonos en el país de origen, en lugar de un solo archivo.
Usamos el patrón de estrategia para resolver este problema. Esto nos permite apoyar la nueva funcionalidad, así como preservar la original. El patrón de estrategia permite que un objeto tenga parte de su comportamiento definido en términos de otro objeto que sigue una interfaz. Usamos el patrón de estrategia creando dos nuevos objetos. Uno de ellos tenía un método que devolvía el país de un acontecimiento. El otro tenía un método que siempre devolvía una cadena vacía, sin importar el evento que se proporcionara.
Aquí está la estrategia que devolvió el país:
class GroupByCountry:
def doOperation(self, json):
return json[‘geo’][‘ISO’]
Esta es la estrategia que siempre devolvió la cadena vacía:
class NoGroupBy:
def doOperation(self, json):
return “”
El siguiente código muestra cómo se utilizan estas estrategias en la aplicación que crea el feed de datos sociales. Esta aplicación toma un archivo de registro de un servidor Web, agrega información a cada evento y envía archivos con la información agregada. Puede ver el patrón de estrategia utilizado en la línea 5 del código. La aplicación producirá varios archivos o un solo archivo en función de la estrategia que se pase al método Run.
def run(file, writer, worker, outFilename, strategy):
with open(file) as f:
for line in f:
json = worker.addInfo(f)
country = strategy.doOperation(json)
writer.write(outFilename + ”.” + country, json)
writer.close()
La principal alternativa a las estrategias son las lambdas. Las lambdas son más concisas que las estrategias, pero no soportan fácilmente la adición de métodos o estado. También queríamos separar cada estrategia en su propio módulo y permitir que la estrategia se especificara en la línea de comandos. Con este requisito, lambdas se convirtió en tan detallado como las estrategias, por lo que utilizamos las estrategias al final.