Programming concurrent or distributed software has always been a difficult problem, so to brush up on the “best practices” in the field I picked up Pattern-Oriented Software Architecture, Volume 2: Patterns for Concurrent and Networked Objects. In contrast to books I’ve previously reviewed, this book has some incredibly strong points and some incredibly weak points (and ends up a little above average I suppose).
Let me begin by saying that I haven’t read POSA Volume 1 yet and I’m concurrently reading Design Patterns (which I’d say is equivalent to POSA Volume 1), so I may be at a slight disadvantage here. That being said, the authors outright tell us that most of the patterns in this book rely on the Wrapper Fascade pattern, which is conveniently the first pattern described.
The Wrapper Fascade basically wraps some C code in C++ libraries to make your old libraries object-oriented and easier to handle. The example they do is worked out very well and makes a very convincing argument that you should always be doing this. However, at the end of the chapter (if you haven’t figured this out for some reason somehow) that this only works for languages that can call C code conveniently and quickly. So now my OO scheme for wrapping my fast legacy code is screwed because the only language that they tell you this will work for is C++ and now it’s not an OO scheme but really a C++ scheme. Granted this isn’t the author’s fault: they didn’t go make it hard as hell to write C/Java interoperable code, but the fact that most of the patterns in the book rely on the Wrapper Fascade screws you into writing C++ code (again, not that there’s anything wrong with that, but this is an OO book and not just a C++ book). The only possible saving grace here is that Python can apparently call C libraries really easily (possibly will cover this in a later post since the Google results are not being helpful for once), so at least there’s another possible OO language that we can use here.
<soapbox>Since I’m still griping about specifics, the second pattern, Component Configurator, really shows the date of when this book was first published. The idea is noble and quite beautiful (well as beautiful as this crap can get): you have some classes but you have them DYNAMICALLY linked so you can re-compile, re-link, and do other fun stuff with your code in the name of reliability. The downside is again, the implementation. The C++ implementation of this is so brutual I literally stopped reading the book page-by-page and depressingly realized I was not going to get through this book in a reasonable time and retain a reasonable amount of information the way I was doing it thus far. Then there’s the whole “dated” concept. This example just makes the book feel OLD. Why not just use Java with dynamic class loading? That’s one of the great perks of having a bulky-ass runtime system with virtual machine etc etc etc! The code may still not be pretty but it can’t be as bad as this. Some slack has to be given since this book first came out in 2000, which you can obviously tell when they say Java has some cool stuff like applets which nobody has given a crap about for several years now, but you’d think that with the six rounds of corrections made over the last eight years they could put in a little footnote that says “Exercise for the reader: Go check out this webpage about class loading and tell us if it makes things easier?”. </soapbox>
The other thing that is both this book’s greatest blessing and most miserable curse is the amount of detail they go into (admittedly this is a pattern language trait and not specific to this book). If I actually wanted to implement this stuff, then you’ve got it all here in wonderful cookbook form. But that’s exactly what it is. Holy crap is this thing boring to read from front to back when NOT skimming it! They reference other patterns up the ass (which again is wonderful if actually implementing this) but on my first read, I haven’t gotten to the parts about later patterns and thus have NO IDEA what they’re talking about. Some of the solutions also seem a bit long-winded, but this may be okay since they’re actually trying to solve real-world problems and get caught up in implementation details and the like.
So you’re not gonna really get the material in the book on the first read-through, which kinda sucks, but there’s some possibility that it’s like the other pattern books and is like wine (it’s an “acquired taste” and gets better with time). The authors claim this is so when they tell us that the true power of patterns comes out when patterns are used together, and that no pattern stands by itself. Since many of the examples really seem to shine when two or three patterns are used, I buy this argument (although the picture they have at the end with all the patterns together looks completely insane yet neat).
Everything being said, I still like this book. It’s got better potential now that eight years have passed and there are new possibilities for implementing these patterns better, and that brings up an important point: many of the patterns here are really good for concurrent systems. I like about half of them and couldn’t care less about the other half, but when the book is all about the details, and the details are eight years old, I get irked. Here’s an example of one thing I did like though: The “Scoped Locking in C++” pattern. They specifically tell you “this is a C++ pattern and if your language doesn’t do this then you’re screwed” as opposed to telling you at the real end of the chapter “hey all that stuff you learned only works if your language is inter-compatible with C and here’s some languages that aren’t” (see Wrapper Fascade from earlier). They’re up-front about it, their implementation is good, and it solves the problem.
So probably the book’s subtitle should be changed from “Patterns for Concurrent and Networked Objects” to “Patterns for Concurrent and Networked C/C++ Code” or an update is needed (and I’d rather see the latter), but I’m definitely keeping a list of the patterns and what problems they solve at the office just in case one of these problems creeps up and I need a solution. Furthermore, since this book has come out, SWIGand ctypes have come out as great solutions to the Wrapper Facade problem, which we will definitely talk more about later.
I’m working on Design Patterns and POSA 4: A Pattern Language for Distributed Computing, so we’ll see what problems and joys here are specific to this book and which are pattern-like symptoms. However, I’ve currently been drawn in by an old book I bought several years ago but never got around to reading (Gödel, Escher, Bach), so after I look over that, we’ll be back on track with patterns.