Timeline for Where should interfaces be used?
Current License: CC BY-SA 4.0
11 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jul 17, 2022 at 17:30 | comment | added | Paul Wasilewski | I would define a stronger rule. You must define an interface when you need the … | |
Jul 16, 2022 at 8:11 | comment | added | Ben Cottrell | Also a responsibility isn't the same as 'doing one thing', but relates to dependencies between requirements, so takes some assumption and guesswork about the future and a looking at where requirements are naturally dependent upon each other. A class could do many things but still have one responsibility if its requirements are set-in-stone in a particular way. For example, a class combining networking with message serialisation might be deemed to have one responsibility if there's no way the requirements for these can reasonably change independently of each other. | |
Jul 16, 2022 at 8:03 | comment | added | Ben Cottrell | I wouldn't agree that DIP mandates interface creation -- interfaces are a useful tool for substitution, but DIP doesn't require that,, and doesn't require dependency injection either. A class could just depend upon a sufficiently high-level abstraction with enough flexibility that it simply doesn't need substituting. For example, in .NET, Entity Framework's DbContext is already a sufficiently high-level abstraction that it's pointless to substitute it or put it behind an interface - the designers of the framework provided a lot of good options for automated testing. | |
Jul 16, 2022 at 7:26 | comment | added | The_Sympathizer | @Ben Cottrell: This makes sense - even the very first principle necessarily requires setting a granularity level: what constitutes "one single responsibility"? After all, if you get extreme about it, having two methods could be called two "responsibilities" as they do 2 different things. But at least DIP seems to mandate interface creation and to some extent so does OCP. Is the boundary of that mandate, then, to be also understood as such a "free parameter" in the design, a knob we must adjust for the needs of the particular project in question? | |
Jul 16, 2022 at 7:15 | comment | added | Ben Cottrell | @The_Sympathizer Most of the SOLID principles are context-dependent -- i.e. they depend upon the specific application domain and the different kinds of people (e,g, users, stakeholders, developers) who will determine how a project's requirements will change in future. The problems that SOLID set out to solve aren't really about what the code needs to do "right now"; a key driver behind SOLID is the understanding that code written and delivered into users' hands today will need to be rewritten/refactored in the future, so it's about minimising the risk of that going wrong. | |
Jul 16, 2022 at 1:59 | history | edited | Robert Harvey | CC BY-SA 4.0 |
deleted 13 characters in body
|
Jul 16, 2022 at 1:55 | comment | added | Robert Harvey | There are also DI systems that bind an interface to an implementation through some sort of configuration, either in an aggregate root, or by decorating the classes with attributes, or using a configuration file. For those situations, yes, you always need constructor parameters that are interfaces, to allow the DI container to build your object graph by substituting the proper implementations. | |
Jul 16, 2022 at 1:53 | comment | added | Robert Harvey | If you create a class that will only ever be used as one implementation of a capability (or will only ever be used in one other class), then you may not need interfaces, because you don't need implementation-swapping capabilities. You asked for a guiding principle; there it is. | |
Jul 16, 2022 at 1:48 | comment | added | The_Sympathizer | How then are we to properly understand DIP, which seems to be a sort of admonition to "create interfaces!" (or other suitably "abstract" decouplers)? | |
Jul 16, 2022 at 1:47 | comment | added | The_Sympathizer | So does this mean it doesn't go against any good programming rules to otherwise directly pass & use concrete classes where you don't reasonably foresee a need to swap objects? I.e. you shouldn't "default" to passing inputs to functions and class constructors as interfaces unless you foresee multiple similar types of object like that going in? If there is no need for multiple implementations, having a hard dependency in, say, the user interface layer on logic-layer objects ("business logic" objects) is okay? As I've heard some suggest the separation between layers should be fully abstracted. | |
Jul 16, 2022 at 1:44 | history | answered | Robert Harvey | CC BY-SA 4.0 |