In the past, one of the nice things about web application development versus desktop development has been the proliferation of application development frameworks. Where desktop development pretty much gave you a set of GUI components and a few concepts like event driven programming and MVC, web frameworks, in particular the more recent ones such as Rails and Grails, gave you an application architecture into which you could implement your domain specific logic.
Lots of benefits accrued from this predefined structure, not the least of which was the ability to quickly understand the application based on a shared understanding of how applications using this framework were put together. In my experience of looking at desktop and web applications over the years, the web applications were better and more consistently designed than their desktop counterparts. Similar tries at desktop frameworks just never seemed to gain any traction (recall Scope, an app framework based on the HMVC pattern that died of neglect).
Now along comes Griffon, a desktop application framework modeled on (and sharing an architecture) with Grails. Griffon has a very similar controller, view and model breakdown as Grails, and support for plugins. I’d like to see similar frameworks for .NET and Cocoa (yes, yes, Cocoa has some of it’s own framework goodness, but could use some higher level application abstractions to make application development more consistent).
I got a few angry and scolding comments on my last post on pair programming. Let me address each of the issues in turn:
It’s easy for folks to misunderstand pair programming and to dismiss it as useless, weird or wasteful. It’s one of the first things that gets ditched when the going gets tough, yet it’s one of the most important, along with TDD. That’s why I wanted to make as strong of a statement as possible in favor of pair programming and against singleton programming.
What I like about authlogic is it refrains from providing any controller/view level support and handles model layer better. Instead, it provides a solid model functionality that is similar in principle to ActiveRecord and provides lots of how-to examples on how you might code your controllers/views/workflows. It does it well. Although authlogic is complemented for refraining from too much code generation, Authlogic still does a lot of magical stuff. You encounter this readily with tests. Instantiating and persisting a user will log you in! It is hard to test your User model from console since authlogic will fail if you try to instantiate User object in console. You have to jump thru hoops (include Authlogic, set proper controller reference) to get it to work. (more…)
Cold Caller: I just Googled “Software+Developers+Chicago” and your company didn’t show up on the first three pages. You can use our help!
Me: I just Googled “Search Engine Optimization Consultants.” Your company didn’t show up on the first three pages either.
Cold Caller: Thanks for your time, sir.
When scientists and engineers explain their esoteric disciplines to the general public, they reach for analogies. Sometimes those analogies are apt and serve to clarify what is hard to understand, sometimes they are less apt and serve to obfuscate and confuse. We certainly use our fair share of analogies in software development — construction, manufacturing, brain surgery — and some of them, especially the one to construction, have been very harmful.
So when I saw the article in the NYT this past week on pair programming, I started counting the analogies.
A lot of pair programming chatter this week. Starting with a New York times article describing pair programming at Hashrocket. It’s an interesting article, with a tone that could be described as “anthropologist describing the strange, yet quaint customs of the native tribe”
Obie Fernandez followed up with a list of 10 reasons why pairing doesn’t work in most cases. It’s actually a list of the things that Hashrocket does to support pairing, although entries like “2. Most software developers just don’t want to work that hard” and “1. Most software shops don’t really care about excellence” do have a certain, “aren’t we great” vibe to them, causing Mike Gunderloy to dryly observe: “Funny, Extreme Programming Explained never said anything about fancy hw or being awesome as a prerequisite for pair programming.”
C’mon Mike — everybody knows that being awesome is a prerequisite for everything in XP.
Josh Susser adds that pair programming isn’t right for all projects, particularly projects that have long compile times that force the pair to stare blankly at the screen.
I’d also add this interview with Kent Beck because a) every programmer could use some more Kent Beck in their life and b) because he talks about XP as being concerned with the the social context of programmers, with pairing being a part of that.
Now you are caught up. Here’s the part where I talk.
A couple of days ago I happened upon an interesting article about the difference between art and design. The author makes a lot of interesting points, and whether you agree or not with the statements he makes, the article does make for a great conversation starter.
Art and design are two different words, and some say two different worlds as well. The use of each often comes with a distinct connotation. I could go on about how design’s goal is to solve a problem, whereas art doesn’t necessarily always have a problem to solve. I could talk about how art doesn’t necessarily require a common user experience, whereas design more often than not does. I could expand upon that by discussing how art doesn’t require that a thing be usable, whereas design is often judged in part or whole by its level of usability. I could even discuss how art can be effective whether done collaboratively or not, and contrast that with numerous examples of how here in our agile software development environment at Pathfinder we find collaboration inseparable from our design process.
But I could also talk about how much art and design overlap and blend, so much so that it becomes difficult to make concrete distinctions. And how, sure, software design is about solving a problem, but it’s also about solving a problem beautifully. (more…)
If you’re an ambitious new Rails developer in Chicago who wants to work along side Dr. Noel and our other sage Rails developers, check out our Rails Internship.
The problem: I needed to display a warning to a user if the data they were looking at was more than 90 days old.
The solution: Create a method that takes 2 dates (either DateTime or Time), and returns the number of days, or hours between them.
def self.difference_in_dates(date1, date2, unit = 1.day) return nil if date1.nil? || date2.nil? || unit == 0 (( date1.to_time - date2.to_time ) / unit).round.abs end
The problem was simple enough, and my tests were all passing, so I moved on to my next task.
That code has been out in production for several months, but earlier this week, a new developer told me he got an error when running the test:
NoMethodError: undefined method `to_f' for Mon, 21 Sep 2009 14:29:38 -0500:DateTime
(we’re running this in Rails 2.0.2)
I looked at the code, knowing it was working before, ran the unit tests myself, and didn’t see the issue. Now I’m on Windows and everyone else is on a mac, so as soon as I run into an issue that no one else has seen I want to prove if its a Windows problem. But wait, this test has been running in our Continuous Integration server (Hudson) for months, and no one else on the team ever had any issues with it, and the code has been working in production without any errors in the logs.
I jumped into rails script/console to see what’s up, and here’s what I found:
>> x = DateTime.now => Wed, 23 Sep 2009 00:00:00 +0000 >>; x.to_time => Wed Sep 23 00:00:00 UTC 2009 >> x.to_time.to_f => 1253664000.0
Which is what I expected, but when I asked the other developer to run that same instruction, he got an error.
>> DateTime.now.to_time.to_f NoMethodError: undefined method `to_f' for Mon, 21 Sep 2009 14:29:38 -0500:DateTime
What’s up with that? We’re running the same code, and all of our libraries are the same version. Looking at the date value in his error, I saw the timezone, and decided to try this variation locally:
>> x = DateTime.parse("2009-09-21T14:29:38-0500") => Mon, 21 Sep 2009 14:29:38 -0500 >> x.to_time.class =>; DateTime
So I’m gathering that when there is a timezone and you ask DateTime.to_time, its just going to give you back a DateTime.
I’ve worked on more than a few software projects over the decades and one of my favorite little misunderstandings is the Importance versus Effort disconnect. That’s where non-experts assume that because a particular part of a software system is more important than another, it must also take more effort to develop. That is rarely the case and, in fact, importance — however that is defined — is rarely a driving factor in determining effort or cost. This sort of misconception can result in some planning and budgeting mistakes, sometimes to comic or even tragic effect.
To illustrate, I can point to a trading system that I worked on (the names have been changed to protect the innocent). The average size of a transaction in this system was over $1 billion in 1990′s money. The part of the system that resolved the transactions was really really “important,” but the part of the system that allowed an application helpdesk to support users by seeing what their user’s saw cost 60% more to develop. That’s right, an “unimportant” helpdesk module was more expensive and took more effort and cost more than the “important” backend that handled billions of dollars a day.