Hi Yegor,
Thanks for sharing your blog post. I have a few comments on it though. You have two examples of static utility methods you think would be better replaced with a series of Object based patterns. The second example uses this as the procedural example:
And then transforms it into this OO example:
Where you would have Trimmed, FileLines, and UnicodeFile as custom classes which you write and implement the collections API, and provide all kinds of other benefits you describe. Many of the problems you describe seem to be because you are using a poorly written transform method to begin with. For example, you say this:
Besides that, it is obvious that the second script runs in O(1) space, while the first one executes in O(n). This is the consequence of our procedural approach to data in the first script.
I don't see how the second example performs in O(1) time! It performs in O(n) time where n is the number of lines in the file. The procedural approach runs in O(3n) time, but that is only because it is poorly written. It could, for example, do this:
Barring any coding mistakes in that bit, this is O(n), doesn't read from the file until it can store the results, doesn't hold intermediate results, all benefits you give as reasons to use the OO implementation. It could be static since it doesn't access any state, and so could be put into a utility method. The use of the transformer and encoding
String (the encoding could probably be eliminated if I though a bit about it, like having decorated transformers or something). But I wouldn't need to right all the code required to make the intermediate classes (Trimmer, FileLines, UnicodeFile) implement Collection<String> properly. And fewer lines of code means less bugs, and both less bugs and less time spent implementing a huge interface means more productivity in other areas.
So I guess I have a few questions and comments:
1) How do you figure your OO code is O(1) and not O(n)?
2) I would suggest you not compare good OO code to bad procedural code when trying to make general statements like 'Utility classes are evil'.
3) Is the general statement that you are trying to get across that Utility classes make it easier to write poor procedural code by providing easy to use small chunks that lets the user of the Utility write lazy code which does not effectively do the job. If so, then I think you should make that more explicit in the blog. Otherwise it looks more like you are comparing apples to oranges and concluding blueberries are best.