Java: everything in the class is static - is that reasonable?

I'm just curious that what I'm doing is somehow a bad design.

I have an ArrayList of things. I need this list so that it always exists. I need only one of these lists. I also have some ways to interact with this list. So I made everything static.

The fact is that, since all these things are hidden in one class, literally everything in this class is declared static. It seems a little strange because it is as if I want the whole class to be static.

The facts that Java does not allow me to make the whole class static, and that I was taught to minimize static methods in my code, cause some disturbing calls in my head, but I honestly don’t see any rational why what I do will work poorly.

EDIT: A little more about the program and why I decided to do what I did, because I think it would help (and it was asked, of course).

The center of the program is two databases: one for elements and one for symbols. Characters must have a temporary staging of items, but all items must be able to constantly display.

I decided that I would have an arrailist of items, each element has a Boolean marking, available or inaccessible (which simplifies the display of both all items and available items). Each character will have its own, smaller arraylist of elements, to which I would add duplicate elements from the database.

To have access to the database from other classes (I started with the idea), I thought that my easiest option is to just make a large arraylist static, because there is no situation where I need it to not exist, and there is no situation there, when I need more than one. Of course, since I made a static list, I also needed to make all the basic methods of interacting with it static.

I am sure there are better ways to do what I'm trying to do, but I'm just a novice practitioner.

EDIT2: Oh, and the list of items will be added, deleted and will be changed while the program is running. Another effect of characters receiving copies of objects is that their own elements will remain the same as long as they are.

+6
source share
4 answers

Based on your update, you have come to the classic "This is a singleton!" the moment after which someone should tell you that "He is (almost) never a singleton!". Instead, it should be a regular, non-static, not a single class, and the rest of the application should be written so as to always use a single instance. The fact that your application needs only one instance of a thing does not make this thing one-sided. It will be useful for you to read several articles that appear on Google to search for “why one-sided evil” and “singleton antipattern” .

It also sounds as if you are talking about a general volatile state, which is a whole other (giant) can of worms with which you do not want to enter without special attention.

+2
source

If you need exactly one Thing list on your system, you should ask yourself what these things are. Are they elements that can be customized before each run? Are they things that will change as the user executes the program? Perhaps these things should be stored as records in a database, even light in memory, such as Apache Derby or NoSQL database.

Even if you really have a fixed set of elements, you should consider using a dependency injection and list vending system in the Singleton area instead of using a hard singleton. Thus, you can replace the list in test classes by changing the configuration.

If you find that the latter is confused, think about it. Suppose you have a class that processes Things , say, keeping a static list in it. Sort of:

 public class ThingCatalog { private static final List<Thing> things = new ArrayList<>(); public ThingCatalog() { // initialize list of things. } public List<Thing> getThings() { return things; } public Thing getThingWithId(int id) { // ... } } 

Now you can make the ThingCatalog class singleton; you saw how to do it. Make the constructor private and create a static getInstance method. You will be tempted to write

 public class TreasureGenerator { private ThingCatalog things = ThingCatalog.getInstance(); // ... } 

What happens if you want to write unit test for a method in this class that doesn't use things? You don't need things, so you really don't need ThingCatalog. Fortunately, you are stuck with it.

You can fix this by providing the TreasureGenerator method setThingCatalog:

 public void setThingCatalog(ThingCatalog things) { this.things = things; } 

Of course, you only have one ThingCatalog, so that doesn't help much. But if you had an interface that ThingCatalog could implement:

 public interface ThingVendor { List<Thing> getThings(); Thing getThingById(int id); } 

and all your classes used ThingVendor instead of ThingCatalog, you could replace it in your tests.

Here is a more business example. You are writing a financial program, and you need to print today's date when checking. It is typical to write code like:

 String recipient = ...; String accountOwner = ...; BigDecimal amount = ...; String accountNumber = ...; Date today = new Date(); printCheck(...); 

Now someone asks you: "Can your program handle jumps correctly?" Fourteen years ago, the question may have concerned 2000. How would you test this? You are stuck today in this method.

Instead, you write an interface called DateGenerator :

 public interface DateGenerator { Date today(); } public class TodayGenerator implements DateGenerator { public Date today() { return new Date(); } } public class LeapDayGenerator implements DateGenerator { public Date today() { Calendar cal = Calendar.getInstance(); cal.set(2016, FEBRUARY, 29); // assume static imports; return cal.getTime(); } } 

Your class will have a setDateGenerator method, and you usually use TodayGenerator. In your jump test, you will use the LeapDayGenerator.

A dependency injection system automates these processes. What you learn with experience, if you stay with computing, is that objects do not need to know how to configure themselves. Other parts of the project should stick objects together.

+4
source

Sorry, but I'm afraid yours might be a bad plan, and you might need to redesign your program. Your class has a state, and this tells me that it should not be static.

Things that should be static:

  • Constants
  • Useful methods
  • Fields belonging to a class, not an instance.

Consider providing us with more information about your program structure so that we can provide a more accurate answer.

+2
source

I tend to agree that your design sounds suboptimal. Many of your goals are those that are typical of procedural rather than object-oriented programming.

If you find that your project is highly dependent on static mutable data, then you should ask yourself why you need so much global data.

+1
source

Source: https://habr.com/ru/post/945393/


All Articles