www.codinghillbilly.com   kyle.baley.org  Subscribe / Contact
 
 
 
 
LATEST POSTS
Saturday, August 29, 2009

Another in the series of “reviewer feedback I’m going to deal with using dicey justification techniques” for Brownfield Application Development. This time, there were concerns that the topics covered in the book don’t go in-depth enough. One reviewer said he or she would need to reference other works in order to learn more.

My justification for that: Good!

We cover a lot of topics in the book. Automated testing, continuous integration, dependency injection, object/relational mappers. Given the scope that we chose, we can’t get in depth. That’s the choice we made when outlining said scope. But if all we’ve done is piqued someone’s interest enough to seek out more information elsewhere, I’ll consider that a success.

That said, clearly we need to set expectations for the reader. One of the underlying themes of the book is to foster a sense of curiosity and, more importantly, a sense of pride in one’s work. To make the reader aware of potential new things and encourage them to delve deeper. In short, to start the journey, not to end it. This is where careful wording at the beginning will improve things, I think.

Next up, why we’re not going to take out the alcohol-fueled rants on datasets.

Kyle the Justified

Friday, August 14, 2009

At the beginning of the project I’m on, I made a humbling mistake. There were two others on the team, an employee and another contractor. The mandate the other contractor and I were given was to introduce some new techniques to the employees which is all hunky-dory.

The other contractor is a young’un, over ten years my junior. I had interviewed him for another position in the company some months earlier and to his benefit, we didn’t take him on for that one. He’s a developer at heart, it would have been his first contract, and it was for a Livelink position. My rationale was that he’d have left within three months. But when I joined the new project, I was glad to hear they picked him up for it. During the interview, he said all the right things: read blogs, interested in continuous improvement, always honing his craft, etc, etc.

In short, someone with the right attitude but perhaps short on experience. Someone I could mold into a veritable hillbilly powerhouse!

(Now there are a couple of ways this story can end with this set up. First: I take him under my wing, put him on the path of righteousness, and unleash him on the world to make it a better place. That’s boring and I wouldn’t blog it. The more entertaining way is that he turns out to be a fraud and that it was actually his evil twin brother we interviewed. I’ll disappoint and say that that didn’t happen either.)

So my mindset going in was as the wizened old sagacious consultant descended from upon high to bestow his wisdom on the team. After all, the kid was barely out of diapers. He needed direction. DIRECTION, I TELL YOU!!!

I’ll paraphrase one of our early conversations:

Coding Hillbilly (preparing for a long drawn-out follow-up explanation): Let’s make sure we keep our integration tests separate from our unit tests
Assumed greenhorn: Yeah, I’m down with that fo shizzle. I don’t want to be slowing ourselves down waiting for those suckerz to runz, yo!
Coding Hillbilly: Because they take longer to r—…umm…I mean. Yeah.

Later conversations touched on testing techniques, CI product comparisons, composition vs. inheritance, and dependency injection. In a great many of them, he would disagree with me. But what I wasn’t prepared for is that in almost every case, he disagreed with me for valid and well-thought-out reasons. To the point where my argument degenerated to “oh yeah! Well you’re ugly!” And I even lost that argument because I later discovered he’s done work as a model. One argument we had was doomed from the start when I said, “why are you bothering to test on Firefox when the company has standardized on IE6?”

What made all these discussions even more humiliating is that he never shoved his superior knowledge in my face. He was always civil and respectful. But he uses an even worse tactic when I say something clearly wrong: He would always reply with “I see”, then go silent. Allowing me to ruminate on why, in the name of all that is hillbilly, I would claim that it was better to use an <asp:repeater> instead of a <%foreach%>.

This was early in the project, when I was blinded by the “knowledge” that, as the senior developer, whatever I said was always right. Before the kid started, it was clear to me that there was a lot of work to be done training the rest of the team and I was content to take things slowly and use the first project just to get the lay of the land. Then Sundance rolls into town and we’ve now integrated jQuery into the mix, introduced Moq for testing, and refactored our data access layer to use a truer definition of repository. And while not all of this is completely his doing, his perseverance has been a strong contributing factor.

Expectations have since been reset on both sides. Rather than the mentoring relationship I had expected (and tried to push), it is more of a peer relationship now. And in the name of continuous improvement, I’ve learned that you never stop learning. From anyone.

Kyle the Stagnant

Friday, August 07, 2009

A common piece of feedback we got for early reviews of Brownfield Application Development is that the automated testing chapter should come before the automated build/continuous integration chapter. This was an awesome bit of feedback mostly because we could ignore it and instead get some air time on my blog on why we're doing it this way.

When I come into a project, my most immediate goal is usually to get it into a continuous integration environment as soon as possible. And the bare minimum for that is to get the source code and compile it. If there are tests and they pass, that's an added bonus. I'll add them to the CI process afterward.

For me, it comes down to treating your environment just as incrementally as your code. I want my CI environment up and running now. Maybe the tests pass, maybe they don't. If I dump them in there now, that adds a variable into the mix I don't want to deal with at the moment.

There's some element of personal preference, I suppose. But it's also borne from experience. At one time, I had some minor frustration trying to do everything in the automated build before dumping it on the CI server and having it fail. Just like we check in smaller bits of code more often, I like to enhance my CI process in small chunks more often.

Incidentally, CI is why we cover version control first. Not because we think you don't know anything about version control, but so that you can get your source repository prepared for continuous integration. Any hack can dump code into SVN. The important thing is whether you can get it back in an immediately useful state. Continuous integration can help determine if it's immediately useful.

Alas, the rest of the feedback for the book was not so easily dismissed. Damn you people and your "values".

Kyle the Edited

Wednesday, August 05, 2009

Code challenge time! And by code challenge, I mean, "Do my work for me so I don't have to think/Google".

We have a parent object, called Parent, and each one has a collection of child objects, called AllegedChild. Ignore potential cycles for this exercise. The database has a single table with fields: ParentID, ParentName, ChildID, ChildName. The data is such:

1, Coding Hillbilly, 1, Brandi-Lynn
1, Coding Hillbilly, 2, Sammy-Jo
1, Coding Hillbilly, 3, Sammy-Jo Jr.
1, Coding Hillbilly, 4, Sammy-Jo Sr.
2, Donald Belcham, 5, Justice Gray
2, Donald Belcham, 5, Dave Laribee
2, Donald Belcham, 5, Scott

We will retrieve this list into a collection of ParentChildDto objects with properties that mirror the database. From this list, we'd like to create a new list of Parent objects each with an appropriate list of AllegedChild objects.

The challenge, given a List<ParentChildDto>, what is a clean and efficient way of creating a List<Parent>? The current implementation looks something like this:

private List<Parent> GitEm( IEnumerable<ParentChildDto> flatList )
{
rFrom = from p in flatList
orderby p.ParentId
select p;

ParentChildDto prev = null;
var to = new List<Parent>( );
foreach( var dto in rFrom )
{
if(prev == null || prev.ParentId != dto.ParentId)
{
prev = new Parent
{
Id = dto.ParentId,
FullName = dto.Name
};
to.Add(prev);
prev.AllegedChildren = new List<AllegedChild>();
}
if(dto.ChildId != null)
prev.AllegedChildren.Add(new AllegedChild
{
Id = dto.ChildId,
FullName = dto.Name
});
}
return to;
}

While this works, it looks a little too old-school what with the funky indentation and the use of a "previous" placeholder. But try as I might, I can't think of another solution that would be cleaner or more maintainable. There's a chance I may be too "close" to the problem though.

Honorary Hillbilly Status awaits the person who provides an answer deemed worthy of the domain upon which this example is based. Answers must assume a cordial tone and work within the context outlined. Ones that do not (hint: These will be the answers that take the form "Why are you doing XXXX in the first place?" or one of its variations) will be summarily dismissed.

Kyle the Advancefully Grateful

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
.NET General (18) alt.net (4) altnetconf (9) ASP.NET AJAX (40) ASP.NET MVC (29) Bahamas (1) Bahanet (9) BDD (1) Brownfield (18) Career (9) Castle (1) Code coverage (1) Coding Style (6) Communication (1) Community (18) Conscientious Coding (34) Continuous Integration (11) dasBlog (12) Development (16) DevTeach (4) Domain (2) Environment (4) Estimating (1) Featured (14) Flamingo (10) Games (1) Google App Engine (2) GWT (5) Hardware (6) Java (1) Javascript (7) Linq (2) Livelink (6) Lucene.NET (2) MbUnit (1) Metrics (1) Miscellaneous (24) Mocking (4) NAnt (4) NHibernate (12) NInject (1) Office (3) Office Development (6) Open Rasta (1) Patterns (5) Presenting (13) Professional Development (15) Refactoring (10) ReSharper (11) REST (2) S#arp Architecture (5) Security (3) Software (11) Sundry (18) TDD (19) Tools (21) User Interface (5) Utilities (8) Visual Studio (8) VSTO (1) Web development (12) Windows (3) Working Remotely (16) Workplace (3) Writing (4)
 
LATEST POSTS
 
POPULAR POSTS
 
 
ARCHIVE