Es gibt mehrere "Designmuster", die in vielen Business-Logiken verwendet werden können. Diese Designmuster sind geprüft und ihre Verwendung, dort wo es möglich ist, kann viel Zeit sparen und in vielen Fällen zu einer effizienteren Business-Logik führen. Diese Fallstudie befasst sich schwerpunktmäßig mit solch einem Designmuster.
Designmuster "Zähler aktualisieren"
Dieses Designmuster ist in beinahe allen Business-Logiken hilfreich, die dafür vorgesehen sind, die Zeit zwischen bestimmten Events zu messen. Beispiele für derartige Business-Logik sind: Verfügbarkeitsmessung, Ausfallzeit, mittlere Zeit zwischen Ausfällen, mittlere Reparaturzeit, durchschnittliche Antwortzeit, durchschnittliche Bearbeitungszeit, Prozentsatz von Komponenten mit einer Verfügbarkeit kleiner als X, Anzahl von nicht rechtzeitig gelösten Fällen usw.
Diese Arten von Business-Logik haben gemeinsam, dass ihr Ergebnis vom Zeitstempel verschiedener Events abhängt, die sie empfangen.
Eine Faustregel dafür, ob Ihre Business-Logik von diesem Designmuster profitieren kann, ist: Wenn Ihre Business-Logik vom Zeitstempel der verschiedenen Events abhängt, die sie empfängt, sollte sie dieses Designmuster verwenden.
Aufbau dieses Designmusters
Der Code einer Business-Logik, die dieses Muster nutzt, besteht aus zwei Teilen: einem Rahmen und einer Implementierung. Der Rahmen enthält Code, der in den meisten Fällen vorgegeben und für die verschiedenen Arten von Business-Logik gleich ist. Dieser Teil ist für die Berechnung der Verfügbarkeit und der Anzahl von nicht rechtzeitig gelösten Tickets gleich. Die Implementierung enthält Code, der spezifisch für jede Business-Logik ist.
Es wird empfohlen, diese beiden Codeteile in separaten Business-Logik-Modulen zu nutzen und das Modul des Rahmens in unterschiedlichen Metriken wiederzuverwenden.
Code des Rahmens:
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
Aufbau des Implementierungsmoduls:
' 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 Kontext.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
Um dieses Designmuster besser zu erklären, finden Sie hier ein Beispiel für die Implementierung dieses Musters für die Berechnung der Verfügbarkeit. In diesem Beispiel wird davon ausgegangen, dass Events für UP und DOWN vorhanden sind, die von zwei separaten Event-Routinen in der Business-Logik verarbeitet werden. Die Verfügbarkeit wird als Prozentsatz der Zeit angegeben, in der das System während der Gesamtzeit im Zeitfenster betriebsbereit ist. Der Status des Systems ist der Status des letzten empfangenen Events (UP oder DOWN).
Code der Implementierung (Code des Rahmens ist gleich):
' 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
Es gibt einige Variationen dieses Musters. Eine der gängigsten Variationen ist, dass ein separater Zeitzähler für unterschiedliche Entitäten verwaltet werden soll. Beispiel: Wenn Sie die Bearbeitungszeit messen möchten, sollte ein separater Zähler für jedes offene Ticket verwaltet werden. Wenn ein nur für ein Ticket relevantes Event verarbeitet wird, ist es in diesem Fall effizienter, nur den Zähler dieses Tickets zu aktualisieren. Wenn ein gängiges Event verarbeitet wird (wie "OnPeriodEnd" oder "OnTimeslotEnter"), sollten die Zähler aller Tickets aktualisiert werden.
Hinweis: Für diese Mustervariation muss eine separate Kopie der globalen Variable "g_PrevEventTimestamp" für jedes Ticket verwaltet werden.
Einige gute Beispiele für die Verwendung dieses Musters finden Sie in unseren vordefinierten Inhalten. Beachten Sie, dass dieses Muster in den vordefinierten Inhalten anders verwendet wird und die Trennung zwischen Rahmen und Implementierung nicht so deutlich ist.
|
Copyright © 2013 CA.
Alle Rechte vorbehalten.
|
|