-
Notifications
You must be signed in to change notification settings - Fork 0
/
work.tex
270 lines (221 loc) · 8.9 KB
/
work.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
\documentclass[12pt, letterpaper]{article}
\usepackage[utf8]{inputenc}
\usepackage{minted}
\usepackage{graphicx} %package to manage images
\graphicspath{ {images/} }
\usepackage{hyperref}
\thispagestyle{plain}
\begin{document}
\begin{center}
\Large
\textbf{Análise comparativa de ferramentas de Workflow para Ruby}
\vspace{0.4cm}
\large
Engenharia de Processos e Requisitos
\vspace{0.4cm}
\textbf{Eduardo Mauricio Barbiero}
\vspace{0.4cm}
\large
Sistemas de Informação - Católica de Santa Catarina
\vspace{0.4cm}
{Joinville, Dezembro de 2015}
\vspace{0.9cm}
\textbf{Resumo}
\end{center}
\par
Análise comparativa entre dois FrameWorks desenvolvidos com Ruby, para auxiliar no Fluxo de trabalho de um determinado negócio. Será feita uma breve descrição sobre os dois frameworks "Workflow" e "State Machines", que possuem algumas particularidades e demonstrado em forma de tabela a representação de funcionalidades e diferenças.
\section{Workflow}
Workflow é uma API inspirada na "máquina de estados finitos" para a modelagem e interagir com o que temos a tendência de se referir como "fluxo de trabalho".
Uma grande remeça de informações sobre o negócio, tende a envolver conceitos de fluxo de trabalho, bem como, essa biblioteca tende a expressar que esses conceitos sejam o mais claro possível. É utilizada uma terminologia semelhante encontrada na "teoria de máquina de estado".
Um fluxo de trabalho possui sempre um estado. Ele só pode estar em um estado de cada vez, porém, quando ele muda de estado, chamamos isso de transição. As transições de um evento, ocorrem de modo que cada transição ocorra, onde caso haja alguma falha na execução dessa transição, seja executado uma outra remessa de código, que possa ou não corrigir esse problema. Desse modo, esses transições podem gerar vários eventos, e qualquer evento pode gerar uma outra transição ou uma nova ação.
Aplicando esses conceitos a um caso, digamos que uma cidade possui alguns problemas e devem ser resolvido com alguns passos, até que chegue a um determinado setor de uma empresa. Dessa forma, um problema é diagnosticado, passado a uma analista de problemas até chegar ao responsável pelo setor. Após isso, deve ser enviada a uma determinada área para execução ou reparação do problema, vejamos na utilização da API:
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
class Problemas
include Workflow
workflow do
state :new do
event :submit, :transitions_to => :aguardando_revisao
end
state :aguardando_revisao do
event :review, :transitions_to => :sendo_revisado
end
state :sendo_revisado do
event :accept, :transitions_to => :accepted
event :reject, :transitions_to => :rejected
end
state :accepted
state :rejected
end
end
\end{minted}
Nesse caso, o uso ficaria dessa forma:
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
problema = Problemas.new
problema.accepted? # => false
problema.new? # => true
\end{minted}
Ou seja, é verificado se o problema foi aceito, e verifica se é um evento novo.
Uma outra forma de verificar esse status, é chamando o objeto "\texttt{current\_state}" que retorna um objeto de estados do workflow atual.
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
problema.current_state
=> #<Workflow::State:0x7f1e3d6731f0 @events={
:submit=>#<Workflow::Event:0x7f1e3d6730d8 @action=nil,
@transitions_to=:aguardando_revisao, @name=:submit, @meta={}>},
name:new, meta{}
\end{minted}
Agora precisamos saber, se o problema foi aceito, e onde se encontra nossa review:
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
problema.current_state < :accepted
=> true
problema.current_state >= :accepted
=> false
problema.current_state.between? :aguardando_revisao, :rejected
=> true
\end{minted}
Nesse caso, podemos observar, que ele se encontra "\texttt{aguardando\_revisao}", e desse modo ele ainda é "rejeitado".
Agora nós podemos chamar o evento "submit", que faz a transição para o estado "\texttt{aguardando\_revisao}":
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
problema.submit !
problema.aguardando_revisao? # = > True
\end{minted}
Esses eventos, são na verdade métodos de instancia de um fluxo e trabalho, que dependendo do estado onde você está, ele vai conter um conjunto de eventos diferentes para serem usandos e para auxiliar na transição para outros estados.
É fácil verificar se uma certa transição foi feita, a partir do evento atual, basta verificar pelo método "\texttt{problema.can\_submit?}", se essa transição foi submetida do estado atual.
\section{State Machines}
State Machines é uma API baseada na antiga "State Machine" que foi descontinuada a algum tempo, porém leva em consideração a grande parte de sua tecnologia.
\par
A State Machines torná seu workflow operante e simples de gerenciar o comportamento de uma classe, simplifica o projeto, introduzindo as várias partes de uma máquina de estado real, incluindo estados, eventos, transições e retornos de chamada. No entanto, a API é projetado para ser tão simples que você não precisa mesmo de saber o que é uma máquina de estado.
\par
Vejamos um exemplo simples de aplicação, utilizando como base um Problema de infraestrutura na cidade, onde só poderia ser possível transitar pela rua, se todos os problemas fossem resolvidos.
Exemplificando:
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
class Infraestrutura
state_machine :state, initial: :transitar do
after_transition on: :reparar, :transitar
after_failure on: :transitando, :necessita_reparacao
state :necessita_reparacao do
def reparacao
@reparacao = true
end
def avisar_prefeitura
#executa evento para avisar a prefeitura
end
end
state :transitar do
transition stalled: same, :transitando
end
state :transitando do
def transitando
@transitando = true
end
end
event :reparar do
def parar
@transitando = false
end
def reparado
@reparacao = false
end
end
def initialize
@transitando = false
@reparacao = false
end
def parado?
@transitando
end
end
end
\end{minted}
\par
Desse modo, podemos observar, que o estado "\texttt{necessita\_reparacao}", é o fim do fluxo de trabalho, onde ele irá lançar uma notificação para a prefeitura, para resolução do problema.
Vejamos como usar na prática.
\begin{minted}
[
frame=lines,
framesep=2mm,
baselinestretch=1.2,
fontsize=\footnotesize,
]
{ruby}
infra = Infraestrutura.new
infra.state # transitando
infra.transitando? # true
# [#<StateMachines:Transition attribute=:state
# from="transitar" from_name=":transitar" to="transitando"
# to_name=:transitando>]
infra.state_transitions
# suponhamos que o metodo transitando, falhe
infra.state # necessita_reparacao
infra.reparar
infra.state_event # [:reparar]
# vejamos que quando o evento de reparacao e chamado
# o mesmo ja faz a transicao para o estando "transitando"
# ao finalizar
infra.state # transitando
\end{minted}
\newpage
\section{Comparação}
A seguir será feita uma comparação entre as duas tecnologias.
\begin{center}
\begin{tabular}{|l|l|l|l|l|l|l|l|l|}
\hline
& \scriptsize{Ruby} & \scriptsize{Maleável} & \scriptsize{Rastreável} & \scriptsize{Interface} & \scriptsize{Tutoriais} & \scriptsize{Escalabilidade} & \scriptsize{Processos} \\ \hline
\scriptsize{WorkFlow} & 1.9.x & +1 & +1 & -1 & +1 & -1 & +1 \\ \hline
\scriptsize{State Machines} & 2.x & +1 & +1 & -1 & -1 & +1 & +1 \\ \hline
\end{tabular}
\end{center}
\newpage
\section{Conclusão}
\par
Pelo fato do gem Workflow ser extremamente simples de ser usado e aplicado, torna-se uma boa escolha, quando se trata de um sistema de não tanta regra de negócio sobre o fluxo de trabalho, pela complexidade do código quando se trata de persistência. Ao contrário da State Machines que traz uma boa camada para desenvolvimento sobre persistência.
\par
Com base nisso vale destacar que o programador deve se adequar no que realmente se precisa e a que melhor se encaixa na regra de negócio. A robustez da State Machines com relação a persistência, ou a simplicidade da Workflow para desenvolvimento de uma api/app de simples manutenção.
\newpage
\section{Referências}
\url{https://github.com/geekq/workflow}. Acesso em 30/11/2015.\break
\url{https://github.com/state-machines/state_machines}. Acesso em 01/12/2015.\break
\url{https://github.com/pluginaweek/state_machine}. Acesso em 01/12/2015.
\pagenumbering{arabic}
\end{document}