4 ms·
Recently, for an academic project, I were given a one static one-function very long class that implemented an algorithm (was obviously programmed as a cpp algor
by TrianguloY 6y ago
Recently, for an academic project, I were given a one static one-function very long class that implemented an algorithm (was obviously programmed as a cpp algorithm). The algorithm consisted of steps (gather data, transform data, print data, etc) so as a 'what if' I refactored it by moving each step into a class (so the main function was now one line for each step). Also, what originally was multiple if/else to different outcomes (print to file vs print to console) was now one abstract class with one sub class each. The algorithm code was practically the same, the difference was where it were located. Instead of needing to scroll a lot, you now needed to switch between files.
Was it worth it? Probably yes, not for the final code but for the experience of 'this is an exaggeration that you should not repeat' (although the resulting class diagram was a work of art).
As usual, extreme abstracting is bad, but extreme lack of abstracting is too. You should find a common term that make the current work simple enough, but that also allows for future changes to be simple to implement.
If you are making a list-like class because you need to keep a collection of strings which you are only comparing, don't use strings. Use <T> even if you only use it with strings, the extra cost while creating the class is almost nothing, but the cost of a future refactorization will surely be greater.
"Try not to open doors you don't need, but keep them accessible in case you need them later"
- usrusr 6y ago> Use <T> even if you only use it with strings, the extra cost while creating the class is almost nothing, but the cost of a future refactorization will surely be greater. Allow me to question the "almost" in "almost nothing". Java generics are famously unreified, at runtime it's exactly the same. I have noticed this habit of what could be called redundant genericity in my own code as well. Sometimes the motivation seems to be hardly more than a coping strategy for the notoriously verbose class names of idiomatic java. But it can also provide self-describing value: at the use site, Bag<String> reads better than BagOfStrings and on the implemention side, class Bag<S> makes it clear that nothing in there will look at e.g. individual characters. Obviously, if you do need to consider individual characters, go with BagOfStrings - or go with class Bag<S extends CharSequence>, which would notify the reader right in the headline that somewhere in the implementing it requires access to the actual text nature of its data. As a bonus, even if production code only ever fills the angulars with one specific type, chances are that it's a type that is painful in a unit test. If you do esoteric set operations on WhateverFactoryFactories or something like that it's super-convenient if you can just play them through with strings.
- Twisol 6y ago> Allow me to question the "almost" in "almost nothing". Java generics are famously unreified, at runtime it's exactly the same. On the other hand, decaying <T> to Object (rather than monomorphizing as C++ templates do) somewhat reduces the viable attack surface for optimizations. On the gripping hand, Java is traced/JITted, so it should pick up many of these opportunities (and more) anyway.
- Nursie 6y ago> If you are making a list-like class because you need to keep a collection of strings which you are only comparing, don't use strings. Use <T> even if you only use it with strings, the extra cost while creating the class is almost nothing, but the cost of a future refactorization will surely be greater. Make it a little less readable for a future case you might never encounter?
- Twisol 6y agoI'm probably a bit of an outlier, but I do find it more readable to use type parameters instead of concrete types. If the type is opaque, I know the only ways to get or use values of that type are whatever explicit means the specifier of that type provides. This is less valuable the more specialized the type you're looking at -- generifying everything is just as much an antipattern as anything else -- but String is so widespread and abusable that it really is helpful to abstract over it in many circumstances.
- Nursie 6y agoEach to their own, as in so many ways. To me it becomes effectively another variable I have to track through the code and adds a small amount of extra cognitive load. Not a lot, of course, it's not a huge thing and I do use them where appropriate.
- DenisM 6y ago> Was it worth it? It was - having gone through both extremes you have gained understanding of both and discretion in using either.