3 ms·
Who ever said "the right features" were limited to function pointers? Who ever even talked about function pointers? My example didn't even use function pointers
by loup-vaillant 9y ago
Who ever said "the right features" were limited to function pointers? Who ever even talked about function pointers? My example didn't even use function pointers! Are your imagination so limited that you cannot think of language features that would reduce the need for any specific pattern? I just showed you one, dammit!
Let's step back a little:
> 9 out of 10 patterns are nothing more than specific uses of inheritance and polymorphism.
Of course, inheritance and polymorphism are the only thing Java has! Or had, back in 1995. Hammer & nail. There are other ways of expressing those patterns, other ways of solving the same problems that do not require those patterns at all. You just need to wake the fuck up and realise OOP is not the only game in town.
> design patterns help clarify technical discussions as they communicate clear concepts as well as solutions to particular problems they solve.
I have yet to witness a single instance of that in my job, and I've seen loads. On the contrary, naming patterns often clouds the underlying concepts. A pet peeve of mine is the Singleton. It's overused for sure, but that also makes it one of the most widely understood patterns. Yet few seem to realise that singletons are nothing more than global variables with a couple bells and whistles. And since the thing is not called "global variable", it doesn't trigger the appropriate mental warnings.
What good are pattern names when programmers can't think clearly to begin with?
It's not just the conversations. Every time I saw a pattern name in real code, I could find a simpler way. I also saw misapplied patterns, like factories that actually were memory pools. Whoever did that didn't know what they were talking about, and patterns didn't save them.
- mikekchar 9y agoI've read lots of your postings and I like them. I think you are a smart person and I realise that this topic is getting a bit frustrating. But because I think we're all talking past one another, I'll hopefully be able to clear up a few things. Patterns of code exist. It's a mistake to look at the GoF pattern catalogue and think that it represents patterns that you should use in every situation (or even at all!). I remember hearing someone say one time that all programming should be made up of GoF patterns (touring complete??? ;-) ). Yes, it's absurd. Going all the way back to the original poor article, that's really the problem. People latch on to these ideas; they hear something and it sounds attractive; whatever. Poor programmers are poor programmers. I personally don't think they get worse having learned about patterns. It can help, but it's not the only thing you need by a long shot. In FP there are lots of patterns. A Functor could be a pattern if anyone bothered to write it up in that fashion. It would make a very nice pattern. Applicative is a great example of a generated pattern -- it's a thing you would never actually design up front, but just pops out. Maybe/Option, Either, etc monads.... awesome patterns (again, if anyone decided to write them up in that fashion). Let's go back to GoF patterns, maybe the Singleton. The Singleton is not a global variable with a couple of bells and whistles. That's a very popular, but misconstrued view. It's actually the bells and whistles that are the point of the Singleton. A Singleton is a method to ensure that something occurs at most one time in your system (potentially scoped). You use it when you have a piece of hardware that will crash if you initialise it twice. Or when you have to initialise a communications protocol exactly once. Or when you have a very expensive operation and you want to ensure that it only gets called once in a particular scope. Usually people use a global scope for their singletons -- because that's what they actually want. But it's not uncommon to scope singletons at a module level, or other kinds of scope. How do you usually implement a singleton? By providing a function in the scope you want that memoises a piece of data. Yeah, it's not rocket science. It's not supposed to be. It's just a technique. And if you don't write essentially the same code in non-object based langues to achieve the same result, I'll eat my hat (or at least I'll ask you how you would do it differently and then suggest that it might make a good pattern). One of the weaknesses of the GoF book was that it wrote all the examples in similar languages. At the time, those were the languages that were relevant. Those were the languages that the authors were proficient in. It might surprise many people to know that the GoF was not the first publication on software patterns (not by a long shot). In fact the GoF was only interesting because they attempted to make a pattern catalogue -- a set of patterns that would be relevant to a certain kind of programming. That this is not the kind of programming you enjoy is completely irrelevant. There are other patterns. You can make other catalogues. That is the whole point. And, you are correct. Patterns don't make a good programmer. But good programmers know programming techniques that are relevant to the style of programming that they use. How do they learn those techniques? How do they communicate where they are appropriate and where they are not? Back in my day we just said, "Here's a keyboard. Don't suck!" And then we'd look at their code and say, "You suck. Why can't you write code like mine?" I'm not really so happy to go back to those days.
- loup-vaillant 9y agoThe singleton thing is interesting, I admit I overlooked the scope thing. In practice though, I only ever used it to overcome a particular C++ deficiency: initialisation dependencies. C++ doesn't specify the order of initialisation across compilation units, so I can't just lean on constructors. To ensure initialisation occurs only once, a static scope and a constructor are enough. And to ensure nobody else can spin up another instance, the constructor can be private, though I've never needed that. Anyway, for extra "clean" points, I tend to just expose the interface of the singleton as a set of global functions, doing whatever's necessary for the user to not having to think about initialisation or `get_instance()` at all. If C++ could guaranteed the order of initialisation satisfies dependencies, we could shave a few lines off that pattern. (Whether this is a good idea is a separate issue.) My point was, each pattern has a corresponding language feature (or set thereof) that could make it less verbose.