37 ms·
From STUPID to SOLID Code!
- dave1010uk 13y agoAnthony Ferrara did a similar presentation a while back: http://blog.ircmaxell.com/2012/05/dont-be-stupid-grasp-solid-slides.html http://blog.ircmaxell.com/2012/05/dont-be-stupid-grasp-solid...
- couac 13y agoYes, I linked his presentation in the introduction :)
- deleted 13y ago[deleted]
- winkerVSbecks 13y agoSomeone needs to fix the font on that website. Ultra thin font on white background and not rendering properly – highly, unreadable!
- couac 13y agoOh I am really sorry. Could you give me more details (OS, browser) so that I can fix the font?
- winkerVSbecks 13y agochrome on os x http://cl.ly/image/2H4115120p0t http://cl.ly/image/2H4115120p0t
- MarkMc 13y agoAlways avoid singletons? Here's my situation: in various parts of my code I need to get the current time. Normally I would call System.currentTimeMillis() but in my test cases I need to ensure the time is a particular value. So I have a Clock singleton class which allows me to get the current time but also to 'stop the clock'. Is it really better for me to pass the Clock instance all over the place, rather than have a singleton instance that can be referenced anywhere?
- skrebbel 13y agoIf you really want to modify global state while running a test, then you might as well use a dependency injection container and get similar behaviour, entirely generalized. You can then have two much simpler clock classes, one for real time and one for fake time. Personally, I prefer just passing around the clock, though - it makes dependencies between classes crystal clear.
- ExCodeCowboy 13y agoYou get the added benefit of not relying on global state. Which you have to do anyway if you want to parallelize your test suite execution.
- kazagistar 13y agoI have been questioning the "programming languages are for humans, use full names" principle recently. Why do we have a tendency, as humans, to create abbreviations so often then? Mathematicians get upset if an operation uses more then a single character or symbol to express it, and are willing to have massive amounts of overloading to achieve it.
- couac 13y agoMaybe because we are lazy, and we think that abbreviations save time/energy, which is obviously a wrong assumption.
- kazagistar 13y agoAgain, the "obviousness" cuts both ways. In other words, it is obvious to mathematicians that concise symbols are better, and it is obvious to programmers that verbose strings are better, and both have a lot of experience backing their claims... if anything, math has more. So, I think the real question is how do we quantify and measure it? How do we gather the formal and empirical data needed to resolve this issue?
- alipang 13y agoSure, but mathematical language only applies to very specific concepts. You're free to talk about the applied domain (if not pure math) using informal text. Programs need to be interpreted by a computer, and as such need to be written in a formal language everywhere, and as such has a larger amount of concepts that need to be formally modelled. More concepts means we need more descriptive names to be able to distinguish them.
- hackinthebochs 13y agoMath uses single letter/symbols usually because those letters have a very short scope, and they are always well defined before usage (or there is a pattern that any mathematician would recognize). Also, short naming is a boon in math because the mathematical objects defined are pretty constant: everyone learns the same notation and that notation becomes the basis for the next layer of abstraction. Programming by its nature is an exercise in re-enventing the wheel (how many different semantics are there for opening a file in all the different languages in use?). Also, the sheer number of algorithms and abstractions in use in programming dwarfs that of mathematics.
- skrebbel 13y agoI've always felt that the SOLID rules are very difficult to comprehend, yet pretty basic to apply. A junior dev that I recently coached, who had grown up on modern OO languages (Python, C#, etc), understood all these rules in his underbelly but would never be able to explain them. I believe that we should be able to come up with a set of (slightly different) rules that are simpler to explain and yield the same good designs.
- couac 13y agoI think that it is a matter of vocabulary, no? Reading the LSP definition in Liskov's paper is quite hard to understand, but with simpler words, it is more understandable.
- luiz-pv9 13y agoAbout the square/rectangle example, what would be the solution? The Square subclass should not verify equality with width and height or it should not even exist? Or something else? -- edit Wikipedia: If Square and Rectangle had only getter methods (i.e., they were immutable objects), then no violation of LSP could occur.
- dragonwriter 13y ago> If Square and Rectangle had only getter methods (i.e., they were immutable objects), then no violation of LSP could occur. Yeah, this is the fundamental problem; mutable objects tend to result in LSP violations when class heirarchies follow common sense is-a relationships, but mutating operations are not limited to those (if any exist) that preserve identity. A corollary to this is that the use of default constructors very often accompanies LSP violations, as it usually implies all of the object's state is subject to mutating operations.
- dljsjr 13y agoA lot of people love to try and make a case for Singletons. I have yet to see anyone make a really, truly good case for a pure software singleton. They just make it an absolute nightmare to be well informed -- as a developer -- about state in complex/concurrent/distributed systems. The only time I ever use them is when my hands are tied by some sort of hardware restriction; a JNI wrapper around some native lib that talks to proprietary hardware like a motor controller where instantiation of more than one comms object would blow out a fuse or something. And even then, I'd make the argument that the people who designed the hardware and its corresponding C API should have just made a safer interface instead of saying "Don't call `new` more than once, or else!". Seems lazy and less-than-appropriately fault tolerant.
- jamesaguilar 13y agoThe only other case I can think of is when the object represents a true hardware resource (e.g. a flash queue controller). Although even that doesn't technically need to be a singleton. Another case where I've used one is when I'm caching channels to other servers created by a factory function.
- RogerL 13y agoI know what you are saying, and agree. But consider: I have state that I truly need to be global - something I read from an INI file, the command line, or internally calculated, it doesn't much matter. Is not the alternative to a singleton having that state replicated all over the place? And then you introduce model/view/ signals, have to deal perhaps with race conditions, and so on. Then, just try to grep for the existence of that state in your code. Like anything, it's a tradeoff. Let's say I have an app with 10 OpenGL windows, and I want to simultaneously control the lighting model for all at once. A singleton gives me an easy way to do that, but then the windows have to poll in some manner (which is perhaps not an issue, since they are in a render loop anyway). But I am brittle - introduce the requirement that each window handles light differently and the singleton is toast. OTOH, introducing a signal/slot or model/view architecture may be overkill for what I am doing. This might be a small corner of the code, and I just want clarity for the few times I go in to read it. I find it extraordinarily hard to understand messaging code - where did this message come from, what was the state of that object that caused it to fire the message, and so on. I think complexity goes up at least by 1 order of magnitude when you have to maintain state and time in your mind to understand a program. Perhaps not the best example; so consider command line arguments. It's read only, set once, but perhaps needed to be accessed by many different parts of my code. A singleton or 5 seems pretty darn clean to me. Again, not without it's tradeoffs, but the alternatives, to me, seem worse. You can pass, pass, pass, the data through methods and constructors until it gets to the code that needs the info - in which case you have infected a lot of code with rather superfluous (to them) knowledge about command line settings. That's brittle, and you end up touching a lot of code when you add something to the command line. You can do a signal/slot or model/view, which can be quite powerful, but you may be forced into a specific design by your sw stack (they have a model/view architecture which you are using for GUI or something). So your code is brittle by being coded to a specific API, and again, it rather obscures where this data comes from. Plus, this forces the command line reading code to know all about your specific API, how to format the signal, when to send it (command line reading is often done well before the whole stack is started up and going, so you can't send a signal yet). That's very brittle as well. Can you take that code, put it in a test harness, and trivially write tests for it? Probably not. Maybe I am missing some obvious technique. But a few things in an app are in fact global. Trying to obscure that fact, to my mind, just makes the sw more brittle and a lot harder to understand and debug. Which is not in any way an argument for making non-global things global for convenience.
- ExpiredLink 13y ago'Dependency Inversion' increases coupling. More and more I'm inclined to consider 'Dependency Inversion' an Anti-Pattern.
- scrabble 13y agoCare to explain your take on this point of view? The way I see it, it couples objects to the things they should be coupled to while avoiding unnecessary coupling.
- dragonwriter 13y ago> 'Dependency Inversion' increases coupling. This is an interesting claim. Could you explain further how this is the case (or provide references which explain it?)
- nathell 13y agoI tend to perceive tight coupling as a virtue rather than as a symptom of stupidity. On the other hand, indescriptive naming is a real, and severe, problem in my code. Also, both these acronyms seem to lean toward the object-oriented paradigm. I'd like to see something more universal.