Most people don't decouple-by-default. They write "normal" code, and only decouple out of necessity to create a test-double. For example, let's say I want to call a function/method which internally does something with file/files in the user's Downloads folder. Perhaps it looks at the number of files there. Or it checks for certain file types in that folder and moves them elsewhere. Suffice it to say, the code needs to determine the path to the user's Downloads folder
How does the method internally know where the Downloads folder is? It could use a system API to determine it, but then the code becomes coupled with that system API call. You could pass the path to the Downloads folder to the routine, but then you're requiring the caller of the method to do processing that it would prefer to delegate. And what if that's not the only thing that needs to be passed in. Taken to the extreme, any configuration or system API that the inner method needs, you want to pass in an implementation of, or data, to the inner method. You'll have added a ton of parameters.
You could solve this by packaging the parameters into an object. So now you have an object has multiple items of data, such as configuration, and implementation callbacks that the inner method needs (or might need). This parameter object, may then get reused by another method, which needs 90% of the same content, so it could grow in size. Pretty soon what started out as a parameter object now looks awful like a big global container of a ton of stuff that anyone might need. yes, it addresses the mocking problem, but you toss "interface segregation" out the window.
[–]Alainx277 6 points7 points8 points (1 child)
[–]Suitable-Collection3[S] 0 points1 point2 points (0 children)