Hello fellow java-ranchers. I'm hoping to get some ideas or feedback regarding tight coupling and LSP. Here's the situation:
In my project there's multiple files and folders to be handled somehow (manually); There's multiple files that resembles each other and *some* action needs to be done to them.
To solve the problem I created java program which does following:
1. Finds recursively all files in a given folder
2. Those files are given to *Filter* (custom java interface, whose implementation is given at programs' startup) which determines which files to be processed (Implementation might be, for example, a *Filter* which filters files with certain extension)
3. Accepted files are given to *Handler* (custom java interface, whose implementation is given at programs' startup) which will then carry out some action to those files
Here's the essential code:
With that kind of design I tried to achieve loose coupling. However, then I implemented *Handler* which can behave correctly only if all files to be processed are excat ones (know extension, for example). E.g. *Filter* and *Handler* are tightly coupled. I might verify files in *Handler* before processing is done, and throw RuntimeException if not correct, but this violates LSP; With that kind of behaviour I would be strengthening the precondition (and weakening postcondition also as result of the method would be exception thrown with "valid" input). Any ideas or feedback about this one? I might solve the problem by presenting method verifyFiles(Set<File>filteredFiles) to *Handler*, but that doesn't sound correct solution..
I don't think runtime exceptions violate LSP. Runtime exceptions tell you your code is wrong to begin with, so you shouldn't recover. LSP then is no longer a worry.
Some code must be responsible for getting the files, filtering them and then handling them. In this case it's your main method. If it passes files carelessly to a handler without filtering them first, then a runtime exception from the handler is no more than deserved.
If you still think a runtime exceptions would violate LSP, then why not just document the possibility of a runtime exception in your handler's interface?
On a sidenote, your method parameter types are pretty restrictive. They should probably accept a Collection<? extends File>.
The mind is a strange and wonderful thing. I'm not sure that it will ever be able to figure itself out, everything else, maybe. From the atom to the universe, everything, except itself.
Joined: Jan 06, 2006
Hi and thanks for your reply Stephen.
Yes, now I can see what you mean. Also the client has responsiblity; to give correct parameters to the calling method he is calling. So sanity check for input parameter is acceptable. To the sidenote you mentioned I don't totally agree. True, File and any of its subclass should be accepted, but in this case I think that Set is better solution than Collection. All files are processed just once and Set can't contain duplicates. But thanks for your reply anyhow
Well, in the first place you can still process the same file with unequal File instances. Files are equal only by path name, not by their real location on the file system.
Secondly, you're mixing up responsibilities. It's not the handler's responsibility to decide what Files are passed to it. The client is responsible for making sure there are no duplicates. If there are duplicates, the client failed.
The benefit of using Collection is that Sets can be very unwieldy to work with. Say you are working with a List of Files. Then you first have to convert the list to a Set just to pass it to the handler. With the Collection it doesn't matter.