Static service class in web application

Asked

Viewed 775 times

1

I have a class to generate report and another to check e-mail in an application, should leave it as static? The email class is to check the email in a certain period or when the user requests.

  • The right place for this is in the programmers.

  • Leave what static? The reratory or email class?

  • @Lucashenrique I don’t know this forum, only stackoverflow and codeReview.

  • 1

    Ok :). http://programmers.stackexchange.com/

  • @Lucashenrique, the two for example, my question is more in the sense, of classes that will be accessed at all times must be static understand.

  • I know this is ridiculous, but what does Static do? I was told that it is different from Static of C++.

  • You do not need to instantiate a class to have access to a particular method. That is to say Classe.metodoStatico.

  • Ah, good, C++;D style.

  • 3

    @Lucashenrique There are no programmers in Portuguese. The question fits here, but could be more detailed. Macario, can you include more details about the structure of your app, and the reasons for the doubt? In the current form, the question gives a lot of room for opinionated answers, and then it becomes difficult for one to be "correct". The ideal is for you to make the question more objective.

  • @bfavaretto He has accounts of the sites in English, I think there is no problem.

  • 3

    @Lucashenrique if the person came to ask in Portuguese, we will help you here. Take a look at the goal to know better the objectives of this site.

  • I have noticed that this is one of the problems of Stack, on repetition of posts that already have on the site in English, but I was really happy to see that there is a national version of this forum, and we need to create our database as well.

Show 7 more comments

4 answers

4


"Static classes", or classes containing static general utility methods, are an interesting option for some common tasks.

Personally, I have a habit of encapsulating some routines in this way. Just to illustrate:

public class Texto {
    boolean vazia(String str) { return str != null && str.trim().length > 0; } 
    String primeiraMaiuscula(String str) { ... }
    String corta(String str, int limite) { ... }
    //....
}

Such methods can be imported statically (import static) and used in any web application class.


On the other hand, for cases as suggested in the question (reports and emails) I do not think is the best solution. Some reasons:

Variation of use creates confusion

Reporting and sending emails can have varying parameters in different features in the same application. Over time, this ends up generating a kind of "library" full of overloaded methods. Let’s take an example:

public static void enviaEmail(String destinatario, String texto) { ... }
public static void enviaEmail(String destinatario, String conteudo, boolean html) { ... }
public static void enviaEmail(List<String> destinatarios, String texto) { ... }
public static void enviaEmail(List<String> destinatarios, String conteudo, boolean html) { ... }
public static void enviaEmail(List<String> destinatarios, String texto, File anexo) { ... }
public static void enviaEmail(List<String> destinatarios, String conteudo, boolean html, List<File> anexos) { ... }

Must continue?

Configuration dependency or external values

When a routine (method) depends on settings (email, report location, etc.) it would be better if the way to recover static values was not fixed.

For example, what if you create email routines in static methods and then discover that you need to send emails using more than one account or to more servers? Duplicate methods? Change static settings? Add more parameters to existing methods?

And to test a static method that carries a certain configuration or has fixed values? Anyone who works seriously with automated testing knows that a static method that does a lot is "shot in the foot".

Finally, static methods should have the minimum of responsibility.

And the economy in not instantiating classes?

In practice, instantiating some classes is not the bottleneck of the system. Both in the case of sending emails, as in the generation of reports, communication with the SMTP server, queries to the database and the creation of the output (PDF, XLS, etc.) are the points where one must work to gain in performance.

Make an investment in the architecture of your application and place such routines in asynchronous processes capable of creating informative logs for actions and repeating them in the event of failure. This will make your application more responsive (shorter response time) and less dependent on unnecessary optimizations.

Another very important point is to optimize darlings reports, creating indexes and using efficient query techniques (for example, in SQL Server you can add the hint (NO LOCK) in the queries of reports to avoid the treatment of Locks, that usually don’t matter much when we just want to list the data).

Constructing objects in an intelligent way

Finally, I’m going to point out some techniques for how to create small libraries, which I’ve been very fond of, and which are briefly described in my article Intelligently Building Objects: Pattern Builder and Fluent Interfaces.

Builder Pattern

Remember the confusion of the static email signatures? One way to encapsulate the creation of objects with different properties and attributes that are not always used is the design pattern Builder (Builder Pattern).

Let’s use the classic example of creating a Pizza, whose simplistic approach would be:

public class Pizza {

    private int tamanho;
    private boolean queijo;
    private boolean tomate;
    private boolean bacon;

    Pizza(int tamanho) {
        this.tamanho = tamanho;
    }

    Pizza(int tamanho, boolean queijo) { 
        this(tamanho);
        this.queijo = queijo;
    }

    Pizza(int tamanho, boolean queijo, boolean tomate) {
        this(tamanho, queijo);
        this.tomate = tomate;
    }

    Pizza(int tamanho, boolean queijo, boolean tomate, boolean bacon) {
        this(tamanho, queijo, tomate);
        this.bacon = bacon;
    }

}

Imagine passing a parameter to each ingredient? Then we would have a call like this:

new Pizza(10, true, false, true, false, true, false, true, false, ...)

Difficult and not very intuitive, right? Let’s apply the Builder Pattern:

public class Pizza {

    private int tamanho;
    private boolean queijo;
    private boolean tomate;
    private boolean bacon;

    public static class Builder {

        // requerido
        private final int tamanho;

        // opcional
        private boolean queijo = false;
        private boolean tomate = false;
        private boolean bacon = false;

        public Builder(int tamanho) {
            this.tamanho = tamanho;
        }

        public Builder queijo() {
            queijo = true;
            return this;
        }

        public Builder tomate() {
            tomate = true;
            return this;
        }

        public Builder bacon() {
            bacon = true;
            return this;
        }

        public Pizza build() {
            return new Pizza(this);
        }

    }

    private Pizza(Builder builder) {
        tamanho = builder.tamanho;
        queijo = builder.queijo;
        tomate = builder.tomate;
        bacon = builder.bacon;
    }

}

Now we can create an empty pizza and cover it with just what we want:

Pizza pizza = new Pizza.Builder(10)
                   .queijo()
                   .tomate()
                   .bacon()
                   .build();

This technique is widely used in modern frameworks, with my favorite example being ResponseBuilder of API JAX-RS.

Fluent Interfaces

Another very cool way to instantiate library objects is to use Fluent Interfaces. With them, we can use our creativity and make coding more flexible, more direct and much more interesting.

For example, suppose we want to create a shopping cart. The first simplistic implementation looks like this:

public class Pedido {

    List<Item> itens;
    Cliente cliente;

    void adicionarItem(Item item) {
        itens.add(item);
    }

    void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    void fechar() {
        // ...
    }

}

And the use goes like this:

Pedido p = new Pedido();
p.setCliente(new Cliente("José"));
p.adicionarItem(new Item("Motocicleta", 1));
p.adicionarItem(new Item("Capacete", 2));
p.fechar();

Applying the concept of Fluent interfaces, with few changes, we can make it much better:

public class Pedido {

    List<Item> itens;
    Cliente cliente;

    Pedido com(int quantidade, String nome) {
        itens.add(new Item(nome, quantidade));
        return this;
    }

    Pedido para(String nome) {
        cliente = new Cliente(nome);
        return this;
    }

    void fechar() {
        // ...
    }

}

And then we use the code like this:

new Pedido()
    .para("José")
    .com(1, "Motocicleta")
    .com(2, "Capacete")
    .fechar();

The above example looks very interesting if used for sending emails!

Completion

Static methods are important and have their place. However, do not use this language feature if the goal is to optimize code by preventing the creation of object instances. Also do not use for use cases that are not trivial: when there is variation of arguments, dependence on external values, competition risk, etc.

  • 1

    in good, it seems that you are talking to the code, very crazy, it seems something similar that I need later to study with mockito.

3

It will depend on how you use these classes. But, for this, we will go in parts

What does the Static?

The keyword static means that, to which it refers, belongs the class and not the instance. Thus, to use methods or variables static, it will not be necessary to instantiate a new object of that class.

When I should use a static class?

As can be seen in that reply, there’s no way you can make a static class, but, to create a static class, you just have to make all variables and methods static.

Making a static class means that it will not have a different behavior for each object. An example of static class is the Math, which is unnecessary to instantiate an object of this class, and you will only use methods of mathematical manipulation and/or mathematical constants.

That is, a class should be static when all possible instances of objects will have always the same behavior.

In short

A static class is a class that would have a behavior equal for all objects, if they were instantiated.

This concept should be used when your class does not behave differently, regardless of the number of objects you instantiate. It is up to the programmer to know when this is a reality or not.

1

You could have your static methods without problem. You could do something like:

public final class EmailHelper {
    public static void enviarEmail(Usuario usuario, Relatorio relatorio){
        // seu código
    }
}

And another class to generate the report:

public final class GerarRelatorio {
    public static Relatorio gerarRelatorio(...){
        // seu código
    }
}

Just be careful when using instance attributes because this method will be called by any user in the project. For example:

public final class EmailHelper {
    private String emailDoUsuario; // <--------- vai dar problema
    private String servidorDeEmail; // <-------- não vai dar problema

    public static void enviarEmail(Usuario usuario, Relatorio relatorio){
        // seu código
    }
}
  • in fact my idea, is not to recreate that object that is accessed every moment?

  • Ops, was mals. Missed to put the method as Static. I already edited above. [=

0

If you want, and it is more useful even to create a interface or put the methods and members of the two classes (which you want to be static) within the two email objects (which I assume exist).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.