Usando o Padrão de Estratégia para Controlar o Agrupamento de Dados
Por Allen Fung e Ajay Lakshminarayanarao
Um importante produto ShareThis é o Social Data Feed, que nossos clientes usam para acessar sinais sociais através da internet e consumir dados de países sobre eventos sociais gerados ao redor do mundo. O Social Data Feed é um arquivo que contém um evento para cada página da web que nossos usuários tenham visto. Este arquivo contém cerca de 500 milhões de eventos diariamente. Um evento contém informações, tais como URL, geo e timestamp. Um cliente solicitou recentemente que colocássemos os eventos em vários arquivos, com base no país de origem, em vez de um único arquivo.
Nós usamos o padrão de estratégia para resolver este problema. Isto permite-nos suportar a nova funcionalidade, bem como preservar a original. O padrão de Estratégia permite que um objeto tenha algum do seu comportamento definido em termos de outro objeto que segue uma interface. Utilizámos o padrão de Estratégia criando dois novos objectos. Um deles tinha um método que devolvia o país de um evento. O outro tinha um método que sempre retornava uma string vazia, não importava qual evento fosse fornecido.
Aqui está a Estratégia que devolveu o país:
class GroupByCountry:
def doOperation(self, json):
return json[‘geo’][‘ISO’]
Aqui está a Estratégia que sempre devolveu o fio vazio:
class NoGroupBy:
def doOperation(self, json):
return “”
O código abaixo mostra como estas Estratégias são usadas na aplicação que cria o Social Data Feed. Esta aplicação pega um arquivo de log de um servidor web, adiciona informações a cada evento, e emite arquivos com as informações adicionadas. Você pode ver o padrão de Estratégia usado na linha 5 do código. A aplicação irá produzir vários arquivos ou um único arquivo, dependendo de qual Estratégia é passada para o método de execução.
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()
A principal alternativa às Estratégias são as lambdas. As lambdas são mais concisas que as Estratégias, mas não suportam facilmente a adição de métodos ou estados. Também quisemos separar cada Estratégia em seu próprio módulo e permitir que a Estratégia fosse especificada na linha de comando. Com este requisito, as lambdas tornaram-se tão verbosas quanto as Estratégias, por isso usamos as Estratégias no final.