Strategyパターンを使ったデータのグループ化の制御
Allen FungとAjay Lakshminarayanaraoによる
ShareThis の重要な製品の一つに、ソーシャルデータフィードがあります。当社のお客様は、インターネット上のソーシャルシグナルにアクセスし、世界中で発生したソーシャルイベントに関する国レベルのデータを消費するために使用します。ソーシャルデータフィードは、ユーザーが閲覧した各ウェブページのイベントを含むファイルです。このファイルには、毎日約5億件のイベントが含まれています。イベントには、URL、ジオ、タイムスタンプなどの情報が含まれています。最近、お客様から、イベントを1つのファイルではなく、国別に複数のファイルに分けてほしいという要望がありました。
この問題を解決するために、Strategyパターンを使用しました。これにより、新しい機能をサポートすると同時に、オリジナルの機能も維持することができます。Strategyパターンでは、あるオブジェクトの動作の一部を、あるインターフェイスに従った別のオブジェクトの観点から定義することができます。Strategyパターンを使って、2つの新しいオブジェクトを作りました。一方のオブジェクトは、イベントの国を返すメソッドを持っていました。もう一つは、どんなイベントが提供されても、常に空の文字列を返すメソッドを持っていました。
国を返した戦略がここにある。
class GroupByCountry:
def doOperation(self, json):
return json[‘geo’][‘ISO’]
いつも空の文字列を返していたストラテジーを紹介します。
class NoGroupBy:
def doOperation(self, json):
return “”
以下のコードは、ソーシャル・データ・フィードを作成するアプリケーションで、これらのストラテジーがどのように使用されているかを示しています。このアプリケーションは、ウェブサーバからログファイルを受け取り、各イベントに情報を追加し、追加された情報を含むファイルを出力します。コードの5行目にストラテジーのパターンが使われています。このアプリケーションは、runメソッドに渡されたストラテジーによって、複数のファイルまたは1つのファイルを出力します。
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()
ストラテジーに代わる主なものはラムダです。ラムダはストラテジーよりも簡潔ですが、メソッドやステートの追加には簡単に対応できません。また、私たちはストラテジーをそれぞれのモジュールに分け、コマンドラインでストラテジーを指定できるようにしたいと考えていました。この要件を満たすと、ラムダはストラテジーと同じくらい冗長になってしまうので、最終的にはストラテジーを使用しました。