The answer is "because a scanner has state."
Looking at the code for java.util.Scanner, you will see a number of private fields such as a buffer and its associated information, a Matcher, a Pattern, an input source, information about if the source is closed or not, the type of the last thing matched, information about if the last thing was a valid match or not, the radix used for numbers, the locale (information about if you are using .
or ,
as a thousands separator), and its own LRU cache for recently used patterns, the information about the last exception that was encountered, some information about parsing numbers, some information about parsing booleans, quite a bit more information about parsing integers... and I think thats about it.
As you can see, thats a fairly large block of text there. That is the state of the Scanner. In order to make the Scanner into a static class, that state would need to be stored somewhere else. The C way of doing it really doesn't have that much state with it. You've got a fscanf
. The FILE maintains some state about the position it is at (but that needs to be passed in for each invocation of fscanf
). If there was an error, you have to process it (and then you start writing code that looks like this) - and that doesn't tell you information like "I was expecting an Integer, but found a String."
When one looks at the theoretically static Scanner - all of the state is maintained outside of the class, it isn't encapsulated within the class. Other bits of code could tinker with those variables. When other code can tinker with the state of the class, it becomes very difficult to reason about what the class will do in any given situation.
You could, maybe, write something like ScannerState { Locale loc; ... }
and have code that results in:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
But then, this is much more cumbersome than having the state encapsulated within a Scanner object in the first place (and not needing to pass in the state).
Lastly, the Scanner implements the interface of Iterator<String>
which means that one can use it in code such as:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
Without being able to get an instance of the Scanner class, this type of structure becomes more cumbersome within an object oriented language.
Best Answer
Because, in the context you're linking to, not having internal state is the DEFINITION of a static class.
Here static class doesn't mean
static class
. It meansjava.lang.Math
. That's a final class full of static methods.Now that our vocabulary is clear...
Well...
So why
Because Murphy was an optimist. You say you only have one DB resource now but suppose that changes?
Designing around the idea that there will only ever be one of anything is forgetting why we solve some problems with keyboards, not soldering irons.
I favor the immutable instance approach (I can't bring myself to say singleton because the GoF singleton pattern is so so so not optimal) because shared mutable state is the real sin.
Give me a way to get an immutable instance that points to the DB resource you want me to talk to and I'll talk to it. Whether it talks to your 1st or 2nd DB resource is none of my business.
That's dependency injection. Counting the number of of DB resources is now a problem pushed out into construction. From there you could push it out to configuration if you wish.
Now I'll admit I'm biased. You don't have to use DI. You can use singleton. Here's a well considered article a comparing Singleton vs Dependency Injection.
I'll jump to the summery:
Which I love because it lets me simply say this: don't write code that puts your DB in case 1.