4 ms·
I think that is implicit. The guidelines set out here allow you to deliver that value without having to rip up your product for every minor change.
by meaty 14y ago
I think that is implicit.
The guidelines set out here allow you to deliver that value without having to rip up your product for every minor change.
- taeric 14y ago:) I can agree that it is implicit. I just want it explicit.
- w0utert 14y agoThe problem I have with lists of 'principles' like this, is that they usually carry the presumption that there are no exceptions to any one of them. IMO this is not a good way to introduce novice programmers to sound software architecture, and often leads to an unmaintainable mess of 'flexible, extensible, loosely-coupled code' that does not 'repeat itself' and 'encapsulates and abstracts away implementation details'. Especially in situations where a) none of these things actually matter, or b) most (or all) of them could have been realized with much less complexity. Just as an example, I really hate principles like 'program to interface, not implementation'. More often than not, you are not writing 'extensible frameworks' or 'reusable classes', so hiding each.and.every.class behind an interface serves no purpose. I get really depressed browsing the typical Java or C# code written by all the architecture astronauts around me that are obeying some variant of the '10 object oriented design principles' and thinking they need to make ISomething for every Something constructed by a AbstractSomethingFactory they can dream of, even though it's completely obvious only one kind Something will ever exist. TL;DR: there's almost as much risk creating crappy code blindly following what is commonly sold as 'OO design principles' as there is in hacking up everything with complete disregard of sound design and architecture. I think this should come pretty close to what your parent poster was trying to say. I also think many developers working in languages that aren't strictly OO would agree.
- moron4hire 14y agoYAGNI serves me more often than it hurts me, in this case (as with all such rules-of-thumb, they are double-edged-swords, to mix my metaphors). I try not to write code I don't need until I need it. If an interface is necessary, it'll come out eventually. But I agree, some people get really abstraction happy.
- meaty 14y agoIt's not about how many ISomething's exist - it's about defining a contract between Something and the rest of the system. When it comes to testing, how are you going to test your ClassX if it's tightly coupled to ClassY rather than IClassY (which can be mocked/stubbed)? Oh, you have to test both. Also, an interface is a great way of implementing "worry about that shit later - just let me talk to it now". You can define and evolve the contracts before you have to refactor expensive implementations. As for AbstractSomethingFactory, I've not written a bit of code like that for night on 10 years. The container gives me what shit I need, ready configured with all dependencies. Blindly following rules is dangerous, but burning entire books for what appears to be lack of experience is much more dangerous.
- w0utert 14y ago>> It's not about how many ISomething's exist - it's about defining a contract between Something and the rest of the system. Why would I need to introduce a separate interface class to define this contract, instead of making it explicit through the public class interface? What problem do I solve by adding another layer of abstraction between Something (the class) and Something (the interface), if Something is just some internally used entity that isn't part of a framework or public API? I've seen millions of lines of code to date, and the number of times hiding public class interfaces behind interface classes (note how those sound almost identical, wonder why that would be?) can be counted on the fingers of one hand. Interface classes only make sense if you expect classes to be used like you would use components in a component-based architecture, e.g. for plugins, or polymorphic, adaptable structures that may be implemented by combinations of classes, etc. >> When it comes to testing, how are you going to test your ClassX if it's tightly coupled to ClassY rather than IClassY (which can be mocked/stubbed)? Oh, you have to test both. You don't always need interface classes for loose coupling, abstract base classes cover many cases, and in many other cases loose coupling is simply not required. There is nothing wrong in testing multiple classes that are tightly coupled together, without stubbing. In those cases where loose coupling is absolutely essential (frameworks for example) and you want to compose classes to provide some kind of interface, use interface classes. My point is not that interfaces classes are wrong, but they are overused, and more often than not, they add complexity without benefits. >> Also, an interface is a great way of implementing "worry about that shit later - just let me talk to it now". You can define and evolve the contracts before you have to refactor expensive implementations. Again, I don't see why you would need interface classes for any of this. I can write a stub class that let's me 'worry about shit later' simply by defining its public interface and leaving its implementation empty. If I have a lot of classes adhering to the same (semi-) abstract interface and I don't want to stub them all with empty methods, I simply create a temporary base class I can remove later. Eventually I'll have to implement everything anyway, and I'm not writing interfaces just for the fun of it, or the remote possibility that some interface may be required later, even though no-one asked for it. >> As for AbstractSomethingFactory, I've not written a bit of code like that for night on 10 years. The container gives me what shit I need, ready configured with all dependencies. Interesting that you should say that, because I used AbstractSomethingFactory simply as a caricature of an often overused design pattern, without implying that you should never write an abstract factory. In fact, abstract factories are a useful solution in many common designs, even though they are so overused. >> Blindly following rules is dangerous, but burning entire books for what appears to be lack of experience is much more dangerous. Which means we have to aim somewhere in between, which is exactly what I was trying to say in the first place. Unfortunately many developers somehow seem to drift to either one of the extremes, the Java/C#-like language programmers to the 'create moar classes!' side, everyone else to the 'just make it work' side. My point is that both lead to unmaintainable, bug-ridden code.