-1

This is mainly a coding style question. I was wondering if it is a good coding principle to store and get objects from utility classes?

For example, let's say I created a list of integers and I want that list to be used by other classes. However, in order to do this, I have to pass the list inside each class every time I want to use/edit the list. Instead of doing this, is it a good practice to create a utility class that 'gets' this list for me every time I want to use it?

Using a utility class cleans up my code. However, I have heard that it is considered a bad practice to even use a utility class. Thanks!

public class ThisExample {

    private static final List<Integer> thisList = new ArrayList<Integer>();

    public static List<Integer> getMoveHistory() {
        return thisList;
    }
}
Rann Lifshitz
  • 4,040
  • 4
  • 22
  • 42
  • 1
    Globally accessible objects can be difficult to debug and will tightly couple your codebase, but it's not an uncommon pattern. There is a high probability that a better way to solve whatever core problem you're working on exists. – Derek Apr 18 '19 at 03:01
  • Hey! Thanks for the fast response! Perhaps I am wording this incorrectly - I apologize. I've been looking for ways to make my code easier to read - creating globally accessible objects was one of the solutions to this. If I did do this, would it typically be frowned upon to do so? – codingisfun Apr 18 '19 at 03:08
  • The problem isn't using a utility class, it's having an implicit communication channel where multiple instances of a consumer could step on each other. For example, it's very common to run tests in parallel, and they each need their own copy of the move list. – chrylis -cautiouslyoptimistic- Apr 18 '19 at 03:35

1 Answers1

2

I suggest viewing your question in terms of pros and cons, not best practices since the latter are a matter of opinion.

Pros of using a global container:

  • Easy accessibility to the global variables - each class which will import the container will be able to access the global data.
  • Centralization of shared variables - looking for a specific global variable is easy, assuming all of the variables are stored in the same container class.
  • Documentation - storing all the globals in one class helps document the context and purpose of the globals - simply group them by context and add a comment explaining their role in the application.
  • Simplicity - for smaller code bases/applications, with a single threaded approach and a small number of classes and code flows, using a container of global variables can be a simple and straight forward solution for passing information between entities.

Cons of using a global container:

  • Class coupling - all of the classes which will use global variables will have to import the same Container class, which will cause a dependency on the container class by many other classes. Changes to the container class will now affect many other classes at the same time.

  • Single point of failure - a lot of the application code flows will pass throw the container class. This makes certain approaches (such as using a synchronization lock) impractical to use on the container class, due to performance considerations for example.

  • Difficulty in debugging - since many elements of the application will inevitably access the global variables, it can be more difficult to debug their contents, especially in multi-threaded solutions.

  • Object-Oriented anti-pattern - if the OO approach is focused on encapsulation of code and abstraction of solutions, then the global container is the exact opposite - shared code which is purely focused on implementations (when using DS global variables, for example).

  • Always in memory - A Global container's variables will be in-scope as long as the application runs. Many memory leaks are the result of forgotten, in-scope variables.

References:

Rann Lifshitz
  • 4,040
  • 4
  • 22
  • 42