Posted by Sam on Feb 10, 2007 at 07:15 PM UTC - 5 hrs
I'm in the middle of reading Steve McConnell's Code Complete 2 (website
), and it is chock-full of good advice (no wonder its considered a must-read classic for software developers). There's been plenty in it I've wanted to share and blog about, particularly the parts about design and class construction, and when I find the time, I certainly will. It just so happened that this time, my computer was already on so the barriers to blogging were low.
In any case, I'm in the chapter where he's talking about the "Pseudocode Programming Process." The idea is that you write precise pseudocode in English (or really, I suppose any human language that your audience will be reading in), and in doing so, you get a clear description of the intent behind the method. Of course, you shouldn't write a novel - the statements should be concise and to the point. He specifies that it should be written "at a low enough level that generating code from it will be automatic," but it should be written at the level of intent. Intent here means that you should talk about the meaning
, not how the code will be implemented
. The added bonus of course, is that you now have useful comments for your code.
I think this fits quite nicely with a link Peter Bell put on his blog
not that long ago, Programming by Wishful Thinking
. Programming by wishful thinking would be at a higher level, yet lower (as I understand it), but it looks like it would dovetail nicely with the PPP
. Its a bit off topic, but to explain why I say higher level, yet lower, I just mean that in PBWT
, you'd be writing statements in your language of choice to implement a solution, and then you'd go implement those methods (this also works well in TDD
. So at the level of the statement, you're writing code, so it is lower level, but it is higher level in that you are designing a higher level routine that would use these helpers. You'd likely use the PPP in both "levels" if you will, though it would probably be more helpful in the lower ones, since the PBWT should be very
I used to take this approach (described in the PPP), but stopped for reasons I'm unsure of. I liked it when I did it, but I guess I got out of the habit. But, you can be sure I'll be trying it out again, especially since a lot of the stuff I'm working on lately is really dynamic programming, with little "real-world" objects to think about.
One long quote which prompted this post that I wanted to share comes when McConnell is describing that as part of the process, you will be naming your method. Of course, we know that a method name should be unambiguous, because it might signify a problem (lack of cohesion, in particular) if you cannot name it without the ambiguity. Here's what McConnell had to say:
Naming the routine might seem trivial, but good routine names are one sign of a superior program and they're not easy to come up with. In general, a routine should have a clear, unambiguous name. If you have trouble creating a good name, that usually indicates that the purpose of the routine isn't clear. A vague, wishy-washy name is like a politician on the campaign trail. It sounds as if it's saying something, but when you take a hard look, you can't figure out what it means. If you can make the name clearer, do so. If the wishy-washy name results from a wishy-washy design, pay attention to the warning sign. Back up and improve the design.
Sound advice, no?
PS: I finally upgraded to Firefox 2.0 (I don't know what took me so long, but apparently I was still running 1.0 on this computer) and I'm loving that spell-check feature.
Hey! Why don't you make your life easier and subscribe to the full post
or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate
wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!
Last modified on Feb 10, 2007 at 07:16 PM UTC - 5 hrs
Leave a comment
Great book Sammy! Just finished it a while back. I sat down this weekend to rewrite LightBase and the biggest problem I'm having is with elegant method naming.
Lets take the simplest thing - %ObjectName%Service needs some get methods to return either 1 or 0..n records. What are the most elegant names for those? In general terms I want to either return a record based on a unique property (ID, email address, SKU, etc.) or based on a filter and display order, so my least bad naming so far is getbyProperty() and getbyFilter(). But then I'd like getbyProperty to be capable of supporting a more than one value so if I want to get ID's 3,7,12 or just ID 2 I can use the same method call so perhaps it should be getbyPropertyValueList() which becomes a little confusing if you're using it to request just a single value.
Working it all through, but I certainly find the code is the trivial part - optimizing the API is the hard part!
Posted by Peter Bell
on Feb 10, 2007 at 09:21 PM UTC - 5 hrs
"return either 1 or 0..n records" - I think 0..n covers it. =) At first I was confused and thought you meant the value "1". But, I understand what you mean.
I like how ActiveRecord in Ruby/Rails does this. They have find_by_id(1) which would return one record, and find_all(filter=>"") and so forth. There are also find_by_%property%() where property would be replaced with the actual property name (and in fact, you can combine them for find_by_prop1_and_prop2(prop1value, prop2value). Of course, I don't think CF offers a way to get /that/ elegant of a solution.
In this case, is there a reason you don't just introduce the 3rd method (and have all three?) I might shorten getByPropertyValueList to getByPropertyList() in that case... Or, why not use the findByFilter to get your set with the list? And then again, I'm not altogether convinced you can't just let getByProperty take the list. This is especially so if you named the argument "propertyValueList."
I don't know if any of those solutions are too ambiguous. /I/ understand what they are conveying, and I'm pretty particular about things like that (I /think/ I am anyway).
In general though, I find it a hard practice as well. I need a bit better discipline. I know when I don't like the name (or the code), but I'm not yet convinced that I'm at the point where, when I am satisfied with the name (or the code), that it is truly excellent.
Posted by Sam
on Feb 11, 2007 at 12:50 AM UTC - 5 hrs
"Working it all through, but I certainly find the code is the trivial part - optimizing the API is the hard part!"
One last thing: I am in agreement here. That's some of the stuff I've been struggling with lately with cfrails.
Posted by Sam
on Feb 11, 2007 at 12:51 AM UTC - 5 hrs
Thanks for comments. I don't actually like "find" as I don't want to find them - I want to *get* them, and why would I find_all when I don't want them all - I want to filter the results set? I actually don't think DHH did a very good job on naming at all, although obviously it is good enough that (like anything) once you learn it, it works.
Still, one way of looking at it is if I can just beat Rails for naming, names may still not be that good, but I guess they'll do!
Posted by Peter Bell
on Feb 11, 2007 at 09:07 AM UTC - 5 hrs
I guess since we were talking about naming methods, I should have been a bit more explicit. When I mentioned Rails' find methods, I was (mainly) referring to the fact that there are analogous ones to yours (or, it seems that way), plus the find_by_property_names.
As far as the find_all, I always took "all" to refer to the number of records that matched, not all the records. It would be like find_10 which would limit the results to 10 (although, I must be honest, I don't know if there is a handler in method_missing that allows it - but I wouldn't be surprised if there was.
As far as naming in general, one of the few things (actually, the only one I can think of at the moment) I dislike about Ruby in general is the naming of some methods. For instance, I would never guess that gsub would take a pattern and replacement text and do the replacement.
However, I don't recall any specific instances I didn't like about Rails' naming conventions. That's not to say there weren't any, but I just can't think of one (although, it seem to me that I did have some trouble at some point).
Posted by Sam
on Feb 11, 2007 at 10:06 AM UTC - 5 hrs
Agreed - was just pointing out the problems that even DHH had with coming up with naming. I now understand the find_all, although I guess it would be less ambiguous if it was find_all_where(filter).
Not putting down Rails per se - just noting how hard it really is to name the simplest things elegantly. For me, find goes back to the old saw about "can" vs "may" (which isn't actually required now unless talking to a fusty old Oxford Don or someone), but the principle was that "can" was simply asking whether you were capable of something whereas "may" was getting permission. So when I was growing up, in certain circles "can I have a biscuit" might be responded to with a "I am sure you are probably capable of it" - it would take a "may I have a biscuit" to get permission. Luckily that language feature is now formally deprecated, but it just shows how carefuly you have to be sometimes!!!
Posted by Peter Bell
on Feb 11, 2007 at 10:20 AM UTC - 5 hrs
Leave a comment
"find_all_where(filter)" --- You're right! I never saw it. Indeed, it is a tough job!
"Not putting down Rails per se" - I wouldn't worry too much about it if I thought you were =).
Can vs. May: I'm glad it has been deprecated =). I got caught by that many times!
Posted by Sam
on Feb 11, 2007 at 10:36 AM UTC - 5 hrs