I just got back from doing a short presentation at Edmug on some of the new features in .NET 3.5. While I was preparing for this presentation, I decided that I should start doing some screencasts. Because the topics have been blogged about all over the web, including by me, but I've never seen them demo'd, I figured that I would do a set of screencasts on some of the new language constructs.
The first one is on Simple Properties and Anonymous Constructors. You'd think that there wouldn't be much there, but it totals out to just over 26 minutes in length. I also have picked up a series of good questions and answers from tonight's crowd that I'll add to a follow up screencast. You can download the avi here (I just tried opening this and it was deathly slow. You're best bet will be to right-click and Save As instead of trying to stream it). You'll also need the Camtasia Codec which is available here.
Let me know what you think of this attempt and I'll see what I can do to make the next one better.
I've been tormented and ridiculed by someone from Winnipeg (I know, *really* embarrassing), a guy from the US, and some whacko for an alternate hair reality. All have posted on the things that they're looking to concentrate on for the next while. Apparently this is expected of me too.
Get the passion back
I've got to work on finding a way to get my passion for coding back. I think it's there, just below the surface, but it's being pushed down by factors other than my love for coding. Of all the items that you see on my list, this is going to be the hardest to accomplish. There's a really good chance that I'll probably need to take a break from the daily work grind to re-energize and refocus. If I don't accomplish this, I'm destine to become a 9-5 code monkey who doesn't push their skill boundaries, doesn't pursue the best solutions and is content blending in.
Become a specialist
Traditionally I've always been a jack of all trades when I've been at different companies. I don't think that this is a bad thing. When a developer is starting out, I think it's good for them to be exposed to as many different tools, techniques and project areas as possible. As we move on in our careers, we do tend to develop higher levels of skill in some, but not all, of the areas that we're exposed to. I need to step back from what I'm currently doing and decide what exactly I want my responsibilities to be. What am I good at? What is it that I want to do daily? What holes in the industry can I realistically fill? If I sit down and answer all of these questions I think that I'll become a much better, due to focus, programmer.
Right now I have two blogs. This one and my food one. To me, both seem to get neglected. I need to rectify that. The food one is pretty easy to fix. I just need to start writing about more of the restaurants that I visit and more of the food I cook. Simple question of making the time. For this blog it's a little different. I have a personal goal of keeping this blog filled with original material. I don't want this site to become a link blog (no offense to this guy or this guy who have fantastic link blogs) or a place for the endless stream of new product release announcements. For me this leads to a bit of an information problem. I only write for this blog when I'm feeling a great deal of passion about my topic. As I mentioned earlier, that passion has been fleeting recently. I figure that at the best of times my post count is not going to be but a small fraction of what someone like Ayende generates. I do want to try to increase my post count, but not at the expense of the content. The first step to that is going to be making more time to think about what I want to write. If I think about it, there's a better chance that I'll get fired up enough to write about it.
One of the things that I really like to do is evangelize the development tools, techniques and methodologies that I'm passionate about. I find that committing to these events helps me to force myself into learning as much as possible about the subject. I'm going to focus on getting involved in more speaking engagements such as Code Camps, User Group meetings, conferences and even internal lunch and learns.
I'm not going to list a series of books that I have waiting in the wings. The truth is, I don't have one. Instead I want to make the time to read a list of books that has nothing to do with technology. I'm a firm believer that everyone needs a good work-life balance. I also think that taking the time to pursue the life portion of that balance will elevate your results and enjoyment at work. For the past couple of evenings I've been reading Iran Awakening by Shirin Ebadi (highly recommended) and the escape from technology that it has provided me has given me more energy to work on things within the technology realm.
So that's the list of things that I'm supposedly going to do to become a better programmer. Unlike the other guys that have commented on this, I had no interest in putting arbitrary numbers to any of the items I listed. In some ways that flies in the face of good goal setting (which is what this really is), but I'm not convinced that any of these things can truly be measured. I could have said that I was going to speak at 8 or more events in the next 6 months, but what correlation is there between those two numbers and the goal of becoming a better programmer? For me, the action (speaking, blogging, etc.), not the frequency or volume, is what makes you a better programmer. If I write on thought provoking and informative post, I've probably taken a bigger step towards becoming a better programmer than if I posted 10 times about "Product X is now Beta!".
Take all this for what it really is, a personal exercise in goal setting. Whether you agree or disagree with what is listed here, it never really was something for you to comment on. It was a mental exercise that I just happened to commit to my blog.
I received an email at work the other day saying that one of Edmug's members had just been awarded a prestigious distinction. It seems that the nomination of this person had passed me, and most people from what I hear, by. So late, but with no less congratulation....
Christina Gray was nominated for the Inroads category of the YWCA of Edmonton's Tribute to Women of Distinction Awards this year (2007). When I first heard the title Inroads, I was lost for a definition. Here it is for you.
for a woman recognized for making inroads into non-traditional or new career areas, such as industry and the trades, or fields related to environmental, scientific or technology-based work in Edmonton and area.
What I know of Christina. Well, she's been a stalwart attendee of Edmug's monthly event and our first annual Code Camp. At times she has been the only female attendee at them. Not only an attendee, Christy has participated in Edmug by presenting and being our saving grace one night where she offered and organized her work location on a moment's (literally) notice.
It's one thing to participate in those ways, it's entirely different to be the mentor for new programmers that she is. Regularly during the conversations I have with her she mentions how she's working to expose her current students to more in programming by bringing them out to Edmug to meet, greet and learn.
Here's how the program at the Gala introduced her.
After working as a Microsoft certified trainer for 4 years, Christina Gray returned to Dev Studios in Edmonton to become the lead instructor for the software development program. As the only female instructor in a traditionally male dominated field, she has dramatically influenced the perceptions of students and staff. Christina also provides strong mentorship for the few women who are already involved in the technological industry and students at Dev. Through her enthusiastic work in the non-profit and political sectors, she is a role model for her students. With energy and passion, the inroads Christina has made in this industry has forged the path for those that follow.
Christina, on behalf of all of us running and attending Edmug, congratulations. A more fitting and deserving recipient could not be found. Oh, and get a blog so I can link to it ;)
I'm in the midst of reading Oren's latest post about Working Software Over Comprehensive Documentation. While I generally agree with Oren (and I realize he's a big enough man that I don't want to piss him off), I did see one statement in that post that scared the shit out of me. The following is made in the discussion context of refactoring to a previously tried and proven-to-fail (for whatever reason) implementation.
And then I would run the tests and they would show that this causes failure in another part, or it would be caught in QA, or I would do the responsible thing and actually get a sense of the system before I start messing with it.
Okay, Oren. Here's where I get someone large in stature (not JP or Bellware) between you and I. What the hell man? Sure you run the tests and they might show the ensuing failures. Might is the operative word there. What if there is no test for that implementation that you've just switched to? Well, according to your statement it "...would be caught in QA". Based on that statement I'm understanding that you, Oren, are claiming that it is okay to defer finding issues, which are the result of refactoring, until QA.
I understand that we are always sending bad, buggy and sometimes plain crap code to QA. If there were no defects in the code that we sent to them, what would they have to do during the day? Having them there as a second sober look (the first being the development team) is not carte blanche to be sending code off to them willy-nilly. If we allow ourselves, as developers, to accept the thought that "...it will be caught in QA", we're standing at the top of a very, very slippery slope.
If it's okay to say "My tests didn't catch it so it must be good. Send it to QA." when performing refactoring, what will be the next task that its acceptable to say this for? Perhaps when I build that screen and I don't really feel like checking the tab order I should be allowed to make that same statement. Now you're firmly on the slippery slope, sliding head first to the bottom where you will be greeted by a giant pile of manure.
We developers are pushing techniques such as TDD, BDD and Continuous Integration through tools like xUnit, ReSharper, CruiseControl.NET and many more. We push this stuff because we claim to want to ensure that we can build and maintain code at the highest levels of quality possible. Sometimes striving for those lofty peaks of quality we will have to pause and write some documentation about the code. We will have to make notes about techniques and past experiences that have failed. If we don't we are doomed to repeat our own history.
Like Oren (this is where I suck up), I'm firmly in the camp of Working Software. That said, I like to be pragmatic about the tradeoff between Working Software and Comprehensive Documentation. Note that the trade off is with comprehensive documentation. I'm currently seeing a system where every finite detail must be documented prior to releasing features to development. With as much paper as is generated, I'd think that the next generation of developers (namely maintenance) would have no problems figuring out what is going on with the system. That said, they could probably figure it out in about the same amount of time given 50% of the documents that we're generating. That's where you need to make the trade off.
Are we giving the next developer to look at this enough to get things figured out in an acceptable time frame? If you can take away some of the documentation and spend the time providing business functionality to the client, everyone will be a lot happier.
Yes, you read that right. Edmug is going to have two shorter presentations on the 28th of June. Top Opgenorth is going to present an introduction to embedded databases and db4o. I'm also going to be presenting on this night. My topic will be the new C# Language features in Visual Studio 2008. I'm not going to cover Linq as I think it's been done to death at the expense of some of the other nice language and IDE features that are coming down the pipe. I'm only going to have one hour so the talk won't cover a tonne of topics, but for the ones I do cover we will get quite deep into how they work, any interesting compilations they create and how these may be useful to you in your daily development. Some of the topics I'm looking at covering are:
- Anonymous Constructors
- The 'var' type
- Extension methods
If there are any others (not including Linq) that you'd like to see presented on, leave me a comment and I'll do what I can to fit them in.
Patrick Cauldwell wrote a brilliant post recently about the guiding principles for running your software development projects. It runs the gamut from how to know when a piece of code is ready to be handed off to testing, to good techniques for categorizing trace levels in your code. There isn't a single point on his list that I don't agree with. Some I have a stronger propensity to than others. For instance, "Continuous Integration" is deal breaker for me. If there's no CI for it, I won't work on it. Others, such as "Buy, not Build" do not evoke such a strong reaction out of me, but I do still believe that they have their place in this list.
There are a couple of things that are missing from Patrick's list though. Here's what I would add:
- Build for Maintenance
- All code should be built with the maintenance team in mind. If you can't adequately argue that you'd be able to understand it in 3 weeks time, you need to rework it so you would.
- Pragmatic and appropriate verbosity in naming will always make the situation more understandable for the maintenance team
- You are the maintenance team. Immediately after you write a line of code, you are in maintenance mode. Don't write it if you don't want to have to fix it.
- All code design should be done with the Single Responsibility Principle in mind.
- SRP will make achieving 90% code coverage much easier and more attainable.
- Do not write code to accommodate possible future changes. Write code that adheres to SRP, code to the interface and have good test coverage. Those three things will make your code easily accommodate future changes.
- Coding to Interfaces
- Always code to interfaces
- Interfaces hide the actual implementation from the consumer of the code. This goes a long way to allowing for fast changes to your code base.
- Fail fast
- Provide your developers with the ability to run the application's test suite quickly and easily on their local machines. The faster that these run, the more that developers will run them. The more that developers run the tests, the faster they will know about breaking changes.
- Stabilize developer tasks while they are working on them
- Change is inevitable. In some situations change is a daily fact of life. Be open to allowing the customer to change their mind.
- Don't be feeding developers constantly changing specifications while they are working on writing code. Hold the changes back until the developer has had time to stabilize their code, then feed them to him/her. They will be more productive this way.
- Be pragmatic when holding changes back from developers. If the change request is very large or very intrusive you may get more benefit from stopping the developer before they get to far.
Are there any other things that you'd add to this list?
I've recently been thinking a lot about the deliverables that are required for software projects. Amazingly there are projects out there that are running with out any concept of what there deliverables are. Yeah, we all know that we're supposed to be delivering some sort of software, but beyond that what is it that your project needs to deliver to the client?
I would suggest that the non-software deliverables will vary depending on your client's bureaucratic needs, their support mechanisms, legislation adherence, who the final audience is and any number of other factors. If you're delivering an internal facing software service, you probably need good API documentation for the other developers who will end up being your users. Contrast that with a situation where you're building software for a government regulated industry. I haven't had the opportunity to work in that situation, but I'm sure there would be a lot of paper deliverables and they'd probably range from screen designs to algorithm documentation.
Most of us assume that it's easy to determine the deliverables that we have. As developers we instinctively say things like "The code is the documentation" or "There are comments in the code that explain it". While these can be true, it is so only for a select audience. What of the people, oh, let's say the business case owners, who don't have Visual Studio or Eclipse on their computers? Without being able to view the code (not to mention that they probably would be drowning in the syntax and design) how are they to get the information that we developers so meticulously insert in? From a developer's perspective it's easy. Because we can, we just go look at the code. The Code is the perfect deliverable for us.
The thing is, the code isn't a deliverable for the business user. A working application is, but raw code is not useful to them at all. They need something that is created with them as the primary audience. They need something that they can easily translate into their own terms, if it isn't in their terms already. For them you may end up creating use cases, system flow diagrams and specification documents. People working the support desk may require a completely different deliverable that the business user. The folks in charge of the emergency restore plan will definitely need a different set of information.
There is a catch here though. These people will never come to you and ask for these documents. Most of the time they don't even know that your project exists. To be a conscientious professional you have have to go out of your way to get the attention of these people. If you don't ask, you'll never know if something more than the working application is required. Most of the time you will find that something more is needed. Rarely will you find that nothing but the application is included on the deliverable list.
The kicker for me is the fact that some shops are caught up in the mentality that creating documents will solve all the future problems. You have to strike a balance. If you're building software for a client and they say that they want the application, plus specs, plus disaster recovery, what makes it okay for you to create API documentation and charge them for it? You are, after all, only supposed to be delivering three things. Arbitrarily adding on other items to the deliverable list, and ultimately passing on the cost of doing so, is not a good way to treat your client.
Another thing to think about is why you're creating any deliverable. Sometimes the client may think it's needed, but when you sit and look at it you can see that the deliverable is never going to be looked at after it is handed over. In that case you also have the responsibility to point this out to the client and ensure that their money is being used to create new business functionality in the application or documentation that actually is useful.
Personally, I lean heavily on YAGNI (You Ain't Gonna Need It) when it comes to this stuff. I've spent too many long days working on the latest version of some model or diagram only to see it float off into oblivion, never to be seen again. It's frustrating, demoralizing and a complete waste of money that could be spent delivering actual business value. For me it's like writing code. If it's not being asked for now, and there's no immediate need for it, don't code it. Only do what you need to when you need to. Now, that said, some deliverables are really bloody hard to create after the fact. Keep that in mind too.
This week I have the enjoyable experience of bringing 3 new developers onto our project. Most of you that know me probably read that last sentence with a sarcastic tone on the word enjoyable. You, my friends, would be wrong. Of all the ridiculous things that I do at work right now, training and molding new programmers is by far the most enjoyable. It's sad that I don't have more concrete work to train them with, but I have to deal with what I have.
Because I have little, if any, work most days to give to my development team, figuring out how I was going to train newbies was a daunting task. There's the standard "Here, take this document and read it. I'll be back to see you in two days." approach, which I've had to implement to a certain extent. There's also the "Welcome to the company. We have two weeks of class room training prepared for you." approach as well. I decided to try to fall somewhere in between.
What I've done is given the new guys (sorry ladies, nobody from the fairer sex is in this group of recruits) a small set of readings for them to stay busy with. I expected them to read it during the times that I didn't have other stuff organized (or spontaneously created) for them. This leads me to the "other stuff" I was trying to be prepared to give them. The truth is, my preparation skills were non-existent last week, so Monday when the newbies arrived, I had nothing. That's not 100% true. I had run a few things past some people, but I hadn't taken those ideas and formulated a plan.
For the past few days I've been winging it. What I've tried to do is intersperse a number of different experiences with the reading. I've pulled all of them into a session where we talked about the overall architecture of our application. We've spent time discussing the tools that we have, both home grown and otherwise. I've tried to pull each of them off into a design session so that they can see how I'm approaching the decisions and requests that I'm putting forward to the developers. Lastly, I've started to set them up with full days of pair-programming some of the existing team.
The pair-programming is an interesting experiment both for me and the company. Normally, new hires work through one or two defects with an entrenched (yes, at times it is like a war) developer and then they're sent off on their own to work through the minefield that is our code base. This is how I was introduced to the application and project, and, frankly, it didn't help me at all. If it weren't for the fact we have a slack schedule right now, I think that I wouldn't have been given the leeway to push forward with this approach. Because of the schedule slack I'm able to work the pair-programming angle for as long as I can.
So, I'm wondering two things. First, for the couple of the newbies that may actually read this between Ayende's 55 posts a week, has this approach been beneficial? Second, how are the rest of you assimilating new developers into your teams?
I had a discussion with a management type the other day about implementing the concept of release and internal iterations. Currently that project has extremely long iterations (6 weeks or more in length) which always are released to the client for testing. As a result of this, the feedback cycle from testing is very slow. The client isn't getting the software into their hands, and then not getting their concerns raised until longer after that point, that there can be a gap of 4 months between initial development and defects being raised and fixed.
In an attempt to shorten that feedback cycle, I made my suggestion of implementing shorter, internal iterations that fell within one larger duration (and feature list) iteration. Here's how I saw it working. If the project had a release iteration planned with a duration of 6 weeks and known set of features, the development team would split that release iteration into a set of smaller internal iterations (say 3, each being 2 weeks in length). At the end of each of those internal iterations, the development team would be responsible for providing a demo of that 2 week iterations features to the client. The demo would allow for high level feedback on things like UI design, workflow and domain concepts, but it would not allow the client to get into the meat of the features. In my mind, the purpose of the internal iterations wasn't to elicit full feedback, user acceptance testing or full feature verification. Instead I was suggesting that this project take steps to increase their ability to readjust the direction that their development effort was heading.
In my mind the benefit of iteration based development is the feedback and directional guidance that the client provides sooner, rather than later. I liken it to the small steering corrections that pilots make when the plane is hurtling down the runway on takeoff or landing. It's much more comfortable having those little left and right corrections and sways in your seat (I say this now sitting on my balcony...it would be quite different if you asked me during takeoff) than it is to have one hard turn once the plane was up to speed. If your iterations are the length of the runway, you're going to have to make a bigger and less comfortable change when you get to the end of it. I think that internal iterations are one of the best ways to avoid that shocking change.
Unfortunately, my suggestion of internal iterations was misinterpreted as "release to the testers and clients every time there is a feature completed or a defect fixed". Just another battle to be fought in the war on BDUF I guess.