The easiest way you ever know, which is your first option:
"Create a Static and public attribute in Jlogin or Login to save the user and access it outside Jlogin."
Although you’ve seen "it’s a bad practice to use global variables," believe me, there’s a lot of systems developed more or less like this and making millions a year.
On the other hand, the people who made this code now regret it and see this kind of practice ("strong coupling") a constraint to earn even more millions, so they spend some of the millions they earn developing a new generation of their systems where these problems will no longer exist, and so walks humanity.
Since you came looking for a solution that does not fall into historical errors, here is a line of reasoning that will help you with this and everything else.
Think of your system as layers
It doesn’t have to be as complex as sometimes it seems! Continue reading.
The layers of the simplest design would be as follows::
Aplicativo ------> Negócios
|
|------------> Banco de dados
The above diagram shows three layers, of which App depends on Database and app depends on Business, that depends on no one.
These layers are conceptual, not physical. You don’t necessarily need interfaces, or object/relational mapping, or dependency injection frameworks, or MVC, or advanced software architecture knowledge, or blah-blah-blah...
In the first instance, you just need to keep in mind the responsibilities of each layer and schedule accordingly. Keeping this separation of concepts will help even the simplest applications.
Application Layer
The code on this layer knows the mechanics of the system: the navigation between the screens, the user permissions (which screens and buttons it has access to), the details of connection to the database, etc.
This layer knows what the system does and how the user should interact with the system; so when the user gives an order (click a button, for example), this layer knows which business object to invoke and what information to pass on to him to do his job. But she doesn’t know as the business object does what it has to do. Who knows this is the layer of Business.
Business layer
The business logic is implemented by the classes in this layer.
In this layer there may be an object that, when changing information, registers the user you changed, but this object does not know where to get this name or user id - it needs to be informed to it.
Database Layer
The less layer Business knowledge of the database, better. But this is a rather complex concept and if the layer Business at least not need to know the details of connection is already a great start.
Creating a physical constraint to prevent the layers from mixing
This is very simple to do: distribute your code in Packages where one of the names next to the root identifies the layer. For example:
com.padaria.aplicativo.estoque
com.padaria.negócio.estoque
The bakery’s stock screens are in the first package and the stock business rules are in the second. And all Packages in the system will have the name or starting with com.padaria.app or starting with with.bakery.business.
So if you try to reference a package com.padaria.app from a package with.bakery.business, you know you will be breaking your layer design once a reference in this direction is not allowed. See diagram: the layer App can refer to itself and can also refer to the layer Business. Already the layer Business can refer only to itself.
The layer Database is the responsibility of the bank server, so there is no package.
Eventually, in the future, you will no longer be able to frame all your artifacts into these Packages, so there must be others like with.bakery.below, with.bakery.reports., etc., and then you will need to evolve the design beyond what I am proposing here. But it will be an evolution and not a revolution and there will be at most Refactoring and do not rework.
Framing the user problem in this layer solution
The main object of the layer App obtains and holds an instance of the user, and passes this instance as reference to the objects of the Business or for other forms that need it.
Take this pseudocode as an example:
public class FormPrincipal {
private String nomeUsuario;
public void main() {
FormLogin formLogin = new FormLogin();
formLogin.Show();
if (formLogin.usuarioCancelou()) {
return;
}
ArgumentosConexao argumentosDb = ArgumentosConexao.fromConfiguracoes("config.properties");
ConexaoDb conexao = ConexaoDb.get(argumentosDb);
if (!AutenticacaoUsuario.loginValido(formLogin.nomeUsuario(), formLogin.senha(), conexao)){
Mensagens.show("Usuário ou senha inválidos.");
return;
}
nomeUsuario = formLogin.nomeUsuario();
Show(); // libera o usuário para interagir com este formulário principal
}
public void botaoProcessa_click() {
Processamento processamento = new Processamento();
processamento.processaTudo(nomeUsuario, conexao);
}
}
In this code, the class Processamento
(unlikely that someone has a class with this name, but you got the idea) resides in the layer of Business and the other classes reside in the layer App.
I like this code too because the dependencies are explicit - Each class exposes the resources you need to do your job. This facilitates the reuse of objects in different contexts, automated testing and system maintenance.
A suggestion would be to use the design pattern Singleton. It involves creating a single object of a class, and this object is accessed statically by the application classes.
– mutlei
Are you using any patterns? MVC for example?
– LeoCBS
You can control by the User object itself whether it is logging in or not by setting its permissions.
– Luis Henrique
Our @mutlei liked your suggestion expensive, quite interesting I will test and see if it will work as expected!
– Mariana Sempe
@Leocbs I’m not using any standard but I’m (trying and I’m managing for now) keeping the interface separate from the rest of the application so I didn’t want to create anything in Jlogin but in the classes! Maybe let a class Sessao manage it there ;)
– Mariana Sempe
Because it is @Luishenrique, I don’t know if I can access the instance of the Login class created in Jlogin in other classes like Jprincipal... If so, it is simple: I create a classSsession only with the user, profile and get/set for query and I leave the Login only for validation and query of login data in the database and Seto so (Login) the Sessao class? Q think?
– Mariana Sempe
I think the best idea is to create the class
Sessao
applying the design Pattern Singleton even, so you instantiate it at the time it ralizes the login and makes the appropriate queries in its internal classes.– Luis Henrique