非同期でのUTMタグマイニング

最近、Webアプリケーションのクライアント部分を開発する過程で、ユーザーをサイトに誘導した広告キャンペーンのラベルを決定することが必要になりました。



最初は、タスクは非常に線形に見えました。ここを見て、そこから優先順位に従って何かを受け取り、それを渡します。 しかし、その過程で、一部のタグは非同期に表示される可能性があるため、「待機」できる必要があります。



問題の複雑さにより、そのソリューションに含まれるコードを簡素化することが望まれました。



この投稿では、例としてこの問題の解決策を使用して、設計とオーバーエンジニアリングが柔軟で簡単に変更可能なアプリケーションの開発にどのように役立つかを示します。



タスク条件


探しているタグはUTMタグです。



タグのソースは、タグを探す場所です。 慣例により、それらには検索の優先順位があります。 このタスクでは、ソースは次のとおりです。



ラベルを読み取るためのアルゴリズムは、ソースの優先度に依存し、最初は次のようになります。







解決策


開発されたアプリケーションでは、 依存性注入パターンが使用されるため、一部の予約を含むアプリケーションコンポーネントはサービスとして表示されます。 以下は、問題の解決に参加します。



  1. Cookieリポジトリ
  2. HTTP要求データリポジトリ(GETパラメーター、document.location.pathnameなど);
  3. そして、直接、タグを受け取るサービス。


それらをそれぞれcookiesquery、およびutm呼びます。



Cookieとクエリの機能が十分に明確な場合、utmはどうですか? ラベルを取得するためのアルゴリズムをutmまたはabstract内で直接実装し、アルゴリズムの実装をサービス外に実装することは価値がありますか?



次の場合、アルゴリズムを大幅に簡素化できます。







したがって、ソースはCookieとクエリサービスである必要があります。



しかし、CookieゲッターにCookie値getCookieがあり、クエリgetterパラメーターがgetQueryParameterである場合はどうでしょうか。



つまり、 アダプターパターンを使用する必要があります。



その結果、次のラッパーサービスが表示されます。



  1. cookies-utm-adapter-検索を実行し、必要に応じて、Cookieに保存されているラベルをデコードします。
  2. query-utm-adapter-GETパラメーターで検索を実行します。
  3. query-utm-adapter-backside-HTTPリクエストの間接属性に基づいて検索を実行します。


utmサービスには、このソースのラベルソースインターフェイスと優先度を持つオブジェクトを取り込むaddSourceメソッドがあります。 また、サービス設計者は、サービスのデフォルト設定を拡張するjavascriptオブジェクトを受け入れます。



この図は、utmサービスとCookieリポジトリとの接続を示しています。







サービス設定では、これはすべて次のようになります。



cookies: path: '/src/service/cookies/cookies.js' query: path: '/src/service/query/query.js' cookies-utm-adapter: path: '/src/service/utm/cookies-utm-adapter.js' deps: calls: [['setCookieService', ['@cookies']] query-utm-adapter: path: '/src/service/utm/query-utm-adapter.js' deps: calls: [['setQueryService', ['@query']] query-utm-adapter-backside: path: 'src/service/utm/query-utm-adapter-backside.js' deps: calls: [['setQueryService', ['@query']] utm: path: 'src/service/utm/utm.js' deps: args: [ parameters: [ name: 'utm_source' required: true , name: 'utm_content' required: false , name: 'utm_term' required: false ] ] calls: [ ['addSource', ['@cookies-utm-adapter', 0]], ['addSource', ['@query-utm-adapter', 1]], ['addSource', ['@query-utm-adapter-backside', 2]] ]
      
      





*この例では、設定はcoffeescriptで表示され、@文字はサービスインスタンスへのリンクを意味します。 同様の設定形式がSymfony Dependency Injectionコンポーネントで使用されます。



このすべてを実装してコーディングしたと想像してください。 これですべてが動作しますが、同期して動作します。 いくつかのマークの「期待」をどうするか?



Async.js + jQuery.Deferred


実装に関するいくつかの言葉。



選択した構造ソリューションには、2つの論理レベルがあります。



非同期ソリューションを実装するには、少なくとも最初のレベルで変更を加える必要があります。



utmサービスレベルで、ソース調査サイクルの実装を変更します。



アダプタレベルでは、待機する価値のあるラベルのプロミスリターンを追加します。 たとえば、ga.jsライブラリ(analytics.js)の初期化後に設定される__utmz Cookieは、いくつかのタグの定義を許可する場合があります。



おわりに


解決する問題の設計の最初に、その複雑さとすべての落とし穴を常に想像するとは限りません。 そしてそのような瞬間に、私はそれを可能な限り単純にしたいのですが、コードの過度の断片化は過剰エンジニアリングの考えを示唆しており、一般的には少し怖いです。 この場合、設計の「正確さ」が実を結び、アプリケーションロジックへのさらなる変更を大幅に簡素化しました。



ご清聴ありがとうございました! それが誰かを助けることを願っています。



All Articles