3

小さなイベント ロギング フレームワークの適切な抽象化を概念化するのに苦労しており、ここで適用できる実際の比較対象は見つかりませんでした。

概要: Web アプリケーションは、サーバー側からイベントをログに記録する必要があります。イベント データは json でエンコードされ、フラット ファイルに書き込まれます。イベントには、ページ ビュー、サインアップ、エラー状態などがあります。

すべてのイベントには、Web リクエスト情報やセッション状態などの一連のコア データが含まれます。どのイベントでも、記録する追加データを定義できる必要があります。

理想的には、イベントを開始するためのインターフェイスは最小限に抑えます。イベント定義とデータ要件は、単一の構成ファイルで定義する必要があります。データ検証とデータ変換は、この構成ファイルの背後に隠されている必要があります。つまり、イベントをログに記録するためのインターフェイスには、イベント名と、イベントに変換および記録されるデータ構造のみが必要です。

私の当初の考えでは、単一のデータ構造が単一の関数にマップされ、その責任はデータ構造をディクショナリに変換し、最終的に最終的なイベント オブジェクトにマージされ、json でエンコードされてファイルに書き込まれるというものでした。これらを「作曲家」関数と呼んでいます。Django の用語では、構成ファイル内の何かが、たとえば、ビューに渡された HTTP 要求オブジェクトを「request_composer」関数にマップします。この関数は、そのリクエスト オブジェクトから引き出されたデータの辞書を作成します。ビューから発行されるイベントは、その「要求」オブジェクトを渡す必要があります。

私の質問は、任意のデータ構造をきれいに変換して最終的なデータ構造にマージする、見落としたパターンまたは抽象化があるかどうかということだと思います。この「単一のデータ型が単一の変換関数にマップされる」というのは、少しぎこちなく、洗練されていないように感じます。また、単一のトランスフォーマーが複数の引数を受け入れることが理にかなっている場合にも、問題が発生します。

4

2 に答える 2

1

アーロンには厳格なルールはありません。私の提案は、デザイン全体が整っていて、ビューからイベントを発生させたい場合に、実装がどのように見えるかを想像し始めることです。

だからここに私の提案があります、それはこれらの特定の目標を持っています:

  • イベントは明示的に参照する必要があります(Djangoの設計)
  • イベントは再利用またはアプリケーション固有にすることができます
  • イベントごとにリクエストインスタンスが必要です
  • 各イベントは、追加の任意の引数またはキーワード引数を収集でき、イベントプロセッサにコンテキストを提供するだけです。
  • イベントプロセッサはリクエストデータを抽出し、コンテキストを使用してJSONにシリアル化し、ログファイルに追加します

したがって、プロジェクトでアプリケーションを作成し、にアプリがmyproj.eventsあるとしますmyproj.myapp

イベントプロセッサとデフォルトのプロジェクト全体のインスタンスを次の場所に作成しましょうmyproj/events/__init__.py

import 

class Events(object): pass  # Use your imagination

events = Events(logfile=StringIO.StringIO)  # Say I wanted to log to a file-like object

で、単一のモジュールでmyproj/myapp/events.pyすべてのアプリ固有のイベントを構成できます。myproj.myapp

from myproj.events import events

@events.register_event
def view_requested(request)
    return request


@events.register_event
def user_signed_in(request)
    user = request.user
    return request, dict(username=user.username, gravatar=user.profile.gravatar)

次に、あなたの見解では、次のことができます。

from django.http import HttpResponse
from myproj.myapps import events


def foo(request):
    events.view_requested(request)
    return HttpResponse

このアプローチは、 DjangoのSignalsから多くの設計ヒントを取り入れています。これは、関連するシグナルを発生したコンテキストで呼び出すだけで、レシーバーコールバックで分離された動作を再利用するための直感的なインターフェイスを提供します。

実際には、その実装を見て、特定の要件に合わせて実際に使用または拡張できるかどうかを確認することをお勧めします。

于 2012-10-19T07:48:42.487 に答える
1

これは Facade (複雑な実装への単純なインターフェース) によく似ており、おそらく Strategy (実行時または構成/起動時にプロセスのいくつかの具体的な実装を切り替える) および Builder (複雑なオブジェクトの共通の抽象的な記述を提供し、いくつかの異なる戦略は実際の表現に変換できます)。Strategy を使用すると、Facade を使用する必要がなくなることがあります。

http://en.wikipedia.org/wiki/Builder_pattern

http://en.wikipedia.org/wiki/Facade_pattern

http://en.wikipedia.org/wiki/Strategy_pattern

もう少し具体的に:

Facade には、Log と SetLogger の 2 つのメソッドがあります。

Prototype を使用すると、イベントのタイプと、イベントの各コンポーネントのタイプがあります。ログに記録する非常に複雑なイベントがある場合、またはいくつかの非常に異なる方法でログに記録する必要がある場合にのみ、Prototype を使用します。

Logger (Strategy) 用のインターフェースがあります。これは、SetLogger メソッドの Facade で使用されます。Prototype を使用している場合、Facade.Log と Logger.Log の両方のインターフェイスには、おそらく log(PrototypeEvent e) のようなメソッドがあります。

Prototype を使用せず、Strategy を使用する単純なロガーについては、以下のリンクをたどってください。フロントエンド クラスは実際には現在のロガーを追跡するだけなので、Facade はありません。

C# を使用して単純なロガーを作成するつもりですが、ベスト プラクティスとしてこれを作成するために使用できる設計パターンは何ですか?

于 2012-10-19T06:42:32.883 に答える