One key idea of writing good, reusable and "flexible" code is to be as generic as possible. What do I mean by that? Just look at this code snippet at tell me what's wrong with it?
class Foo {
public Foo(String fileName) {
// moo
}
}
Now, there might be circumstances where this is perfectly fine but let's look at what drawbacks this has:
Can't use in-memory contents
What if I have whatever I want to pass to Foo
already in memory or only in memory? I'd have to create
a temporary file, write to it and make sure it's cleaned up again so I can use Foo. That's not nice.
What if the file isn't accessible directly through the OS file system?
What if it's on a network share where the OS has no built-in support for? I'd have to copy the file first to a local temporary directory and then clean it up again.
Alright! Fine, let's just use this instead then:
class Foo {
public Foo(String data) {
// moo
}
public Foo fromFile(String fileName) {
return Foo(readThatFile(fileName))
}
}
Better? A little. But still.... not really.
What if the file is large and doesn't fit completely into memory?
If the file is large... I can't use Foo. Using String is fine however if Foo absolutely needs everything at once.
How can we do better? Use interfaces!
class Foo {
public Foo(InputStream data) {
// moo
}
}
This is much more generic. Now I can use it with files, I can use it with sockets, I can use it with in-memory data and I could even download the contents from wherever I want.