多くのビジネス ロジックで使用できるいくつかの "設計パターン" があります。 それらの設計パターンはテストされ、適用可能なときにそれらを使用することで多くの時間を節約でき、ほとんどの場合、より効率的なビジネス ロジックを作成できます。 このケース スタディはそのようなデザイン パターンの 1 つに焦点を当てます。
更新カウンタの設計パターン
この設計パターンはほとんどすべてのビジネス ロジックで役に立つもので、あるイベント間の時間を測定するように意図されます。 そのようなビジネス ロジックの例は、可用性、ダウンタイム、平均故障間隔、平均回復時間、平均応答時間、平均解決時間、可用性が X 未満のコンポーネントの割合、時間どおりに解決されなかったケースの数などのビジネス ロジックです。
それらのビジネス ロジックすべてで共通の部分は、結果がそれらのビジネス ロジックが受信するさまざまなイベントのタイムスタンプに依存するということです。
ユーザのビジネス ロジックがこのデザイン パターンから利益を得ることができるかどうかを決めるための経験則は次のとおりです。ビジネス ロジックが、それが受信するさまざまなイベントのタイムスタンプに依存する場合、この設計パターンを使用する必要がある可能性が高くなります。
この設計パターンの骨格
このパターンを利用するビジネス ロジックのコードはフレームワークと実装の 2 つの部分に分割できます。 フレームワークには、ほとんどの場合固定され、さまざまなビジネス ロジックに対して変わらないコードが含まれます。 この部分は、可用性、および時間どおりに解決されないチケットの数の計算に対して同じです。 その実装には、各ビジネス ロジックに固有のコードが含まれます。
コードのそれら 2 つの部分を別々のビジネス ロジック モジュールに入れ、フレームワークのモジュールを別々のメトリックで再利用することを推奨します。
フレームワークのコードを以下に示します。
Dim g_PrevEventTimestamp
Sub OnLoad(time)
g_PrevEventTimestamp = time
InitializeStatusVariables
End Sub
Sub OnRegistration(Dispatcher)
' If there is a separate copy of status variables
' for each registered resource depend on the registered
' resources you should set initial values to the
' status variables of the newly added resources here
End Sub
Sub OnPeriodStart(time)
InitializeCounters
End Sub
Sub OnPeriodEnd(time, completePeriod)
HandleEvent (time)
End Sub
Sub OnTimeslotEnter(time)
HandleEvent (time)
End Sub
Sub OnTimeslotExit(time)
HandleEvent (time)
End Sub
Function Result()
Result = CalculateResult()
End Function
Sub HandleEvent(Time)
Dim diff
diff = TimeDiff( "s",Time,g_PrevEventTimestamp)
UpdateCounters(diff)
g_PrevEventTimestamp = Time
End Sub
実装モジュールのスケルトンを以下に示します。
' Define your status variables here. This can be one
' simple global variable or many complex global variables
' depending on the business logic
Dim g_StatusVar_1, g_StatusVar_2, ... ,g_StatusVar_n
' Define your counters here.
' This can be one simple global variable or many
' complex global variables depending on the business logic
Dim g_Counter_1, g_Counter_2, ... , g_Counter_n
Sub InitializeStatusVariables ()
' Set initial values to the various status variables
End Sub
Sub InitializeCounters ()
' Set initial values to the various counters
g_Counter_1 = 0
g_Counter_2 = 0
'…
g_Counter_n = 0
End Sub
Function CalculateResult ()
' Calculate the result. The result should depend on
' the values of the counters. It should not depend on
' the value of the status variables. It should not
' change the values of the counters or the status
' variables
End Function
Sub UpdateStatus(method, eventDetails)
' Update the value of the status variables based on
' the parameters (and posibly on the old value of the
' status variables)
End Sub
Sub UpdateCounters(diff)
' Update the values of the counters based on their
' previous value, on the value of the status variables
' and on the value of the diff parameter.
' In many cases this calculation is also based on the
' value of Context.IsWithinTimeslot
End Sub
Sub OnEvent_1(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnEvent_1”,eventDetails)
End Sub
Sub OnEvent_2(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnEvent_2”,eventDetails)
End Sub
'...
Sub OnEvent_n(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnEvent_n”,eventDetails)
End Sub
この設計パターンについてさらに説明するために、可用性の計算にこのパターンを実装した例を以下に示します。 この例では、ビジネス ロジック内の個別の 2 つのイベント ハンドラによって処理される UP および DOWN のイベントがあると仮定します。 可用性は、タイムスロット内の総時間に対する、システムが稼動されていた時間のパーセントとして定義されます。 システムのステータスは、最後に受信したイベント(UP または DOWN)のステータスであると仮定します。
実装するコードを以下に示します(フレームワークのコードは変更しません)。
' Status variable
Dim g_Status
' Counters.
Dim g_UpTime, g_TotalTime
Sub InitializeStatusVariables ()
G_Status = “UP”
End Sub
Sub InitializeCounters ()
g_UpTime = 0
g_TotalTime = 0
End Sub
Function CalculateResult ()
If g_TotalTime = 0 Then
CalculateResult = Null
Else
CalculateResult = g_UpTime/g_TotalTime*100
End If
End Function
Sub UpdateStatus(method, eventDetails)
If method = “OnUP” Then
G_Status = “UP”
Else
G_Status = “DOWN”
End If
End Sub
Sub UpdateCounters(diff)
If Context.IsWithinTimeslot Then
G_TotalTime = g_TotalTime + diff
If g_Status = “UP” Then
G_UpTime = g_UpTime + diff
End If
End If
End Sub
Sub OnUp(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnUp”,eventDetails)
End Sub
Sub OnDown(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnDown”,eventDetails)
End Sub
このパターンにはいくつかのバリエーションがあります。 最も一般的なバリエーションの 1 つは、各種のエンティティに対して個別の時間カウンタを保持する必要がある場合です。 たとえば、解決時間を測定する場合、各オープン チケットに対して個別のカウンタを保持する必要があります。 この場合、1 つのチケットにのみ関連するイベントを処理する場合は、そのチケットのカウンタのみを更新するほうが効率的です。 共通のイベントが処理されるとき(OnPeriodEnd、OnTimeslotEnter など)は、すべてのチケットのカウンタが更新される必要があります。
注: このパターンのこのバリエーションでは、各チケットに対して g_PrevEventTimestamp グローバル変数の個別のコピーを保持する必要があります。
このパターンの良い使用例のいくつかは、事前定義済みのコンテンツで見られます。 このパターンは事前定義済みコンテンツでは少し違った形で使用され、フレームワークと実装の間の区別はそれほど明白ではありません。
| Copyright © 2012 CA. All rights reserved. | このトピックについて CA Technologies に電子メールを送信する |