4 ms·
Of all the patterns you could pick on, you pick on one of the most useful in modern OOP; however, I think you actually intend on picking on dependency inversion
by nathanaldensr 9y ago
Of all the patterns you could pick on, you pick on one of the most useful in modern OOP; however, I think you actually intend on picking on dependency inversion, not injection. Dependency injection is simply an automated way to satisfy constructor dependencies in OOP languages where your intent is to invert a dependency graph. I won't go into why dependency inversion (see: Dependency Inversion Principle, the "D" in SOLID) is so valuable because much has already been written on the topic.
As far as your email example, sometimes the language's basic type system abstractions (e.g., string, integer, etc.) do not encapsulate a real-world concept sufficiently. Encapsulation failures can frequently lead to bugs when edge cases are hit. I may, indeed, need to create an Address class to replace "string address" parameters if there is validation logic inherent to the existence of an email address in my code. If there isn't, then the base type of string would do just fine, of course.
- crimsonalucard 9y ago>Of all the patterns you could pick on, you pick on one of the most useful in modern OOP; however, I think you actually intend on picking on dependency inversion, not injection. Dependency injection is simply an automated way to satisfy constructor dependencies in OOP languages where your intent is to invert a dependency graph. I won't go into why dependency inversion (see: Dependency Inversion Principle, the "D" in SOLID) is so valuable because much has already been written on the topic. Both patterns are total failures. You are talking about the most misguided religiously followed pattern(s) in all of modern programming. AN equal amount has been written about how horrible both DI concepts are if you care to look. You think putting an acronym in your response and using big words like injection proves a point? Not SOLID at all. It proves nothing. You have literally ignored my main point. It baffles me how blind some people are. The Email object requires 10x more code and 10x more abstractions and 10x more unit test coverage to finish then a singular function. You haven't even addressed this fact yet. >As far as your email example, sometimes the language's basic type system abstractions (e.g., string, integer, etc.) do not encapsulate a real-world concept sufficiently. Encapsulation failures can frequently lead to bugs when edge cases are hit. I may, indeed, need to create an Address class to replace "string address" parameters if there is validation logic inherent to the existence of an email address in my code. If there isn't, then the base type of string would do just fine, of course. Do you seriously think that encapsulating an email address in an object makes a difference? Here's some "validation logic" for you: //raises error if invalid validate_email_address(email: str) I cannot make an example more clear. If you want to send a VALID email all you need is a function that validates an email and a function that sends it. You do not need to shove validation into an extra object then inject it into another one, then instantiate that object then call the send method... Doing this adds NOTHING beneficial to your code. This one guy told me that by encapsulating the email address into an Address object I am effectively eliminating a runtime exception from the system because the type checker is, in a way, doing the validation. haha. I cannot comprehend how this guy cannot visualize the fact that all he is doing by using an address object rather then a validation function he is just creating a class then basically moving the validation function over to be a method of that class. The runtime error can still occur... just in a different location and obscured by useless abstractions and code surrounding it. Many OOP patterns are pointless abstractions. Many smart people hate OOP all together, (including the founder of YC and this site). Maybe you should look into why. You are basically the topic of this article.
- watwut 9y ago> 10x more unit test coverage to finish then a singular function. That is not true. Assuming that both have same functionality, e.g. both either validate address correctness or both don't, you need exactly same test cases. The only difference is that they will be structured differently - in one case you validate address as part of `AddressObject` test and in another as part of `func email` or `func validate_email_address`. The tests with valid and invalid address however needs to exist in both cases. Whether you go by functional or object oriented way, validation should be separated from main. It can be in another object or in another function, but it definitely does not belong to main function that does also sending. There is very little difference between two, the only one is that whether you validate before hitting send function of after. > You do not need to shove validation into an extra object then inject it into another one. Doing this adds NOTHING beneficial to your code. It is not big deal either. It does not make it harder to understand, both variants are dead simple. Both are immediately readable. Frankly, people who have low abstract thinking or were lazy to learn basics of OOP hate it. It is the same as with people who hate any other paradigm - functional programming and what have you. Functional programming is too hard to read unless you have put work into learning it. There is such a thing as bad OOP, but when you pick dead simple easy to read example and claim it is something complicated, the the issue is not with OOP.
- crimsonalucard 9y ago>That is not true. Assuming that both have same functionality, e.g. both either validate address correctness or both don't, you need exactly same test cases. The only difference is that they will be structured differently - in one case you validate address as part of `AddressObject` test and in another as part of `func email` or `func validate_email_address`. Typically when you make a class. You create additional methods under that class. Those additional methods such as getters, setters, constructors, all need to be unit tested for full coverage. Like I said... Cruft code. >Whether you go by functional or object oriented way, validation should be separated from main. It can be in another object or in another function, but it definitely does not belong to main function that does also sending. There is very little difference between two, the only one is that whether you validate before hitting send function of after. We're in agreement here except I never brought up functional programming. Where in my post did I say it? I'm talking about procedural programming. Like C. >It is not big deal either. It does not make it harder to understand, both variants are dead simple. Both are immediately readable. Frankly, people who have low abstract thinking or were lazy to learn basics of OOP hate it. It is the same as with people who hate any other paradigm - functional programming and what have you. Functional programming is too hard to read unless you have put work into learning it. This is besides the point. I don't care about how hard or how simple or how lazy people are. I'm talking about pointless logic and unneeded abstractions. This is what the article is talking about. Here is a way to make it even more clear. Compare the two below: Class Email(AddressObject, SubjectObject, MessageObject, ConfigObject, ClientObject).send_mail(msg: str, subject: str, address: str) func send_mail(msg: str, subject: str, address: str) Do you see how the send_mail method is IDENTICAL to the send_mail function? The class and the dependencies getting injected into the class are a pointless layer of abstractions when ALL you need to send an email is the send_mail method. This is the core of the argument. Don't get into semantics about people being lazy. And also, again, I never mentioned functional programming. I'm not talking about it. I'm talking about straight up procedural programs of just regular functions that you see often in C code. >There is such a thing as bad OOP, but when you pick dead simple easy to read example and claim it is something complicated, the the issue is not with OOP. I picked something dead simple and easy so readers can understand what I'm talking about. You'd rather me hand you some OO source code so you can parse that insanity?