|
LATEST POSTS
Monday, October 27, 2008
I'm in the early stages of a new project with the dashing and debonair Brian Donahue. On the plus side, despite his misgivings, the codebase is in pretty phenomenal shape all things considered. SVN repository, automated build and tests, ActiveRecord, views reasonably separated into MVP. Even a half-finished CI process which is impressive for a one-man team. Like any codebase, it has its share of issues but all in all, I won't be using this as a sample app for a brownfield application. On the minus side, he reads my blog so I'll have to be more subtle in the digs I make toward my workplace. Anyway, one of the first things I like to do when I start looking through a steaming pile of excrement that someone calls "codebase" is check out the warnings that are lingering. The code had its share with the vast majority related to an upgrade to the latest version of Rhino Mocks but without changing CreateMock. This was an easy fix as a global search and replace from CreateMock to StrictMock got rid of over 80% of the errors. The rest were a flurry of ReSharper refactorings until I got to the final four. Four assemblies reported the error: found conflicts between different versions of the same dependent assembly. Double-clicking this error gives a helpful message offering to add a binding section to the assemblies app.config file. I say helpful seriously there because, while I had no intention of keeping that section in the app.config, at least it was able to tell me what the error message couldn't. Namely, which assembly was causing conflicts. Or so I thought. The new app.config section seemed to indicate that there were NHibernate conflicts among various projects when I knew for a fact that we had exactly one copy of the NHibernate dll in the entire project. Here's where Reflector comes in. More specifically, here's where it's extensibility comes in. Through the use of the Assembly Graph add-in, I was able to generate a picture of the dependencies. (Click on the image to the right for a bigger version.) As you can see, all referenes to NHibernate are going to the same assembly. But as you can also see, there are three semi-related assemblies that aren't being referenced at all. Which means they can safely be removed from the various projects, yesno? You probably think that's foreshadowing's cooler cousin, foreboding, but it's not. The answer is yes, I was able to remove them with no ill effects. The reason I know there are no ill effects? Unit tests, baby! None o' this "let's take a stroll through the application and see if it still works" nonsense for me*. Remove the reference, run through the build process and watch the magic happen. The reason this is important: I'm pretty sure this add-in doesn't account for dynamically loaded assemblies. And while I'm also pretty sure we would have no reason to dynamically load some peripheral NHibernate assemblies, it's nice to have a suite of unit tests backing up that assertion. So to re-cap: - Unit tests good
- Automated builds good
- Reflector good
- Assembly Graph add-in good
- Subversion good (I haven't provided explicit evidence of this here but it's worth mentioning.)
Kyle the Reflectively Assembled *Brian, if you're reading, I'm lying. I did actually go through each section and make sure it's working. But back me up if anyone asks.
Monday, October 20, 2008
I'm preparing my presentations for DevTeach and have come to realize that there is a price to pay for creativity. Here are the abstracts for three of my presentations. Guerrilla Refactoring Greetings, comrades. Welcome to the resistance! Our quarry today is a shamefully designed application that grows fat with duplication and crusty with hard-codedness. It feeds on itself behind a shield of corporate deadlines, each one stricter than the last. The cowardly code mocks us with cries of "We don't have time! We don't have time!" while features are grafted onto the application haphazardly with no thought to future reform! But fear not! We have studied our enemy and have altered our attack plan accordingly. No more frontal assaults. We must liberate the code in focused skirmishes from its bourgeois oppressors! Patiently, we shall advance, tightening our grip in an ever-widening net of unit tests as we hunt down bugs like the dogs they are! So join me, brethren and sistren! With our allies, the Design Pattern Legionnaires and the Dependency Liberation Front, we will train you to take your rightful place in the movement toward a better world, where features are not divided into tasks that are meted out to the "database gal" and the "guy that does the UI because he has PhotoShop installed". Rather, they will be fully and utterly DEMOLISHED by fully armed, multi-functional, and domain-inspired programmers full of KNOWLEDGE AND FURY!!!1!!! Viva La Revolucion! (adapted, of course, from my original post on the subject) Implementing a Brownfield Ecosystem: A Cultural Extravaganza So you missed Folklorama again, eh? Of course, you did. It's in Winnipeg. Well, fear not, coders! In this session, we'll throw so much culture at you, you'll think you're back in high school biology. A very important aspect of Brownfield applications is shifting the culture of your team. This starts with your project's ecosystem. Many developers in Brownfield applications don't even realize how many hoops they jump through during the course of a day to do simple things like checking in code and building the application. In this session, we'll implement a full-fledged ecosystem for a Brownfield application. Working from the perspective of a single developer in a team, we'll cover topics such as the structure of your version control system, your check-in process, automated builds, and continuous integration. In the process, we'll talk about common pain points and common areas of friction that we can overcome with a few simple tool choices and a couple of mindset tweaks. I'll be getting by with a little help from my friends as we simulate a team environment using well-placed and impeccably groomed plants in the audience who will act as other developers in the team, some working with me, others not so much. Adding automated tests to an existing codebase It may seem like heresy but there are actual real-live applications out there in the world that don't have unit tests! No, really! And I know it sounds crazy, but you could be brought on to one of these applications and be tasked with adding automated testing to them. Rare as these circumstances may be, it'll help to be prepared for them. Because it won't be as fun as you are probably imagining right now. For example, how do you automate a test for a web form that connects to a database, displays a form, then posts that data back to the database? In this session, we'll look at techniques for integrating tests into an existing codebase that has never had them before. When do you write tests for existing code? How do you test a mammoth method/class? How do you know if you aren't breaking anything else? For answers to all these questions and more, read Michael Feathers' Working Effectively with Legacy Code attend this session.
You see my dilemma. I wrote these in a fit of imagination without stopping to wonder how I would differentiate one from the other. For example, how do I talk about refactoring without mentioning automated tests? How do I implement a brownfield ecosystem without doing same? In the end, I believe there will be overlap among the presentations. Indeed, I will probably use the same sample application for all three. I've justified it in my head by saying that the overlap is probably a good thing to help people see the interaction 'twixt the various concepts. Plus, it means I can focus on a single element in, say, the refactoring presentation and leave some of the details to the automated tests presentation. In any case, here is some clarification on the goal of each presentation: Guerrilla Refactoring: How can you refactor an application for maintainability when there is no explicit buy-in from the PM and/or the business (and/or the rest of the development team)? Implementing a Brownfield Ecosystem: A walk-through on adding source control, CI, and automated testing to an existing application. I'm planning to use plants in the audience to simulate a team environment to demonstrate what happens to you personally when others don't play by the rules. The "cultural" part comes because this is very much an exercise in changing your team's development culture. It was originally intended as a practical follow-up to Donald's Parachuting into a Brownfield Application presentation but I notice he's not doing it this time around. Adding automated tests to an existing codebase: Here, we'll dive deeper into automated testing for an existing app. It will be sort of a continuation of the brownfield presentation which will add the testing framework but not go any further. Admittedly, it will borrow heavily from Feathers' book but I see that as a good thing. For completeness, the fourth session I'm doing is on TDD for MVC applications. This one is more disparate than the others and should be a fun one as well, even if the abstract for it is the most boring of the four. Kyle the Synergistic
Saturday, October 18, 2008
A couple of things have got protectionism on my mind. It comes up surprisingly often because the Bahamas seems to be, by and large, a protectionism nation. That is based solely on personal observation, not on any sort of fact-checking. So I'll assume everyone out there knows the difference between valid journalism and wild blog-induced accusations based on rumours. Protectionism is the restriction of trade and industries by imposing regulations and tariffs to protect local companies and local interests. A few industries are already protected here. Lawyers, for example, must be Bahamian as do real estate agents, I think. And rumour has it, the IT industry is under consideration for the same treatment. Some of this is understandable, given the country's small population, proximity to the US, and political history. And with the recent economic downturn, it gets even harder to discuss the issue without emotions running high. In any case, whether or not that's true is not something I can talk intelligently about. I am, after all, a foreigner here myself so I don't know that I could be an unbiased judge. I take some comfort in the fact that I am living and spending money here, but working for companies in the US and Canada. In any case, one of my goals with the BahaNET user group, which is my current outlet for organizing the software development industry here, is in direct response to this protectionist opinion and it applies anywhere, not just here. To wit: If you want to make sure your job doesn't go to anyone else (local or foreign**), then be better at it than anyone else. Don't give the company a reason to look elsewhere and they won't do it. This seems to be lost on many people. The natural inclination when someone else gets a job you were after (or that you had) is that they did something underhanded to get it. Instead of thinking, "Maybe I need to upgrade my skills," it's easier to assume that someone has ulterior motives and is working against you so that you can maintain the status quo. The decision to hire someone is usually pretty easy when comparing two people. The basic metric is: which one has more skill than the other? If the difference is obvious, then so is the decision. It's only when the candidates are relatively equal in skill level that other factors come into play. It's naive to assume this is always the case, of course. Some companies are more political than others. But it certainly tips the odds in your favour if you are good at what you do. That's why it's encouraging to see the same people coming out month after month to the BahaNET meetings to see what else is out there and to connect with other developers. Regardless of their actual skill level, it tells me that these people are willing to put some effort into making themselves better. So that when it comes to hiring them versus, say, a Canadian with similar skill level for which you'd need to buy an annual work permit, it's a no-brainer. ** Keep in mind that when I refer to a local or foreigner, I'm talking about status, not physical proximity. The "local vs. remote" thing is a whole different issue which I mention to pre-empt any accusations of hypocrisy based on previous posts on working remotely. Kyle the Unprotected
Monday, October 13, 2008
Have just started a new project and my first task is some Silverlight thingamajig that I'm sure I'll go on about ad nauseum in the coming weeks. But first, let's talk about some ReSharper settings. My very first check-in in the code base was a ReSharper code style settings fil e. This is a way of allowing everyone on the team uses the same settings. The documentation for this feature is here though it's a little out of date. To the right is a screenshot from version 4.1. This is somewhat important for me because I have some different ideas about whitespace than most people. And I don't want to impose my will on someone else. (At least not so crudely.) Nor do I want to alter my own personal projects just because everyone else likes to have all their code scrunched up together so that parentheses and curly braces essentially take the place of spaces and you need a &*%$ Little Orphan Annie Decoder Ring to parse out the actual meaning of these god-forsa--... Ummm...let's just say I'm a little set in my ways and move on... By default, your ReSharper settings are global across all projects. The two other settings are: a) Shared across the team, per solution, and b) Not shared, per solution, stored in a file. Both are very useful in teams where developers work on more than one project, such is the case here. The other obvious example is open-source projects. Here's a quick run-down of each. Shared across the team, per solution Here, the code style settings are stored in a .resharper file in the same folder as the .sln file. This is ideal for a non-intrusive way to enforce coding standards on a project. Developers download the source and go. They may not even know it's using a shared code style. MvcContrib uses this mechanism to enforce standards. I'm not on the new project because I've added .resharper files to my global SVN ignore list and I'm too lazy to change it. Plus, I'm not quite sure how it works between ReSharper 4.0 and ReSharper 4.1. I.e. is it able to manage users that use 4.0 and others that use 4.1? And what happens when one user changes the settings inadvertently? As an example, I just updated to the latest MvcContrib, opened it up, and now I have MvcContrib.4.1.resharper checked out for some reason. So instead, we're using the next option. Not shared, per solution, stored in a file With this option, you explicitly tell ReSharper where the settings are stored. It requires a little more work to set up. Unlike the previous option, the developer needs to go into the ReSharper settings and physically select this option and navigate to the file. It takes an absolute path, not a relative one. I'm guessing that this is because the settings to tell ReSharper which option to use are stored in the .resharper file, which as I've mentioned, we're not including in source control. Both options give you the ability to set standards like naming conventions, spacing, and, theoretically, how to re-order methods, fields, and properties within your class. I say theoretically because this particular one (under Type Members Layout) seems a little eccentric. I had to import the settings from the code style file, then shut down and restart the solution for them to take. And when I make changes to this section, they aren't always reflected in the settings file. None of this guarantees that your code will be consistent. After all, not everyone may have ReSharper. Also, I'm pretty sure the settings to auto-format are machine specific so someone could turn them off and then you have to rely on them to do an explicit auto-format before they check in. Furthermore, it appears that formatting profiles are also machine-specific, so even if you create one that runs through all your rules, re-orders things, and otherwise cleans up when you press Ctrl+Shift+Alt+F, that won't get propagated to anyone else's machine. Kyle the Styled
Thursday, October 02, 2008
I told a condensed version of this story on Twitter but it bears repeating in a more rambling format. We replaced the reverse osmosis system on our water at home today. Old unit worked well enough I think but was crazy noisy and it was always a crap shoot to be able to get someone out to do maintenance on it. The maintenance schedule itself was up for debate depending on who answered the phone at the place where it was originally purchased. We replaced it with a unit recommended to us by our plumber. I like our plumber a lot not because of his skill, of which I have no point of reference to judge, but because of his passion. The guy loves talking shop when he's onsite. Whether it's upping the water pressure in our faucets by removing the flow restrictors (I recommend it for showers, not so much for sinks) or rating the options for new fixtures on our bidet (I bet you think I'm kidding about that one), he always talks with an enthusiasm that's infectious. Which is why I use him. So he shows up today and is busting at the seams with excitement, waiting to show me how the system works. As soon as he stepped in the door, he started opening the box like a kid at Christmas. And I should point out that this is not a small man. He's at least 6'4" and, shall we say, "sturdy". At this point, his eyes gleaming, he goes into the features and how it works and whatnot. He starts talking about intake valves and de-ionization filters and membranes and sediment and parts per thingy and pressure whatsits and quarter-inch flibberygibbits. All with as much crazed energy as you can stuff into a 6'4" plumber. As my eyes glazed over, it occurred to me: Is this what I sound like to users? Energy, enthusiasm, and passion are awesome pre-requisites, but let's not forget that we still have to talk to people. As easy as it is to dump "Excellent communication skillz" on your résumé, it pays off in dividends if you actually mean it. I'm not exactly an expert at communication. But I'm anal enough about it that my daughter is going to hate me when she hits high school English class. And I do lament the gradual laxing of rules with the proliferation of IM and Twitter. I like the power communication has. I love the way you can change perceptions by wording something differently. In my experience, choosing appropriate language is almost as much a predictor of success as the actual code. That's in your written documentation, your formal presentations, and in our everyday interaction with users *and* developers alike. To tie this back to my plumber, when he was done his verbal throughput on all things RO, I just looked at him like a good user and said: Whatever, man, just make it work. Kyle the Reversed
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent
my employer's view in any way.
Copyright © 2010 Kyle Baley. All rights reserved.
|
|
|
CATEGORIES
|
|
LATEST POSTS
POPULAR POSTS
|
|
ARCHIVE
| March, 2010 (1) |
| February, 2010 (8) |
| January, 2010 (2) |
| December, 2009 (3) |
| November, 2009 (2) |
| September, 2009 (5) |
| August, 2009 (4) |
| July, 2009 (2) |
| June, 2009 (5) |
| May, 2009 (6) |
| April, 2009 (5) |
| March, 2009 (6) |
| February, 2009 (2) |
| January, 2009 (6) |
| December, 2008 (5) |
| November, 2008 (2) |
| October, 2008 (5) |
| September, 2008 (9) |
| August, 2008 (5) |
| July, 2008 (7) |
| June, 2008 (6) |
| May, 2008 (11) |
| April, 2008 (13) |
| March, 2008 (13) |
| February, 2008 (12) |
| January, 2008 (19) |
| December, 2007 (16) |
| November, 2007 (8) |
| October, 2007 (23) |
| September, 2007 (15) |
| August, 2007 (8) |
| July, 2007 (6) |
| June, 2007 (11) |
| May, 2007 (19) |
| April, 2007 (14) |
| March, 2007 (3) |
| February, 2007 (4) |
| January, 2007 (7) |
| December, 2006 (5) |
| November, 2006 (9) |
| October, 2006 (11) |
| September, 2006 (14) |
| August, 2006 (11) |
| July, 2006 (15) |
| June, 2006 (8) |
| May, 2006 (10) |
| April, 2006 (12) |
| March, 2006 (3) |
| February, 2006 (7) |
|
|
|