Design patterns: signs of languages’ weaknesses?
This is a pattern
There’s only one way in which this technique doesn’t qualify as a pattern according to the definition of Gamma, Helm, Johnson, and Vlissides. They say:
A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. The solution is a general arrangement of objects and classes that solve the problem. The solution is customized and implemented to solve the problem in a particular context.
Their definition arbitrarily restricts “design patterns” to addressing recurring design problems “in object-oriented systems”, and to being general arrangements of “objects and classes”. If we ignore this arbitrary restriction, the “object-oriented class” pattern fits the description exactly.
The definition in Wikipedia is:
In software engineering, a design pattern is a general solution to a common problem in software design. A design pattern isn’t a finished design that can be transformed directly into code; it is a description or template for how to solve a problem that can be used in many different situations.
And the “object-oriented class” solution certainly qualifies.
Codification of patterns
Peter Norvig’s presentation on “Design Patterns in Dynamic Languages” describes three “levels of implementation of a pattern”:
-
Invisible
-
So much a part of language that you don’t notice
-
Formal
-
Implement pattern itself within the language
Instantiate/call it for each use
Usually implemented with macros -
Informal
-
Design pattern in prose; refer to by name, but Must be reimplemented from scratch for each use
In C, the “object-oriented class” pattern is informal. It must be reimplemented from scratch for each use. If you want inheritance, you have to set it up manually. If you want abstraction, you have to set it up manually.
The single major driver for the invention of C++ was to codify this pattern into the language so that it was “invisible”. In C++, you don’t have to think about the structs and you don’t have to worry about keeping data and methods private. You just declare a “class” (using syntax that looks almost exactly like a struct declaration) and annotate the items with “public” and “private” as appropriate.
But underneath, it’s doing the same thing. The earliest C++ compilers simply translated the C++ code into the equivalent C code and invoked the C compiler on it. There’s a reason why the C++ method call syntax is object->method(args…): it’s almost exactly the same as the equivalent code when the pattern is implemented in plain C. The only difference is that the object is passed implicitly, rather than explicitly.
In C, you have to make a conscious decision to use OO style and to implement each feature of your OOP system as you go. If a program has fifty modules, you need to decide, fifty times, whether you will make the next module an OO-style module. In C++, you don’t have to make a decision about whether or not you want OO programming and you don’t have to implement it; it’s built into the language.












What a long post!
I have not yet read all of the words in this post but I think I know what you want to say.
OO programming has been evolved a lot since its beginning.
Programmers have received a lot from language support. Things usually not perfect when it’s first created. People always try to improve the programming language.
Back to 80’s, the “Internet†concept has not yet popular, most applications just as simple as a simple app that runs on one machine. We did not have “Enterprise Application†that day. So, app is just about 3-5 lines of code, we don’t need Code Reuse.
But the life is not that simple, the demand on bigger applications has increased while Internet becomes more popular. As a consequence, app contains thousands line of code. Now we need Code Reuse, and that’s where Design Patterns starts its life.
When the demand for code reuse increases, programming languages has to change. In C, C++, we don’t have concept of Collection class, Event, …In more modern languages, e.g Java, vb6, we have those concepts. We even have some built-in design patterns in the language such as Iterator in Java. In recent language changes, we have more built-in patterns, e.g ASP.NET has MVC.
It’s obvious that languages and technologies always change in order to improve its weakness. So, is it necessary to say something is a sign of languages weakness?
Even if we have a super good language, I am sure that we will still have patterns, as patterns are exprience reuse. it’s something like ” Hey, you want to sth efficiently, do it like me. I did it that way and … it works.”
In case you are not aware, this post is not written by me, it is written by Mark Dominus at http://blog.plover.com/prog/design-patterns.html :-). I find this post very interesting thus I include the verbatim post here.
Back to your comments, while I can see where you are coming from with your arguments, I do not agree with many of them.
This is not entirely true. Complex applications which run across multiple machines (mainframes and interactive terminals) was not hard to be found in the 70’s. Enterprise applications (ERP for example) written in COBOL (created in 1959) also existed long before the 80’s and consisted of milions of LOCs. And code reuse, contrary to your thinking, was the hope of very early programmers (information about one of the oldest user groups about code reuse can be found at http://en.wikipedia.org/wiki/SHARE_%28computing%29)
Note that even in the Java language, we do not have these concepts as well. In fact, Collections and Events exist at the library or framework level, NOT at the language level. On the other hand, I agree that the concept of event and delegate exist in a .NET language like C# or VB.NET.
Not true, Java does not have iterator pattern built into the language, it only exists at the library level. However, in languages like Ruby and Python, Iterator is not necessary since closure can address the same need, or C# 2.0 with the foreach and yield keywords is kind of making the iterator pattern blended into the language level (although they are in fact just syntatic sugar and do not exist at the CIL level)
Good point! I totally agree with this. Patterns will always be there simply because there is no such thing as a perfect language. Any language, at any level of abstraction, will have patterns associated with it, even if we can code by UML (or even voice :-)). After all, every pattern has a context, and the language itself is part of that context.
At the first time I wrote a singleton class I had the question in my mind that was why doesn’t Java support a way to define a singleton class easier. It would be nice if I need only one keyword to mark a class as a singleton one. I wouldn’t need to handle of creating only one instance or safe-threading. When applying Template pattern to my framework, I recognized that Java seems to be biased this pattern since it has abstract classes.
Those things came and there was something appeared to me that design patterns are well-known chess-positions. Software development is a chessboard and programming languages support fundamental things (i.e move, capture, checkmate, etc…). Those things help programmers play on this chessboard. Let’s say if programming languages had supported resolution for each particular chess-position the player would have proceed only one step to solve the game (instead of doing a number of steps) when it is falling to a predefined chess position.
Stop the chess game above and back to software development, it would be nice if programming languages could enrich them by building-in some well-know design patterns. So I prefer addressing this way rather than calling “languages’ weaknesses†although both result almost same?
We could somehow count the number of chess-positions so far but I cannot count it up to next 5, 10 years or even next 5 minutes since we’re living in a very innovational world. Deep Blue machine was built-in more than 2 million chess-positions but nobody correctly say that’s enough and all for now.
Tai has pointed out some interesting information regarding to design patterns. However, I bet the design pattern is more than code reuse. Design patterns solve design problems. Code reuse is one of design problems.
I almost agree with Buu what you’ve commented on Tai’s notes here. However, for me a programming language is not only syntax but also library. Behind syntax are built-in libraries. Fully separating library from a programming language isn’t somewhat precise.
I was just want to point out that the increase demand on code reuse, and speedy developed apps; and the languages & technologies has evolved a lot for that demand.
As I said, I did not read thru the post, and did not notice all the details. The post wanted to claim the languages, not the libraries.
Let’s separate C# from Base Classes Library and use it alone, that will create another Microsoft or Sun.
Another point, OO programing rules the game now. Wanted to claim the language, let’s claim OO programing first.
I dont subject to something that will beat OO programing. If there is another better, I will use it. Let’s wait, who knows!
You have a very interesting comparison, anh Phong; however, I am not quite sure I understand what you aim at by this comparison. Do you want to say that because there are so many chess positions that there should be no limit to the number of patterns? (If this is what you mean then there is at least one flaw: the number of chess positions is finite, while the number of patterns is not.) If not, can you elaborate your argument further?
I agree. Design pattern is meant to create high-quality design. Depending on the architectural constraints of a particular project, a high-quality design usually mean performance, extensibility, maintainability, reusability, reliability, usability and so on.
Depending on the topic that we are discussing about, it may or may not be necessary to distinguish the semantics of a programming language from its built-in libraries. For this particular topic (design patterns are signs of programming languages’ weaknesses), it’s worth making the separation.
That’s true, programming languages and technolgies evolve to help us develop more complex software in less time and reusability is one of the objectives
Hmm, what do you mean?
I guess I’ll elaborate this a bit when discussing about C# 3.0