Another beautiful rant from Uncle Bob: Here’s what an application should look like. The use cases should be the highest level and most visible architectural entities. The use cases are at the center. Always! Databases and frameworks are details! You don’t have to decide upon them up front. You can push them off until later, once you’ve got all the use cases and business rules figured out, written, and tested.
8th light must be something else.

Efficiency arguments bore me. "Don't reinvent the wheel" and "Duplication of effort" are phrases that tell me the speaker does not understand the context of the situations in question. Notice how the solutions they propose are things like "introduce a framework", or "create a common library" or "use a standard tool"?
Stripped of their buzz-phrase finery, all I hear is: "Let's do some work, so we can avoid doing work."
If we don't trust that the people closest to the problem are looking at their options and choosing to "roll their own" because it's the most efficient solution, then we need to solve that problem, instead of trying to solve their so-called common problem with an externally imposed solution.
If you've ever spent any time learning Rails then you probably read one of the editions of Agile Web Development with Rails, and if you're like me (skeptical & pedantic) then you probably asked yourself: what the hell does Rails have to do with Agile development? At the time, I assumed that Dave and David were merely capitalizing on the buzz around Agile; however, even if that's the case, I think they did manage to highlight one of my favorite aspects to building websites with Rails: The ability to make a change, reload the page and see the results makes you a much more agile programmer - where 'agile' is defined as: Characterized by quickness, lightness, and ease of movement; nimble(defonce ignored-namespaces (atom #{}))
(defn reload-all []
(doseq [n (remove (comp @ignored-namespaces ns-name) (all-ns))]
(require (ns-name n) :reload )))
Like I said, when I open a new websocket, I call (reload-all); however, the (reload-all) fn can be called on any event. When discussing this idea internally at DRW, Joe Walnes pointed out that you could also watch the file system and auto-reload on any changes. That's true, and the important take-away is that you can easily become more productive simply by finding the appropriate hook for what you're working on, and using the code above.This is a guest post by Rusty Zarse CTO of Search Discovery, spurred by a series of email conversations that we had regarding the difficulty of finding experienced Rails talent. Rusty leads the Atlanta iOS Developers meetup and is one of the better known technologists in our city.
“Rails is hot,” ain’t no headline today. Five years ago, Ruby on Rails was an underdog, the somebody to watch, the next big thing. It's not news that the Rails community continues evolving and growing while its members do a good job protecting the integrity and quality of the platform. Rails 4 is visible on the horizon and looks better than ever. The growth of the Rails community worldwide appears to be relentless, but there's a dark underside to that growth that does not get enough attention: In terms of sheer numbers, there just doesn't appear to be enough Rails developers to properly serve the needs of the market.
Technical organizations (particularly at the CTO and Director level that I inhabit) are now faced with a stark decision of choosing the Rails platform on its virtues or reluctantly giving the nod to another technology that carries less staffing risk.
On the face of it, people might think that this situation is good for Rails developers because it means that they continue commanding astronomical billable rates, higher quality coding practices and standards for their professional ecosystem and the aura of elite superstars. But Rails remains a community-driven platform and so it's up to the community itself to identify the needs of the market and identify what can be done for our overall growth to continue to flourish.
Our core product at SearchDiscovery does things that truly push the envelope. There's a lot of work remaining to be done, but we feel that it already does what nothing else in the world can do. We owe a lot to the exceptional genius of our Hashrocket team and the wizardry of the lead developer they provided to us. During my career I've led many projects and never seen a product reach this level of complexity without falling apart due to compromises and shortcuts made along the way. I attribute our success in no small part to the principles and practices that Rails embodies. It is the motivation that I had for choosing Ruby on Rails as our web development platform to begin with and continues to provide a level of quality and productivity that I believe is unmatchable.
Our dilemma is that in over 3 months of arduous searching, we have not been able to find even a single Rubyist in Atlanta interested in joining our team. I'm not talking about having to turn down interested applicants; I'm talking about not having any interested applicants to begin with.
Now we have new products in the pipeline and our CEO is pushing to choose an alternative platform. Some of us know PHP and I personally know .NET. My experience with PHP is that its a great hacky tool to tweak wordpress and everything else just becomes spaghetti soup. Microsoft .NET is the platform of choice for developers who like to write the same oil tanker full of plumbing code over and over again just to show how great they are at doing things "better" than everyone else. Here in Atlanta, a common alternative to Rails is .NET, given the large Microsoft contingent we have in town. In my opinion, .NET doesn't deliver quickly enough and PHP inevitably becomes a maintenance nightmare.
Why on earth would we consider switching off Rails? The painful truth is that we need a team of professionals more than we need the best technology. We don't even need to hire an entire army of engineers immediately. We're specifically looking to fill at least one senior position so that this individual can cultivate Ruby on Rails talent within our walls. Our long-term goal is to become that company everyone in Atlanta wants to work at. We admire companies who posses an organic energy and self-managed excellence within their development team and we're willing to invest the capital needed to get there. I feel that we have the professional atmosphere and culture that would be attractive to Rails professionals, but where are they?
Obviously, timing is everything. I've tapped the local user group community and will continue to do so, but so far have not seen much interest in the position. When I do connect with a local Atlanta Rails expert, often the professional courteousness is not reciprocated. I don't want to complain about specific people, but c'mon it just isn't necessary to be rude when someone asks if you are available. Clearly I'm trying to recruit someone, but I'm a CTO not a recruiter. Is politeness too much to ask for? Most technical people in Atlanta are nice and as helpful but there are a handful of dudes with serious reputations that apparently forget that we're all in this together. Their dismissive attitudes are toxic to non programmers who just want to run a business.
Worse, these bad attitudes get back to my bosses. I can argue all day about the gazillion benefits that using Rails brings to the table, but I can’t argue against the facts of our recruiting problem!
I wrote this post at Obie's request when I asked him for advice. I'd failed to consider that this is more than just my problem, more than just a hiring problem: It's a Rails community concern. The Rails platform is not bleeding edge anymore. It's proven, mature, reliable, amazing and a proper choice for just about any web development problem domain you might encounter. I don't know what the solution is, but I do know that we need to ensure that it continues to be the platform of choice for innovation. We’re committed enough in the concept to put our money where our mouth is.
What do you think? Is this actually a community problem? Let's get a greater dialogue going.
At RiverGlide, we’re often asked to help with “Agile transformations”.
My definition1 of agile is being flexible to adapt an existing process.
That is, if your existing process looks like waterfall, you’re still agile if you introspect, retrospect and experiment to improve your process. If at the end, your process looks like waterfall, then as long as you have introspected, retrospected and experimented and found that this approach gives the best results, then your process is agile.
[1] Although this might not fit with other definitions. Your mileage may vary
I’ve been playing around with core-plot, a graphing library for MacOS/iOS, which ships with a local dotset. A normal double click on the docset from Finder wasn’t enough to read it, after a bit of Googling the solution seems straightforward:
~/Library/Developer/Shared/Documentation/DocSetsIf you want to check that Xcode has picked up the new docset then look in Xcode Preferences under Downloads.
For a time, I was a coach. A personal / life / business coach. I loved the work. Well, it didn’t feel like work. It was joyful and amazing.
It was not uncommon for a client to tell me that they felt that they were not yet what / who they wanted to be. When this came up, we’d discuss the question of who or what they wanted to be. We’d create an image of that future self, including the way they’d talk, the way they’d walk, how they’d hold themselves, their posture, their gestures, the presence they’d create when they entered a room, and so on. A rich, full vision of the future self.
Powerful.
“Wow! That’s who I want to be. How do I get there?”
Sounds tricky, right? I mean, if it were easy, wouldn’t we all be powerful or leaders or loved or in the job we want or…
Here’s the technique I shared with my clients.
I get that you’re not yet that person. You have a clear picture of that version of you, who seems like a different person right now. You have a clear picture of how that person would speak, what they’d say, how they’d stand, how they’d move, and the gestures they’d use, right?
Channel that person. Don’t try to be that person. Act like that person.
What would that person say in this situation? Say that.
What would that person do in this situation? Do that.
It has been successfully demonstrated repeatedly that we can change our feelings by changing our words. We can change our behavior by choice, repeating the changes until they become our real selves.
So rather than wondering what I need to do to become the person I am visualizing, I choose to act like that person until I become that person.
Take it on like a persona, until it “takes”.
As it settles in, my feelings will change to reflect the confidence I begin to feel. The behavior will become natural and mine.
One day, I will wake up and discover that I have become the person I was visualizing.
Here’s some code that takes a block called success.
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
// city
NSString *city = [JSON valueForKeyPath:@"location.city"];
NSString *currentTemp = [JSON valueForKeyPath:@"current_observation.temp_c"];
// create a weather object
Weather *weather = [[Weather alloc] init];
weather.city = city;
weather.currentTemperature = [currentTemp intValue];
// notify!
NSDictionary *dictionaryWithWeather =
[NSDictionary dictionaryWithObject:weather forKey:WEATHER_KEY];
[[NSNotificationCenter defaultCenter] postNotificationName:WEATHER_KEY
object:self userInfo:dictionaryWithWeather];
} ...
Cool. But what if I want to pull out that ‘success’ code out into a variable and pass it to the calling method. Here’s what it looks like.
First define a typedef for the block:
typedef void (^success)(NSURLRequest *request, NSHTTPURLResponse *response, id JSON);
You can figure out the typedef method signature by looking at the underlying code, and then just sticking the word typdef in front of it. Note ‘success’ is the name of typdef here.
Then define a variable for the block:
success requestSuccess;
Nothing magical. But I want you to see what assigning a variable to a block looks like. It looks like any other variable assignment.
Then instantiate your method and define the contents of the block.
requestSuccess = ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
// city
NSString *city = [JSON valueForKeyPath:@"location.city"];
NSString *currentTemp = [JSON valueForKeyPath:@"current_observation.temp_c"];
// create a weather object
Weather *weather = [[Weather alloc] init];
weather.city = city;
weather.currentTemperature = [currentTemp intValue];
// notify!
NSDictionary *dictionaryWithWeather =
[NSDictionary dictionaryWithObject:weather forKey:WEATHER_KEY];
[[NSNotificationCenter defaultCenter] postNotificationName:WEATHER_KEY
object:self userInfo:dictionaryWithWeather];
};
Then replace the code you pulled out with the call to the block variable:
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
requestSuccess(request, response, JSON);
}
Voila! Cleaner more readable code.
I've been rereading Zen & the Art of Motorcycle Maintenance. This quote really struck me:
"You are never dedicated to something you have complete confidence in. No one is fanatically shouting that the sun is going to rise tomorrow. They know it’s going to rise tomorrow. When people are fanatically dedicated to political or religious faiths or any other kinds of dogmas or goals, it’s always because these dogmas or goals are in doubt." ~ Pirsig, Robert M. (2009-04-10). Zen and the Art of Motorcycle Maintenance (p. 140).
Made me think of all the zealotry accusations levied at Extreme Programming practitioners about 10 years back... still seen in reaction to some of the more ardent claims of the primacy of TDD even today.
No conclusions, just suspect I will see the next fanatic a little differently next time I encounter one.
Remember the SAT test and their ridiculous analogy questions? “Apple : Banana as Steak : ???”, where you have to figure out the relationship between the first pair in order to guess what the relationship in the second pair should be? (Of course, the SAT guys give you a multiple-choice answer, whereas I’m leaving it open to your interpretation.)
What triggers today’s blog post is this article that showed up in GeekWire, about how Firefox is accusing Microsoft of anti-competitive behaviors by claiming IE will have an unfair advantage on their new ARM-based machines.
Anderson says the situation has antitrust implications. Microsoft has agreed to abide by a set of principles to maintain a level playing field on Windows for competitors despite the expiration of its consent decree with the U.S. Justice Department.
OK, wait a second here. Last time I checked, there’s another operating system out there that completely and entirely prevents any kind of web browser from being deployed on it, which strikes me as grossly anticompetitive, and yet Mozilla chooses to fire their guns at Microsoft, who is attempting to take a shot at the ARM market?
Seems to me like somebody’s either not getting the point of “anticompetitive”, or else they’re just taking a potshot at the company that everybody loves to hate because it’s an easy shot. If Mozilla is really serious about anticompetitive concerns, they will ask DOJ to investigate Apple’s iOS (that owns, what, 2500% of the tablet market) and AppStore, not Microsoft IE on a market that doesn’t event exist yet.
Otherwise, I call bullshit.
Keif Morris thoughtfully compares/contrasts Agile to Continuous Delivery (CD).
Of course the answer to the question posed in the post title is Yes, Continuous Delivery is agile. Very agile, in fact.
Keif raises several concerns traditional Agile has with Continuous Delivery. I admit to being from the old school, XP, and am a little nervous around CD. But I embrace its spirit.
With Agile leaving small release messes to clean up each iteration, or for Waterfall one giant mess to clean up in the release phase, is bad for the nerves too. At least CD picks up after itself in an ongoing basis.
As a daily Java programmer Maven makes a hash of this as Keif points out. But as with many things related to Maven, you gain a few pains and lose several others for net betterment. How does CD treat the snapshot ailment?