Possibility of application of design pattern

1

After an effective login in the application I'm building I return a boolean[] with all the accesses the user has.

// Armazena o controle de acesso do usuário
LoginDAO logindao = new LoginDAO(conexao);
boolean[] acessos = logindao.controleAcesso(codigoUsuario);

Now when it comes to applying these accesses, instantiating only what can be used, I have a code full of if s (totaling 17) that I would like to remove or simplify, see:

/**
 * Aplica o controle de acesso às telas do sistema. Criando apenas
 * as necessárias.
 * @param acessos Lista com os acessos
 */
private void aplicarAcessos(boolean[] acessos) {
    if(acessos[0]) {
        tabAcervo = new TabPane();

        ObservableList<Tab> abasAcervo = tabAcervo.getTabs();

        if(acessos[1]) {            
            abasAcervo.add(new TelaMovimentacao().constroi());
        }

        if(acessos[2]) {
            abasAcervo.add(new TelaConsulta().constroi());
        }

        if(acessos[3]) {
            abasAcervo.add(new TelaReserva().constroi());
        }

    }
    // [...]
}

Note: All Screens obey the Screen interface:

public interface Tela {

    Tab constroi();
}

Is there a design pattern that lets me know which screen to instantiate without needing this amount of if s? Or some technique that will allow me to simplify this code.

    
asked by anonymous 31.03.2018 / 19:55

1 answer

2

Look, you can not say without really knowing the problem, probably more than you know right now.

You're probably looking for Abstract Factory . see if it caters to you. I think it makes the application so complex that even the shape you're doing is simpler but has its use when the natural complexity is great.

One of the ways may be as below, which has limitations (note that I created the screens and use on-demand as a pool ), have different forms that may be better than this, eg creation can be on-demand saving memory and allowing more than one instance of the same class to exist without conflicts.)

import java.util.*;

class Program {
    private static ArrayList<Tela> telas = new ArrayList<Tela>();
    public static void main (String[] args) {
        telas.add(new TelaConsulta());
        telas.add(new TelaReserva());
        for (String item : aplicarAcessos(new boolean[] { true, true })) System.out.println(item);
    }
    private static ArrayList<String> aplicarAcessos(boolean[] acessos) {
        ArrayList<String> abasAcervo = new ArrayList<>();
        for (int i = 0; i < acessos.length; i++) if (acessos[i]) abasAcervo.add(telas.get(i).constroi());
        return abasAcervo;
    }
}

interface Tela {
    String constroi();
}

class TelaConsulta implements Tela {
    public String constroi() {
        return "Tela Consulta";
    }
}
class TelaReserva implements Tela {
    public String constroi() {
        return "Tela Reserva";
    }
}

Take a look at Class .

If you want screens to be added without changing the logic of the code, you can make the classes that inherit this interface have a array method that would be "global", look for Service Locator.

You can use reflection and see all the classes that implement this interface and create instance for each one. I would have to get all the packages of the application first. It's slow. It may have a database or file with the names that need to be instantiated, but I do not like the idea, although it gets a bit faster, not good yet.

It honestly gives less work, is more performative and simpler to do on the hand, even if it is not the most elegant.

You can create a code generator that parses the classes that implement the interface and creates the array or if s or case s with each class.

If I remember any other way that is worth passing I edit here. Like I said it has lots of shapes, and only a few might be interesting for your case.

    
31.03.2018 / 21:19