4 ms·
Why are your two examples in the second paragraph necessarily "abstractions"?
by betenoire 6y ago
Why are your two examples in the second paragraph necessarily "abstractions"?
- Tainnor 6y agoBecause "calculate_vat" is more abstract than the exact sequence of calculations performed?
- waheoo 6y agoAre we talking about that kind of general function labelling abstraction? I was under the impression this was about generalizing the abstraction to something reusable. I.e. calculate_vat will always be used by the same thing and there will only ever be one of them. The generalization would be: interface SalesTaxCalculator { func calculate_sales_tax } This kind of abstraction is more uncommon. What im guessing the article is struggling with is that making abstractions like salestax calculation os usually kind of useless, there is only 1-3 types of sales tax calculation and its best defined inline next to the proce calculation or put in a function like calculate_vat. A lot of developers use abstractions to remove code duplication. Its more fun using this kind of code than code where devs dont try to remove duplicstion but i just wish instead of seeing duplication as evil, they instead saw it a sign that their design is wrong. If youre seeing duplication, there is an abstraction there, whether it is worth it to implement is usually more to do with if its just hiding code duplication or if it is creating a new concept that hides implementation details.
- Tainnor 6y agoYes, if you restrict your definition of abstraction to "polymorphism", then it becomes a different discussion (Go developers would like to have a word). But I think there are lots of abstractions often missing from code that I have seen that don't need any sort of polymorphism. A common example is performing input validation all over the place instead of at the boundary with some sort of form object that only accepts valid params.
- waheoo 6y agoIm not restricting the definition to that at all. Input validation, and any abstraction that smells like a framework or library make great code folds for abstraction. The question is all about cost. Does a single layer abstraction, at the boundaries, with clear inputs and outputs have much of a cost? I don't think so. Does forcing vat calculation into a new class far away from the widget price class have a cost? I think so, the cost is having the same concern separated for no material gain other than perhaps reducing one form of duplication for the cost of creating another.
- Tainnor 6y agoYou may not think that input validation at the boundary has a cost, but the fact is that the "typical" Ruby on Rails application is happy to just pass controller params along to the model layer unchanged and unvalidated (there is a security layer that allows you to whitelist which parameters you want to forward, but nothing more than that). Validation is supposed to happen in the model layer. I think this is horrible design, but it's unfortunately a strong convention and breaking conventions also has associated costs. By contrast, if you write your application in e.g. Spring Boot you typically have validation at the controller level built in, so yes, in that case, it's easy to do the right thing. I think you're right that it may not be necessary to extract "calculate_vat" into another class. It just really depends: if the VAT code is so complex that it should be properly unit tested, I think it deserves its own class. If it's fairly straightforward and only used inside of a single other price calculation class, then yeah, it can remain a private method or so. But I don't think this is a question of whether to abstract or not, rather about what the right level of cohesion and coupling is for a given situation.