4 ms·
> If some principle results in a handful of single-method classes that don't really do anything on their own, the principle is not a good basis for design. Abs
by jdminhbg 13y ago
> If some principle results in a handful of single-method classes that don't really do anything on their own, the principle is not a good basis for design.
Absolutely agree. Proponents of approaches like this tend to only worry about intra-object complexity, and ignore the fact that a vast, complicated object graph is also hard to reason about.
- userbinator 13y agoonly worry about intra-object complexity That reminds me of this, not sure if it's satirical or not: http://www.antiifcampaign.com/ http://www.antiifcampaign.com/ Basically it's advocating removing if/switch statements and replacing them with polymorphic method calls. I understand that polymorphism has its value, but think that it's only valuable when, for lack of a better phrase, the thing that's being polymorphosed is "big and varied" enough that it makes sense to impose this extra level of indirection. I think that it being hard to explain when something is worth it, is enough justification that principles shouldn't be arbitrarily decided based on that.
- sunir 13y agoI don't understand that page in the slightest, but a lot of if-cascades can be factored more cleanly using polymorphism. http://c2.com/cgi/wiki/wiki?PolymorphismVsSelectionIdiom http://c2.com/cgi/wiki/wiki?PolymorphismVsSelectionIdiom (Disclaimer. I wrote the top of that wiki page in a former life.)
- userbinator 13y agoHowever, if you already have a class type for each key I think that's precisely what I was trying to say - polymorphism makes sense when you already have a bunch of classes to do it with, and classes which already contain lots of other fields and methods; it doesn't make sense to create a bunch of classes just to use polymorphism.
- nardi 13y agoOften, though, a series of complicated if statements is hinting at a type system for your objects that hasn't yet materialized in your code. I find it's a good idea to always look at cascading if statements and switch statements and ask, "Would this be cleaner if I reified these concepts as types?" http://en.wikipedia.org/wiki/Reification_(computer_science) http://en.wikipedia.org/wiki/Reification_(computer_science)
- alttab 13y agoThis is the single most important trick for factoring out shitty code. I cannot believe how many times reification collapsed complexity in our code base, or how not using it was the source of bugs. If you have cascading ifs, there is a good chance there is a huge set of ifs for every place this type system is missing. Meaning, if you wanted to add another "case" to a feature, you are modifying cascading ifs in 5-10 places, not even just one. Wrapping up all of this code into an implementation of an interface, that is "hooked in" at each contact point allows you to add a cohesive new use case by generating a new implementation of an interface, instead of "forgetting 2 places in the code" and causing massive bugs or issues because of it. It of course, also makes it easier to test!
- platz 13y agoSo to reify a type involves making an abstraction, which is odd because reify seems the inverse of making an abstraction...
- colomon 13y agoI can't help you determine if that page is satire or not, but now you've got this song running through my head: https://www.youtube.com/watch?v=-Lx8c3-djc8 https://www.youtube.com/watch?v=-Lx8c3-djc8
- zenbowman 13y agoGreat point. Squeezing unrelated objects into class hierarchies to avoid a couple of trivial "ifs" is the ultimate destroyer of readability.
- dragonwriter 13y agoIf it is sensible to call the same function with them as the same parameter, the objects are not unrelated. There is a very real and relevant-to-the-application sense in which they share a common type. (Now, if they aren't sharing implementation -- which they clearly aren't in at least one relevant way if you are avoiding an "if" statement by putting them in a class heirarchy -- then it probably makes more sense for them to implement a common interface rather than being subclasses of the same class, in a language which distinguishes those rather than using multiple inheritance class heirarchies plus method overloading to serve the role of interfaces.)