0

I'm writing a class that will hold row data from a file. Therefore it'll have state, but it's immutable state and there will only ever be one set of data. My initial implementation was a static class, with the initializer block calling the method to read the file. By doing this, I could be sure that the data was read when the class was loaded, and none of the accessor methods for the data would have to check for that case.

A reviewer has commented that the class should be a singleton. While I understand his argument about the class having state, I'm thinking that the fact that it's an immutable state (once the file is read, of course) nullifies this argument.

I do have some other concerns, including handling an IOException (thrown when the reading of the file fails) in a static initialization block, but I'd be interested in opinions about the static vs singleton issue.

Mureinik
  • 252,575
  • 45
  • 248
  • 283
BillD
  • 9
  • 1
  • Lots of opinions about singletons here: http://stackoverflow.com/q/137975/10077 – Fred Larson Oct 03 '14 at 18:38
  • Thanks, Fred. I had no idea that there was so much opposition to them. Or, at least, so much misuse of them in so many people's opinions. – BillD Oct 03 '14 at 19:40
  • My hope was that the immutability (bolded) issue would either 1) be a red flag that someone could identify as a clear-cut signal in favor of the static implementation, or 2) draw comments as to its irrelevance and redirect focus on the true criteria - assuming they exist - for making this decision. The fact that five viewers felt that "answers to this question will tend to be almost entirely based on opinions" is a good indication that said criteria don't exist, so I suppose that's an answer, too. Meh. It was worth a shot. – BillD Oct 06 '14 at 13:15

1 Answers1

2

Personally, I prefer classes like that being singletons.

First, like you mentioned, it's easier to handle IOExceptions from within your code instead of having to deal with them being thrown at seemingly random times and failing the classloader.

Second, I really prefer singletons as they are still instances - and as such they're easier to replace when you're testing.

The simple java version of this principle could look like this:

public class MyProductionClass {
    protected DataHolder getDataHolder() {
        return DataHolder.getInstance();
    }

    public int addOneToDataHolder() {
        return getDataHolder.getIntData() + 1;
    }
}

Now, assume I want to test the business logic of addOneToDataHolder(). All I have to do is mock away the getDataHolder() method:

@RunWith(MockitoJUnitRunner.class)
public class MyProductionClassTest {
    @Mock
    private DataHolder dh;

    private MyProductionClass prod;

    @Before
    public void setUp() {
        MyProductionClass prod = spy(new MyProductionClass());
        doReturn(dh).when(prod).getDataHolder();
    }

    @Test
    public void testAddOneToDataHolder() {
        when(getDataHolder.getIntData()).thenReturn(1);
        assertEquals(2, prod.addOneToDataHolder());
    }
}

Of course, with any CDI framework, this wold look even cleaner.

Mureinik
  • 252,575
  • 45
  • 248
  • 283
  • Thank you. I can certainly make the switch w/o too much difficulty, but I'm wondering if my class really meets the singleton standard of needing to be the only instance. I certainly don't want to re-read the file (which having multiple instances would cause), but I keep coming back to the fact that this seems to be basically a bunch of constants for which I want to provide access via methods instead of directly. Hence the "fuzzy" in the title. I'm still torn, but will take the weekend to mull this over. – BillD Oct 03 '14 at 19:45