Há diversos padrões de design que podem ser usados em muitas lógicas de negócios. Esses padrões foram testados e usá-los quando aplicável pode economizar muito tempo e, na maioria dos casos, pode criar uma lógica de negócios mais eficiente. Este estudo de caso concentra-se em um padrão de design.
Atualizar padrão de design de contadores
Esse design padrão é útil em quase todas as lógicas de negócios, cujo objetivo é medir o tempo entre determinados eventos. Os exemplos de lógicas de negócios são: lógicas de negócios para a medição da disponibilidade, o tempo de inatividade, o tempo médio entre falhas, o tempo médio de restauração, o tempo médio de resposta, o tempo médio de resolução, a porcentagem de componentes com disponibilidade menor que X, o número de ocorrências não resolvidas na hora, etc.
A parte comum para todas as lógicas de negócios é que o resultado depende da data e hora de vários eventos recebidos..
O princípio básico para decidir se a lógica de negócios pode se beneficiar desse padrão de design consiste em: se a lógica de negócios depender da data/hora dos diversos eventos que recebe, ela provavelmente deve usar este padrão de design.
Esqueleto do padrão de design
O código de uma lógica de negócios que utiliza este padrão pode ser dividida em duas partes: uma estrutura e uma implementação. A estrutura contém o código que, na maioria dos casos, é fixo e não é alterado para as diversas lógicas de negócios. Essa parte é a mesma para o cálculo de disponibilidade e para o número de tickets não resolvidos na hora. A implementação contém o código que é específico para cada lógica de negócios.
É recomendável colocar essas duas partes do código em módulos de lógica de negócios distintos e reutilizar o módulo da estrutura em diferentes métricas.
O código da estrutura é demonstrado abaixo:
Dim g_PrevEventTimestamp
Sub OnLoad(time)
g_PrevEventTimestamp = time
InitializeStatusVariables
End Sub
Sub OnRegistration(Dispatcher)
Se houver uma cópia separada de variáveis do status
'para que cada recurso registrado dependa dos recursos
'registrados, é necessário definir valores iniciais para
as variáveis de status dos recursos recém adicionados aqui
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
Aqui está a estrutura do módulo de implementação:
' Defina aqui as variáveis de status. Ela pode ser uma
' variável global simples ou diversas variáveis globais complexas
' dependendo da lógica de negócios
Dim g_StatusVar_1, g_StatusVar_2, ... ,g_StatusVar_n
' Defina os contadores aqui.
'Isso pode ser uma variável global simples ou muitas
' variáveis globais complexas dependendo da lógica de negócios
Dim g_Counter_1, g_Counter_2, ... , g_Counter_n
Sub InitializeStatusVariables ()
'Defina os valores iniciais para as diversas variáveis de status
End Sub
Sub InitializeCounters ()
'Defina os valores iniciais para os diversos contadores
g_Counter_1 = 0
g_Counter_2 = 0
'…
g_Counter_n = 0
End Sub
Function CalculateResult ()
'Calcular o resultado. O resultado deve depender
'dos valores dos contadores. Ele não deve depender
'do valor das variáveis de status. Ele não deve
'alterar os valores dos contadores ou das variáveis
' de status
End Function
Sub UpdateStatus(method, eventDetails)
Atualizar o valor das variáveis de status com base
' nos parâmetros (e possivelmente no valor antigo das
' variáveis de status)
End Sub
Sub UpdateCounters(diff)
Atualizar os valores dos contadores com base nos
'valores anteriores, no valor das variáveis de status
'e no valor do parâmetro diff.
'Em muitos casos, esse cálculo tem como base
' o valor de 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
Para melhor explicar este padrão de design, tem-se um exemplo da implementação deste padrão para calcular a disponibilidade. Esse exemplo supõe que há eventos para UP e DOWN que são tratados por dois manipuladores de eventos diferentes na lógica de negócios. A disponibilidade é definida como o percentual de tempo no qual o sistema está ativo a partir do tempo total no período de atividade. O status do sistema é considerado o status do último evento recebido (ATIVO OU INATIVO).
Veja a seguir o código da implementação (o código da estrutura não é alterado):
' variável de status
Dim g_Status
' Contadores.
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
Há diversas variações neste padrão. Uma das variações mais comuns é quando um contador de tempo distinto deve ser mantido para entidades diferentes. Por exemplo, ao medir o tempo de uma solução, um contador distinto deve ser mantido para cada ticket aberto. Nesse caso, ao manipular um evento relevante apenas para um ticket, é mais eficiente atualizar apenas o contador daquele ticket. Quando um evento comum é manipulado (como OnPeriodEnd ou OnTimeslotEnter) os contadores de todos os tickets devem ser atualizados.
Observação: essa variação do padrão requer que uma cópia separada da variável global g_PrevEventTimestamp seja mantida para cada ticket.
Alguns exemplos úteis sobre o uso deste padrão podem ser encontrados no conteúdo predefinido. Tenha em mente que esse padrão é usado de modo diferente no conteúdo predefinido, e a separação entre a estrutura e a implementação não é tão evidente.
| Copyright © 2012 CA. Todos os direitos reservados. | Enviar email à CA Technologies sobre este tópico |