Design patterns: signs of languages’ weaknesses?

A nice post by Mark Dominus about design patterns. I include the post here in case the link is modified. You should also read the response by Ralph Johnson and Mark’s follow-up.

Source: http://blog.plover.com/prog/design-patterns.html, by Mark Dominus


Design patterns of 1972

Patterns” that are used recurringly in one language may be invisible or trivial in a different language.

Extended Example: “object-oriented class”

C programmers have a pattern that might be called “Object-oriented class”. In this pattern, an object is an instance of a C struct.

 

        struct st_employee_object *emp;

Or, given a suitable typedef:

 

        EMPLOYEE emp;

Some of the struct members are function pointers. If “emp” is an object, then one calls a method on the object by looking up the appropriate function pointer and calling the pointed-to function:

 

        emp->method(emp, args...);

Each struct definition defines a class; objects in the same class have the same member data and support the same methods. If the structure definition is defined by a header file, the layout of the structure can change; methods and fields can be added, and none of the code that uses the objects needs to know.

There are a bunch of variations on this. For example, you can get opaque implementation by defining two header files for each class. One defines the implementation:

 

        struct st_employee_object {
           unsigned salary;
           struct st_manager_object *boss;
           METHOD fire, transfer, competence;
        };

The other defines only the interface:

 

        struct st_employee_object {
           char __SECRET_MEMBER_DATA_DO_NOT_TOUCH[4];
           struct st_manager_object *boss;
           METHOD fire, transfer, competence;
        };

And then files include one or the other as appropriate. Here “boss” is public data but “salary” is private.

You get abstract classes by defining a constructor function that sets all the methods to NULL or to:

 

        void _abstract() { abort(); }

If you want inheritance, you let one of the structs be a prefix of another:

 

        struct st_manager_object;   /* forward declaration */

        #define EMPLOYEE_FIELDS
           unsigned salary;
           struct st_manager_object *boss;
           METHOD fire, transfer, competence;

        struct st_employee_object {
           EMPLOYEE_FIELDS
        };

        struct st_manager_object {
           EMPLOYEE_FIELDS
           unsigned num_subordinates;
           struct st_employee_object **subordinate;
           METHOD delegate_task, send_to_conference;
        };

And if obj is a manager object, you can still treat it like an employee and call employee methods on it.

This may seem weird or contrived, but the technique is widely used. The C standard contains guarantees that the common fields of struct st_manager_object and struct st_employee_object will be laid out identically in memory, specifically so that this object-oriented class technique can work. The code of the X window system has this structure. The code of the Athena widget toolkit has this structure. The code of the Linux kernel filesystem has this structure.

Rob Pike, one of the primary architects of the Plan 9 operating system (the Bell Labs successor to Unix) and co-author (with Brian Kernighan) of The Unix Programming Environment, recommends this technique in his article “Notes on Programming in C”.

Pages: 1 2 3 4

7 Comments

thleFebruary 10th, 2007 at 1:16 pm

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? :-)

thleFebruary 10th, 2007 at 3:02 pm

When we identify and document one, that should not be the end of the story. Rather, we should have the long-term goal of trying to understand how to improve the language so that the pattern becomes invisible or unnecessary.

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.”

Buu NguyenFebruary 10th, 2007 at 3:38 pm

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

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.

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.

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)

In C, C++, we don’t have concept of Collection class, Event

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.

We even have some built-in design patterns in the language such as Iterator in Java

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)

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.”

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.

Phong BuiFebruary 10th, 2007 at 5:09 pm

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.

thleFebruary 11th, 2007 at 6:50 am

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! :-)

Buu NguyenFebruary 11th, 2007 at 7:15 pm

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 bet the design pattern is more than code reuse. Design patterns solve design problems. Code reuse is one of design problems.

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.

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.

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.

Buu NguyenFebruary 11th, 2007 at 11:57 pm

…point out that the increase demand on code reuse, and speedy developed apps; and the languages & technologies has evolved a lot for that demand.

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

Let’s separate C# from Base Classes Library and use it alone, that will create another Microsoft or Sun.

Hmm, what do you mean? :-)

I dont subject to something that will beat OO programing. If there is another better, I will use it. Let’s wait, who knows

I guess I’ll elaborate this a bit when discussing about C# 3.0 :-)

Leave a comment

Your comment