1
I thought of the following public method:
public RespostaDeArme armar();
The class RespostaDeArme
would be so:
public class RespostaDeArme {
private final ResultadoDeArme resultado;
private final Set<Integer> zonasAbertas;
public RespostaDeArme(ResultadoDeArme resultado) {
this(resultado, new HashSet<>());
}
public RespostaDeArme(ResultadoDeArme resultado, Set<Integer> zonasAbertas) {
this.resultado = resultado;
this.zonasAbertas = new HashSet<>(zonasAbertas);
}
public ResultadoDeArme getResultado() {
return resultado;
}
public Set<Integer> getZonasAbertas() {
return zonasAbertas;
}
}
public enum ResultadoDeArme {
SUCESSO(1),
ARME_RECUSADO_PARTICAO_JA_ARMADA(2),
ARME_RECUSADO_EXISTEM_ZONAS_ABERTAS(3),
ERRO(4);
private final int numero;
private ResultadoDeArme(int numero) {
this.numero = numero;
}
public int getNumero() {
return numero;
}
}
It only makes sense to call the method getZonasAbertas()
when the result is ARME_RECUSADO_EXISTEM_ZONAS_ABERTAS
.
Question: does this code have any code Smell? The only one I thought was an eventual need to refactor the class containing the method armar()
with Hide Delegate not to need the intermediary RespostaDeArme
to get the open zones (which I don’t know if would be the case here).
Does anyone see a better way to implement this behavior? If necessary I give more context. I don’t like the idea of having two methods in the same class, one armar()
and a getZonasAbertas()
, because the two would have an unnecessary temporal link (the programmer would need to know that he should first call the armar()
, then the other).
Example of use:
public void executarArme(int idDaCentral) {
RespostaDeArme resposta = conexao.armar();
escritorDaFila.escrever(gerarJsonDeRespostaDeArme(idDaCentral, resposta));
}
private JSONObject gerarJsonDeRespostaDeArme(int idDaCentral, RespostaDeArme resposta) {
JSONObject json = new JSONObject();
json.put("tipoDeMensagem", Mensagens.RESPOSTA_DE_ARME.getNumero());
json.put("idDaCentral", idDaCentral);
json.put("resultado", resposta.getResultado().getNumero());
if (resposta.getResultado() == ResultadoDeArme.ARME_RECUSADO_EXISTEM_ZONAS_ABERTAS) {
json.put("zonasAbertas", new JSONArray(resposta.getZonasAbertas()));
}
return json;
}
What are these open zones? How are these numbers used by those who call the method
getZonasAbertas()
?– Victor Stafusa
It’s a central alarm. A partition has n zones represented by numbers, which must all be closed at the time of the arme for it to be successful. Failing to arm due to open zones, I send this information to a process that records the result of the arme in the bank along with which zones were open, sends a notification to the user, etc. The user has the option to close the zones (manually, this zone is for example a magnetic sensor coupled to a window) before trying a new arm.
– Piovezan
You can give an example of a typical code in which the method
armar()
and thegetZonasAbertas()
would be used? I tried to create another answer that wasn’t based on exceptions, but I came to the conclusion that in order to succeed, I would need to know better in what context this is used.– Victor Stafusa
@Victorstafusa I can try, but I don’t have a code on hand, what I have today is done a little differently and I’m trying to make it more "correct". But basically what I’m going to do with this list of open zones is to include it in a JSON along with a value representing the result of the arme and send this JSON to a message queue, then the other process turns around. Today I convert this zone list into a comma-separated number string and send it to JSON.
– Piovezan
Where is the method
armar()
? In what situationResultadoDeArme
isARME_RECUSADO_PARTICAO_JA_ARMADA
?– ramaral
@ramaral The method
armar()
today is in a classConexaoComCentralDeAlarme
but I don’t know if this is where I should be (it’s one of the things I’m racking my brain about to get better, but this is outside the scope of the current question). TheARME_RECUSADO_PARTICAO_JA_ARMADA
is a conflict resulting from a user (or multiple) trying to arm via application and via keyboard that is attached to the alarm center, for example.– Piovezan
Ah, in your Enum
ResultadoDeArme
, the methodgetNumero()
could be implemented like this:public int getNumero() { return ordinal() + 1; }
and with that you don’t need the fieldnumero
nor the builder.– Victor Stafusa