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 situationResultadoDeArmeisARME_RECUSADO_PARTICAO_JA_ARMADA?– ramaral
@ramaral The method
armar()today is in a classConexaoComCentralDeAlarmebut 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_ARMADAis 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 fieldnumeronor the builder.– Victor Stafusa