So tonight I got to help demo what a fishbowl was at the ALT.NET Canada (thanks Doc!) conference and the topic of discussion was on the Fundamentals of Software development. During the session I started to realize that what I considered to be fundamental seemed to be far from what others did. After a few discussions I started to think that the fundamentals were different based on generational divides.
I'm speaking for myself, but hopefully for my generation, but when I hear "The Fundamentals of .NET development" I think, Object Oriented Programming, Design Patterns, a knowledge of the syntax of a language, and at least a base understanding of what the CLR is and what it provides for us.
Some other takes on fundamentals were focused on understanding how the underlying operating system works, Algorithms and Data Structures.
This got me a little depressed because I don't have an intimate knowledge of how the underlying operating system works, or how to perform a deletion from a red-black tree, or how to implement a half decent hashing algorithm. Ask me to build an AVL tree and I might puke, or at least ask "why? it's 2008" I have a base understanding, but I'm not sure if that counts as the required fundamental knowledge to build a decent app.
When I was writing C, I cared a lot about writing well optimized code. I cared about memory allocation/de-allocation. I cared about protecting from buffer overruns. I cared about so many things, that I just don't think about, as much, now as a .NET developer. All the things I don't have to be concerned about allows me to focus on other things that I want to care about.
It seems like we developers are proud of being an expert at something, but when that something becomes less and less relevant in building applications today, we tag it as "fundamental". Perhaps in 10 years or so the next generation will wonder why they would need to understand object oriented programming to build valuable applications. After all it will all be written in DSL's, right?
Couple of more pennies for ya!
First off I want to make it clear that I'm not a guru on the topic, but I do find it interesting. The topic of course is Context Based Specifications. I've seen an emergence in interest in writing context based specifications lately on the blogosphere. However, everyone seems to be advertising it slightly differently...
One of the things that our team tries to aim for is to keep technical language out of our specifications. They should be human readable sentences, not "Yoda" speak. This is crucial if we want non technical people to actually read our specs to make sure the code is inline with what the business is attempting to do. The goal, in our humble opinions, is to work closer towards the ubiquitous language. The benefit is that documentation is updated along with the code, because it is the code.
Something that reads..
Doesn't read as easy as:
Another subtle change that our team made was to put the specs above establishing the context. In some cases it just seem to read better from top to bottom.
"It" being the system under test.
We don't always get it right, but by trying to drop the technical language we force ourselves to step away and think about the problem that we are ultimately trying to address.
Again... this is just
my our 2 cents.
So this week we got to start working a brand spanking new MVC project.
So far we're leveraging Castle Windsor, NHibernate, Fluent Nhibernate, and kind of running Linq to NHibernate.
It's amazing how quickly you can get a project up and running in such a short amount of time.
(BTW, Fluent NHibernate rocks!)
When you're building off the trunk of these projects, it's almost like the contributors to all these great projects are extended members of the team.
Thank you all!
Moving on... One of the things that are cool, but also slightly annoying,
is how the MVC framework parses out items from the http payload to populate any input arguments on controller actions.
It's great how it just works, but it's a little annoying if it's under test and you have to add more fields, or remove fields from a form, then you have to go update the signature of the action then go update the test.... yada yada The changes just ripple down...
So one thing we tried out this week was to create a payload parser. What this guy does is take a
DTO parse out the values for each of the properties on the DTO from the current requests payload and fill it. This makes it easy to package up the form parameters in a nicely packaged DTO and fire it off down to a service layer to do some work.
So instead of declaring an action method on a controller that looks like this, where the signature would have to change based on what fields are submitted on a form:
We can write this...
This better allows us to adhere to the OCP. If we need to include additional fields on the form, we can add them to the form as long as the control name is the same as the name of the property on the DTO that it will be bound to. The implementation of the payload parser is quite primitive for now, but at the moment it's all that we needed.
First up the specs... simple enough, for now!
The current implementation:
I finished reading...
What an excellent book, seriously! It was written by Robert C. Martin and his son Micah. The following is a list of excerpts from the book that I can appreciate:
"Continuous attention to technical excellence and good design enhances agility. High quality is the key to high speed. The way to go fast is to keep the software as clean and robust as possible. Thus, all agile team members are committed to producing only the highest quality code they can. They do not make messes and then tell themselves that they'll clean up when they have more time. They clean any messes as they are made."
"The goal of refactoring, as depicted in this chapter, is to clean your code every day, every hour and every minute. We don't want the mess to build. We don't want to have to chisel and scrub the encrusted bits that accumulate over time. We want to be able to extend and modify our systems with a minimum of effort. The most important enabler of that ability is the cleanliness of code."
"Specifying contracts in unit tests. Contracts can also be specified by writing unit tests. By thoroughly testing the behavior of a class, the unit tests make the behavior of the class clear. Authors of client code will want to review the unit tests in order to know what to reasonably assume about the classes they are using."
"Databases are implementation details! Consideration of the database should be deferred as long as possible. Far too many applications were designed with the database in mind from the beginning and so are inextricably tied to those databases. Remember the definition of abstraction: "the amplification of the essential and the elimination of the irrelevant." At this stage of the project, the database is irrelevant; it is merely a technique used for storing and accessing data, nothing more."
"This style of testing is called behavior-driven development. The idea is that you should not think of tests as tests, where you make assertions about state and results. Instead, you should think of tests as specifications of behavior, in which you describe how the code is supposed to behave."
A few weeks ago I started feeling a little over whelmed by the volume of interest in what I was up to. After reading a chapter from Tim Ferris' book, I decided to disconnect. It was the most effective advice I could have ever received. I went cold turkey. I turned off my phone and put it in a drawer. I completely stopped checking my email, and wouldn't allow myself to "surf" the net.
The result after a couple of weeks, I feel liberated... and refreshed!
The first couple of days were hard, I had the itch. I kept wondering... "what if an emergency happens and someone needs to get a hold of me?" There was no emergency, and the best part no shackles. When I finally checked my email, I spent 5 minutes scanning the email that seemed to contain "information" that was important to me. It was amazing how much "noise" I was able to filter out. This is something that Tim describes as a "Low Information Diet."
I'm toying with the idea of completely disconnecting my phone and I'm currently checking my email once a week (Mondays).
I looked back at a post that made remarkable difference to me when I first read it last year. It was JP's tips on becoming a more effective developer. In it he told us to limit the amount of instant messaging that we do during the day. Today I feel that instant messaging has been replaced by mailing lists, twitter, texting and RSS feeds. All of this can consume a good portion of your day, and for me causes me to lose focus, quickly. It's important to be selective about what information is important to keep you focused and to filter out what can wait.
I'm not saying this is for everyone, but the Low Information Diet is working for me, and my daughter is loving the extra focused attention she gets from her daddy (likewise for her daddy).
Mike left a comment on my last post on Windows Forms Databinding asking:
What do the tests look like?
On the ComboBox binding, why aren't you using adding the binding through DataBinding.Add? With the way you have it now if you change the value the combobox is bound too it doesn't get pushed back to the screen.
Well Mr. Mike, on the view implementation there were no tests... *hang my head in shame* Yup, we went at it trying to understand how Windows Forms Data bindings works, but if we had gone at it test first, we would have found that leveraging the built-in data bindings are not very testable. It requires having a BindingContext setup, and in some cases the controls have to actually be displayed for the bindings to actually kick in. Second, if we had gone test first, we would have noticed the issue the Mike brought up in regards to the ComboBox.
Feeling a little guilty about publishing code that wasn't well thought out, I decided to go at it again, with a test first approach. The test started off very high level. I knew the API that I wanted to work with, in this case a fluent interface for defining a binding to a control. The end result was quite different..
The end result doesn't leverage the Windows Forms databindings at all. It registers event handlers for events on the controls.
If you're interested in the rest of the source code download the source here. The moral of the story... Don't become complacent and take off your TDD hat, prematurely. In most cases it can, and should be, tested. Your design will probably come out much cleaner then going at the problem head on without tests to back you up. Not only that, but tests also give you extension points for making changes, and dealing with different contexts you probably wouldn't have thought of right off the bat.
A couple of weeks ago, Adam and I were pairing on a new screen in a windows forms application. He started showing me some stuff that he had learned about windows forms data bindings. I showed him a little bit of what JP tried to teach me, back in the Austin Nothin' But .NET boot camp, about Expressions and we decided to try a different way of binding domain object to screen elements in our application. The following is a method on the view that's invoked from a presenter. It's given an object from our model to display.
Each of our controls are prefixed with "ux". What we did was bind different types of controls to property's on the object to display. This immediately changed that state of the object as the user filled out information on the screen. The BindToPropery() method is given the property on the object to bind too. The following was the implementation we came up with.
The implementation of the BindToProperty method takes in an input argument of type Expression>. This allows us to inspect the expression to parse out the name of the property the binding is for. It's like treating code as data. The IControlBinder implements two interfaces. One that's issued to client components (IBinding) which restricts what they can do with the type. (see above in the Create class) The second interface exposes enough information for extension methods to pull from to build bindings for specific windows forms controls.
The BoundToControl overloads were put into extension methods, allowing others to create new implementations of bindings without having to modify the Control binder itself. The extension methods....
For completeness... the control bindings...
We found that using the fluent interface for creating bindings was pretty easy and made screen synchronization a breeze, however, our implementation wasn't the easiest thing to test. So far it's been good to us.
As a side note... go register for the Las Vegas course, it may cause you to love your job! Also, if you've already attended a boot camp, and you think you already know what the course is about, you have no idea, it keeps getting better and better.
When building up a tree view that represents the directory structure of a file system, like the windows explorer, my first reaction was to use recursion to traverse the file system and build up a tree. I quickly found that doing something like that is a time consuming process, and required some optimization.
I came up with what I like to call the recursive command. Each Tree Node item on a tree view is bound to a command to execute. The command looks like this...
When the command is executed, the command gets an opportunity to modify the state of the tree node that was clicked. In this case I wanted to lazy load the sub directories of a node that was clicked. The command implementation looks like this...
This command is executed each time the tree node that it is bound too is clicked, but will only build up the child tree node items once. Each of the child tree nodes are bound to a new instance of the same command. Hence, what I like to call the recursive command.
For more information on the command pattern check out WikiPedia's write up.
*Update 11:30 am MST, Friday, August. 01, 2008
After a little more inspection, I realized I was doing nothing more than just visiting each tree node item on the demand. Visitors are known to be great for recursive structures.... so ix-nay on the ecursive-ray ommand-kay.
The revised version:
Our team is comprised of 3 dedicated developers, 1 project manager, 1 super dedicated product owner and a trusty task board. Although, we're a small team we've been uber successful, and so far have been able to out perform the competition (in a surprisingly short amount of time).
One of those reasons is because of how "tight" (read:close) the team is. What I mean is that we're completely open with each other, which has allowed us to really gel as a team. We have our good days and bad days, but overall I feel like I can honestly depend on my team mates, and likewise.
We all make the same salary, and have the same amount of shares. There's no super heroes on our team. We all have strengths and our weaknesses, but there's no sense that any one of us feels like we are obligated to outperform one another. We're judged based on team performance rather than individual performance.
"The problem with reviews is that most reviews and raises are based on individual goals and achievements, but XP focuses on team performance. If a programmer spends half of his time pairing with others, how can you evaluate his individual performance? How much incentive does he have to help others if he will be evaluated on individual performance?" - Kent Beck from Extreme Programming Explained
Depending on the day, we each step up to lead the team. There's no water cooler discussions about why a member of the team makes x dollars, while I make x - 20K. We're either performing or not, and call each other out when we're not.
So far, this has helped our team gel. I'm curious to hear how about why you and your team are so "tight"?
So JP had to tag me... then the Los Techies crew had to invite me to join Los Techies. This sucks for someone who "claims" to be quite a private person. Thanks JP for putting me in the spotlight, and thanks to all the techies who thought I was fit to join. So here goes...
How old were you when you first started in programming?
I was in grade 11, so I guess that would have made me 15.
How did you get started in programming?
Hmm... Kind of by accident. I took a C++ course in high school as an option and I found that I actually liked it. I didn't actually think I was capable of becoming a software developer, but I knew I liked it.
What was your first programming language?
What was the first real program you wrote?
In college I signed up for a curriculum that focused more on electrical engineering than software development. However we got a little bit of exposure with different programming languages like assembler and C.
The first actual program that I finished was in my second year of college. We wrote a piece of voice recognition software using MatLab. It was actually a tonne of fun, because it required us to utilize what we had learned about digital signal processing as well as how to pick up a brand new language and learn how to get something compiling with it in a short bit of time. This was probably when I realized I liked staring at code more than I liked staring at circuit diagrams.
What languages have you used since you started programming?
Assembler, C, C++, C#, T-SQL, VB, VB.NET, MatLab. The languages I would say I'm ok in are C and C#.
What was your first professional programming gig?
Right after college I got scooped up by a company called DataShapers, where I got to work on a project called Incentus. It was a Gift Card, and Loyalty Management system. I was hired to build embedded gift card applications for different point of sale terminals.
I was quite fortunate that I got to work on such a sweet project right out of school. I was exposed to things like chip cards, 3DES encryption, SSL/TLS at a raw sockets level written in C. I was fortunate enough to be mentored by one of the best while I was there. Thanks Mr. Mark!
If you knew then what you know now, would you have started programming?
If there is one thing you learned along the way that you would tell new developers, what would it be?
Actually listen to your elders, and follow through with what they tell you. At the same time, question everything they tell you, and decide what's right for you.
"Listen to your elders, but question everything they tell you."
What's the most fun you've ever had programming?
The Nothin' But .NET boot camp (times 2)... seriously, it blows my mind!
Who am I calling out?
Adam Alinauskas (whenever he gets his blog back up)
So yesterday I had this idea on how to run a background thread using an interceptor, but first I needed to Grok how the castle interceptors worked. I quickly ran into a snag, it looked something like this:
The problem is that the latest version of Rhino.Mocks hasn't internalized the castle dependencies. So the compiler doesn't know whether I'm referring to Castle.Core.Interceptor.IInvocation from the Castle.Core.dll or Castle.Core.Interceptor.IInvocation from Rhino.Mocks.dll.
I'm not sure why this is, so I did a little digging. And found this post... In one of the last comments someone else had this same issue...
I'm not really sure what this meant, so I decided to pull the source from the trunk. In the Rhino.Mocks project there's a file called "ilmerge.exclude" and in it was the interface that I was having trouble resolving (IInvocation). I removed it from the file, and rebuilt a release version. Seems to be working now.... I'm still not sure why this change was made... which makes me feel a bit uneasy.
Try it at your own discretion.
In case you haven't you should read...
As a reminder, let's talk about a test smell described in the above mentioned book. It's called "Conditional Test Logic".
"Conditional Test Logic: A test contains code that may or may not be executed." xUnit Test Patterns
"A fully automated test is just code that verifies the behavior or other code. But if this code is complicated, how do we verify that it works properly?"
Warning bells should sound off in your head when you start to see looping or conditional constructs within a single unit test.
"Code that has only a single execution path always executes in exactly the same way. Code that has multiple execution paths presents much greater challenges and does not inspire as much confidence about its outcome."
For more information check this out...
Basically Ignore Logic... that could cause multiple execution paths within a single unit test.
So I got a phone call this morning that went something like this....
"Yo mO, what's happenin' homie?", voice on the phone.
"Ye'.... I'm just slingin some code wit my compadre, G. What's crackin'?", says mo!
"So word on the street is that you're slingin' some made Rhino Mocks 3 dot 5 ish? So lemme asks you, how do you bust out some event raisin' with the new ish?"
My response... "I gots no clue my man, no clue!"
After some quick digging here's what I found... (Please remember this is a contrived example!)
The old school way...
Here's the new way.. that I quickly Googled for...
So there you have it. Enjoy..
I found the usage on Ayende's wiki here. Also, I am not a Rhino.Mocks guru, nor do I want to be, and yes the phone conversation was not as interesting as was previously illustrated.
Building a splash screen. (err... not taking a bath)
So one requirement we had this week was to add a splash screen to the project we're working on. My knowledge of threading is weak, so bare with me. As our application started to grow, the start up times started to grow so a splash screen is supposed to be a queue to the user that yes the app is running.
This is what the end result ended up...
So what's happening is the Splash screen is loaded on a background thread, while the application start up continues on the main thread. When the application start up is finished, the background thread disposes of the command that it's executing. In this case it starts fading the splash screen away.
Here's the core interface that made this happen.
This is a pretty simple solution (IMHO). The actual splash screen is just a win form, that starts a timer and adjusts the opacity when it's asked to display, then fade away when it's asked to hide.
For starting and running a non-blocking background thread, we're using the BackgroundWorker class which takes care of thread synchronization. (This comes in handy for synchronizing UI elements)
Just so you get the rest of the code, here's the DisplaySplashScreenCommand, although I'm sure it was obvious.
Hope this helps anyone out there trying to implement a splash screen. PS. I can't stress the fact that my knowledge of Threading is limited, so if you know of a cleaner implementation... Please, please hook a brotha up!
The end result looks like...
Tonight I finished reading...
This was an amazing book, and definitely offers a great in depth look at the C# language. Most importantly it answered a lot of my questions about elements introduced in C# 3.0, and taught me things I didn't know about C# 1.0. If you're looking for information on the following items, then this book is definitely for you.
- Type Inferencing
Thanks JP for recommending this book!
Here are a few gems that I picked from this book.
"You rarely see an explicit call to Delegate.Combine in C# code - usually the + and += operators are used."
Static vs Dynamic Typing
"C# is statically typed: each variable is of a particular type, and that type is known at compile time. The alternate to static typing is dynamic typing, which can take a variety of guises. "
Explicit vs. Implicit Typing
"The distinction between explicit typing and implicit typing is only relevant in statically typed languages. With explicitly typing, the type of every variable must be explicitly stated in the declaration. Implicit typing allows the compiler to infer the type of the variable based on its use."
Covariant vs. Incovariant
Jon, the author, mentions a blog post by Anders Noras on Planning a fluent interface
Here's an example of a fluent interface for building menu's that I've been playing with.
"When it comes to getting the broad sweep of code, what is required is 'readability of results' - I want to know what the code does, but I don't care how it does it right now."
There's a lot of information on IQueryables, Expression Trees, and other goodness in this book. This is a great book and definitely worth reading, especially if you're as interested in the C# language as I am.
I mean Grokking Rhino Mocks. My usage of Rhino Mocks has changed quite a bit since I first started using it a year ago, as well as the way I write tests.
First it was like this:
Then it evolved to this...
Then for a short time I tried this...
Now I'm trying this...
Now I'm generating reports from my
tests specs using this. I wonder what's next...
Last week I finished reading...
I really enjoyed this book, it's definitely worth taking the time to sit down and read. I realized a lot about myself as I read it. Hopefully you will too! Here are a few excerpts from the book that had an impact on me.
"Management is a bottom line focus: How can I best accomplish certain things? Leadership deals with the top line: What are the things I want to accomplish?"
"... envision a group of producers cutting their way through the jungle with machetes. They're the producers, the problem solvers. They're cutting through the undergrowth, clearing it out.
The managers are behind them, sharpening their machetes, writing policy and procedure manuals, holding muscle development programs, bringing in improved technologies and setting up working schedules and compensation programs for machete wielders.
The leader is the one who climbs the tallest tree, surveys the entire situation, and yells, 'Wrong Jungle!'"
"Work Centeredness. Work-centered people may become 'workaholics,' driving themselves to produce at the sacrifice of health, relationships, and other important areas of their lives. Their fundamental identity comes from their work - 'I'm a doctor', 'I'm a writer', 'I'm an actor.'
Because their identity and sense of self-worth are wrapped up in their work, their security is vulnerable to anything that happens to prevent them from continuing in it. Their guidance is a function of the demands of the work. Their wisdom and power come in the limited areas of their work, rendering them ineffective in other areas of life."
"There are times when neither the teacher nor the student knows for sure what's going to happen. In the beginning, there's a safe environment that enables people to be really open and to learn and to listen to each other's ideas. Then comes brainstorming, where the spirit of evaluation is subordinated to the spirit of creativity, imagining, and intellectual networking. Then an absolutely unusual phenomenon begins to take place. The entire class is transformed with the excitement of a new thrust, a new idea, a new direction that's hard to define, yet it's almost palpable to the people involved."
"Suppose you were to come upon someone in the woods working feverishly to saw down a tree.
'What are you doing?' you ask.
'Can't you see?' comes the impatient reply. 'I'm sawing down this tree.'
'You look exhausted!' you exclaim. 'How long have you been at it?'
'Over five hours,' he returns, 'and I'm beat! This is hard work.'
'Well, why don't you take a break for a few minutes and sharpen that saw?' you inquire. 'I'm sure it would go a lot faster.'
'I don't have time to sharpen the saw,' then man says emphatically. 'I'm too busy sawing!'"
"Principles are natural laws that are external to us and that ultimately control the consequences of our actions. Values are internal and subjective and represent that which we feel strongest about in guiding our behavior."
I'm currently reading...
I came across a paragraph that stuck out for me, and just wanted to share it:
"If you don't let a teacher know at what level you are -- by asking a questions, or revealing your ignorance - you will not learn or grow. You cannot pretend for long, for you will eventually be found out. Admission of ignorance is often the first step in our education."
This was immediately followed by the next powerful statement.
"Thoreau taught, 'How can we remember our ignorance, which our growth requires, when we are using our knowledge all the time?'"
Note to self, "be more ignorant..." *giggle* Have a great day!
I just watched an video by the author Timothy Ferriss and thought wow! Maybe you will too...
An idea the team an I had today, was to build a more fluent interface for creating dynamic SQL queries. Here's what I mean:
It's the responsibility of the query object to prepare the command with the command parameter names and values, so in this test I'm just focused on the raw sql. One of the benefits of this API, is that it's strongly typed, so you can't stick a string in a column represented by a long.
For example, Imagine a customers table that looks like this:
Here's what we've got so far for contracts...
And here's as far as we got with the implementation...
The most important piece is still missing, and that's implementing the "And()" method on ChainedSelector... and finishing off the End method. I'm drawing a blank.. Thoughts are appreciated!
Oh man... oh man! JP's puttin' on a contest and givin' away free stuff... Lot's of it! *drool*
It's kind of a cool idea... The gist of it is to describe how YOU are contributing to the community, and how YOU are leaving an impact on those around you. It's all about YOU!
I can think of a few people that I have definitely left an impact on my life. If anyone's left an impact on you, why not nominate them!
The first place winner of the contest...
wins a seat at the Nothin' But .NET Boot Camp, held in Las Vegas! That's about $3000 bucks for that seat alone! Plus... they get a copy of Visual Studio 2008 Team Suite... Plus a full years subscription to an MSDN Premium subscription.
I have no idea what an MSDN Premium subscription is... so I Googled it, here's what I found:
"MSDN Subscriptions are the ultimate resource for professional Developers, teams and organizations..." - http://msdn.microsoft.com/en-us/subscriptions/aa718661.aspx
Oh man, oh man... not only do you get a first class ticket to one of the most fulfilling courses you'll ever take, but.... you also get the ultimate resource for professional developers. If that doesn't get you all the fame and glory you've ever wanted... I'm not sure what will!
The second place winner...
wins a stack of books, and tools and another copy of Visual Studio 2008 Team Suite with another fully year subscription to MSDN.
The books are wicked too, not to mention expensive! You get...
- The Pragmatic Programmer
- Code Complete
- Head First Design Patterns
- Design Patterns
- Test Driven Development
- CLR via C#
- Working Effectively with Legacy Code
- Domain Driven Design
- Agile, Principles, Patterns and Practices in C#.
I've read everyone of these books except for the last one. I can honestly say, I would read them over and over again. In fact, I am... and the tools.... oh man the tools... once you go ReSharper you'll never go back to naked studio, you just can't physically do it. It makes you physically ill... I puked once trying to do it... it was messy!
The third place winner...
wins a gift card from Amazon worth $140 bucks... That's quite a few books for a starving reader.
For more information go read up on the contest here...
How do you know if you really know someone?
I remember asking myself this question a lot as a kid. As I grew up and developed relationships with people, and cut relationships with people I've found that I never really got to know someone until I've seen them express different emotions.
In order to get to know someone, in my humble opinion, you've got to see them upset. You have got to see them mad, glad, sad and every color of the rainbow. You don't truly get to know someone until you have seen them shout, cry, and laugh till it hurts.
It's in how you react, that truly defines who you are! (or want to be..)
I was recently listening to an episode of the ALT.NET podcast with guests Jeremy Miller, David Laribee, and Chad Myers. I remember Chad saying something to the effect of being slightly embarrassed of the code that Jeremy was about to step in to. I realized that I felt the same way...
I remember last year when I was just jumping into this .NET game. I had nothing to hide, I wanted people to review my work. I wanted feedback, I wanted guidance and I really worked hard to get feedback from people that I respected.
Today, I feel more like Chad! I feel a little more defensive about the stuff that I've written. I'm more nervous about having to explain design decisions made months ago, that I don't agree with today. I'm apologetic for making choices and writing some of the code that I've written. *sigh* (The overuse of the word I, probably hides the fact that yes I am part of an agile team and a lot of the decisions were made as a team or at least in pairs.)
Kshitij reminded me of a quote from Robin Sharma. I don't remember the exact quote but to paraphrase its along the lines of...
"If the cup is full, it will spill if you try to fill it. You must empty the cup in order to re-fill it!"
The reason that I think this quote applies is because I now realize that if
I choose to be to proud to accept criticism now, then I'm likely to be stuck in my ways. The work that I've done, was a reflection of my abilities at the time I was doing it, and not a reflection of who I am today.
Have you ever experienced that feeling of when you bring someone new in to a team, and you subconsciously wonder how they're going to upset the balance of the team. Are they going to find the dirty skeletons in your code closet and expose you. Or are they going to go with the flow, and just accept the way things are and keep on keepin' on!?
I think that I'm trying to form a post from all these random ideas, but the point I'm trying so hard to make is don't be embarrassed of your skill set. If we were all super heroes, then we wouldn't have any!
"The ghetto, let go. It's not a novelty, you can love your neighborhood, without loving poverty." - KRS ONE
You can keep that love for software, using alternative methods...
I'm currently reading...
| ||Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition) |
by Craig Larman
Read more about this book...
(I'm actually reading the 2nd edition)
This is a good book. It started off really boring... really boring! I picked up this book as an introduction to object oriented programming, and it started off with a lot of talk on UML, documentation and the Rational Unified Process. But then I got to chapter 16... "GRASP: Designing Objects with Responsibilities".
Here's an excerpt that I enjoyed!
"Perhaps the most common mistake when creating a domain model is to represent something as an attribute when it should have been a concept. A rule of thumb to help prevent this mistake is:
If we do not think of some conceptual class X as a number or text in the real world, X is probably a conceptual class, not an attribute."
Here's a definition for a Domain Model...
"The Domain Model provides a visual dictionary of the domain vocabulary and concepts from which to draw inspiration for the naming of some things in the software design."
Chapter 16 is great so far, it talks about how to decompose responsibilities for objects using an acronym (I'm not a fan of acronyms) called GRASP. GRASP stands for General Responsibility Assignment Software Patterns.
Craig goes on to talk about the five different patterns of GRASP. They are:
- Information Expert: the class that has the information necessary to fulfill the responsibility.
- Creator: a class that has the responsibility to create an instance of another class.
- High Cohesion: increase the measure of how strongly related and focused the responsibilities of an element are.
- Low Coupling: decrease the amount a class is connected to, has knowledge of, or relies on other elements.
- Controller: a class with the responsibility of receiving or handling a system event message.
A couple of days ago I posted something on an XmlEnumerable. An object that knows how to traverse an XML document in a linear form. After talking with Adam, he suggested that I simplify the implementation with a little XPath action.
Diving a little deeper, I think using XPath expressions are probably a lot more efficient for traversing a document.
If you ever need to traverse each xml element in an xml document , you may want to implement your own XmlEnumerable. I've had some issues with the .NET XML API recently. The built in .NET XmlElement implements the non generic IEnumerable which means you've got to foreach through a bunch of objects.
This kind of scares me a bit because of the Xml object hierarchy. The reason being, there are several sub classes of XmlNode, and trying to understand this object hierarchy is not interesting to me.
Rather than having to check if each item is an Xml element, we just created our own abstraction that we prefer to work with, and map from the framework XmlElement to our own IXmlElement.
Let's say you need to traverse and Xml that looks like this:
If we were to traverse this document we would expect to find 10 elements
We could walk this xml structure and query it, using an API that we prefer by building our own IEnumerable and extension methods for querying.
Now you can traverse your own xml data structures using a more strongly typed API that suits your needs. For example:
Hopefully, this helps someone else who's drowning in xml!
Tim Ferriss writes:
"Brain activation for listening is cut in half if the person is trying to process visual input at the same time. A recent study at The British Institute of Psychiatry showed that checking your email while performing another creative task decreases your IQ in the moment 10 points."
This post is definitely worth reading!
I received a question the other day on building menu's in a win forms application. I wasn't sure of a clean way of doing it, so I thought I would put together a sample app to see if I could come up with something. I'm not sure I'm completely happy with what I've got so far, but my goal was to be able to drop in new menu items, and menu groups without a lot of ceremony and configuration.
The guts of it depends on castle windsor to glue most of the pieces together using the mass component registration api. I found it really hard to test, but was please with how easy it just kind of worked!
The other neat piece that kind of made things easy to get up and running was the concept of a default repository. (I picked up this bit of knowledge from Oren at DevTeach.)
This was the only implementation of a repository in the system, and it was used for a IRepository and IRepository. I just created a new implementation of an IMenuItem or ISubMenu and it picked it up via Windsor's mass component registration.
I also spent a little time playing with Gallio. I had some issue with conflicts between the version of Castle.Microkernel that I was toying with and the one that comes with gallio. I wasn't able to resolve the issue, but after looking into the concept behind Gallio, I like the idea. Kind of neat stuff!
Here's what I came up... Thank you Mr. JP for the inspiration!
Source can be downloaded here!
I can't stress how many ideas in this project came from concepts learned from the Nothin' But .NET boot camp. If you're in the area, you should definitely go check out the Vancouver course coming up next month!
Last week my family and I were in Toronto, Ontario so that I could attend DevTeach. A conference put on by developers for developers, and it was a tonne of fun. Not only did my wife, daughter and I get to check out Toronto, and visit family but I got to bump in to some more of the industries greats and here them speak.
Before I continue I've got to plug this little cafe that we accidentally stumbled into one night. My daughter, wife and her cousin were out looking for the MuchMusic building when we got a little lost. We ended up walking down McCaul Street and spotted this tiny little cafe on the corner of Elm St. It looked pretty cool from the outside and just looked kind of out of place. We're so glad we stopped in... The place was called "MangiaCake Panini Shoppe" and they specialized in panini's and, you guessed it, cake!
We tried a piece of the cherry cheese cake, chocolate cake, and the carrot cake, as well as a salad, a couple of panini's and a lasagna for myself. It was absolutely awesome! The best part was the additional attention we got from the owner named Raj. He was just great and made the experience so much more...
If you're in the Toronto, Ontario area you have to check out MangiaCake Panini Shoppe located at 160 McCaul Street.
Back to the conference...
Day 1: Tuesday, May 13, 2008
8-9:15am: Keynote by Scott Hanselman
Scott talked about Data Dynamic Web Applications, Astoria, tools like Fidler Http Proxy, LinqPad, TcpTrace.
9:30-11:00am: Home-Grown Production System Monitoring: Creating a Bridge Between Development and Operations by Owen Rogers
I really enjoyed Owens talk. I thought it was informative and backed by real project experience. Some of the things I learned:
Problems with log files:
- not analyzed
- not accessible
- size constrained
- multiple logs (different time zones?)
You should log for immediate data, and limit the footprint of logging on client machines. Owen mentions that a great book to read is "Release It" by Mike Nygard.
11am-12:15pm: Behavior Driven Development Installed by David Laribee and Scott Bellware
This was a great session, that showcased the direction that BDD is taking and what it means. Some of the things I learned are:
- User stories should not have UI or technical language in it.
- We should try getting our end users to help write the stories.
- Acceptance criteria has technical details in it.
- Break a apart the product backlog, from a release backlog and an iteration.
- When writing context based specifications use the active voice instead of the passive voice. Eg. "when an account has been opened" is in the passive voice. The active voice says "when opening an account".
1:30-2:45pm: How to make scrum really work by Joel Semeniuk and Turning Visual Studio Into a Software Factory by Kevin McNeish
I bounced out of the scrum talk as soon as we started getting into team foundation server, and the software factory talk wasn't exactly what I expected.
3:00-4:15pm: Achieving Persistence Ignorance with NHibernate by James Kovacs
This was a good talk that discussed alternatives to Active Record and how to implement an infrastructure ignorant domain model. It talked about different settings in NHibernate and how to create the mapping files and most importantly why you would want a infrastructure ignorant domain model.
4:30pm-5:45pm: Rapid (maintainable) web development with MonoRail by Oren Eini
This was another good talk walked through the creation of a project using MonoRail. Oren talked about the different conventions that are used by MonoRail and put it in contrast to the MS MVC framework. I'm definitely more curious about MonoRail and itchin' to slap something together using it.
Day 2: Wednesday, May 14, 2008
8-9:15am: Cross-platform Development with Mono by Geoff Norton and Planned Agility?! by David Laribee
The Mono talk was great, and actually got me pretty excited about the project. I'm surprised by just how much the Mono team has been able to accomplish and by the quick turn around on releases. I'm definitely going to have to spend some time learning more about the project.
The Mono talk ended a little early so I popped into David Laribee's talk on planned agility. This was a great talk on how to bring Agile into your projects. I guess it's still a little surprising to me how many company's are still working in a traditional methodologies, so it makes me feel pretty privileged to work where I do and with the great guys that I work with.
9:30-10:45am: Recommended Practices for Continuous Integration by Owen Rogers
This was another great talk on the concepts of Continuous Integration and how to achieve it with an automated build server. Owen talked about the inception of the CruiseControl.NET project and shared his experiences with how people were using it effectively and how people were abusing it.
11:00am-12:15pm: Busy .NET Developer's Guide to F# by Ted Neward
Mr. Ted knows his stuff. This was a great talk about F# and the functional programming paradigm. A lot of it was over my head, but I enjoyed the discussion around why this is important and what are some of the potential benefits of this style of development. Concurrency and side effect free functions were topics that kept coming up. I will definitely have to commit some time to better understand functional programming.
1:30pm-2:45pm: Blackbelt Configuration for New Projects by Jeffrey Palermo
Mr. Jeffrey gave a great talk on how to take control of your projects by offering suggestions on project structure, how to set up a single user development environment, the importance of version control, dependency management, the importance of automated deployments, application architecture.
To be continued...
A great book to read is...
|Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series) |
by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts
Read more about this title...
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
"The first time you do something, you just do it. The second time you something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor."
Introduce Local Extension: A server class you are using needs several additional methods, but you can't modify the class.
Create a new class that contains these extra methods. Make this extension class a subclass or a wrapper of the original.
E.g From this...
Replace Conditional with Polymorphism: You have a conditional that chooses different behavior depending on the type of an object.
Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.
E.g From this...
Q: Should I be worried if my username and password are sent back and forth to a server in clear text, in a cookie, upon each request????
A couple of months ago I finished reading...
This was a thick book, that discusses unit test smells, unit test refactorings, unit test patterns... and just about anything else related to unit testing. Here's a little of what I've learned from this book...
"Mistakes happen! Of course, some mistakes are much more expensive to prevent than to fix. Suppose a bug does slip through somehow and shows up in the Integration Build. If our unit test are fairly small (i.e., we test only a single behavior in each one), we should be able to pinpoint the bug quickly based on which test fails. This specificity is one of the major advantages that unit tests enjoy over customer tests. The customer tests tell us that some behavior expected by the customer isn't working; the unit tests tell us why. We call this phenomenon Defect Localization. If a customer test fails but no unit tests fail, it indicates a Missing Unit Test."
Tests as Documentation
"Without automated tests, we would need to pore over the SUT code trying to answer the question, 'What should be the result if ...?' With automated tests, we simply use the corresponding Tests as Documentation; they tell us what the result should be. If we want to know how the system does something, we can turn on the debugger, run the test, and single-step through the code to see how it works. In this sense, the automated tests act as a form of documentation for the SUT."
"When it is not important for something to be seen in the test method, it is important that it not be seen in the test method!"
A test double is any object or component that we install in place of the real component for the express purpose of running a test. Depending on the reason why we are using it, a Test Double can behave in one of four ways.
- Dummy Object: a object that is passed to the SUT as an argument but is never actually used.
- Test Stub: an object that replaces a real component on that the SUT depends on so that different inputs can by applied against the SUT.
- Test Spy: an object that can act as an observation point for the indirect outputs of the SUT.
- Mock Object: an object that replaces a real component that the SUT depends on to test the and verify indirect outputs.
- Fake Object: an object that replaces the functionality of the real SUT dependency with an alternate implementation that provides the same functionality.
Strict vs Loose
Mock objects come in two basic flavors:
- Strict Mock: fails the test if incorrect calls are received.
- Loose (lenient) Mock: fails if expected calls are not received, but is lenient if additional calls are received.
"This 'outside-in' approach to writing and testing software combines the conceptual elegance of the traditional 'top-down' approach to writing code with modern TDD techniques supported by Mock Objects. It allows us to build and test the software layer by layer, starting at the outermost layer before we have implemented the lower layers."
"Developers Not Writing Tests may be caused by an overly aggressive development schedule, supervisors who tell developers not to 'waste time writing tests,' or developers who do not have the skills to write tests. Other potential causes might include an imposed design that is not conducive to testing or a test environment that leads to Fragile Tests. Finally, this problem could result from Lost Tests - tests that exist but are not included in the All Tests Suite used by developers during check-in or by the automated build tool."
"Another productivity-sapping smell is Frequent Debugging. Automated unit tests should obviate the need to use a debugger in all but rare cases, because the set of tests that are failing should make it obvious why the failure is occurring. Frequent Debugging is a sign that the unit tests are lacking in coverage or are trying to test to much functionality at once."
Fragile Test: "A test fails to compile or run when the SUT is changed in ways that do not affect the part the is exercising... Fragile tests increase the cost of test maintenance by forcing us to visit many more tests each time we modify the functionality of the system or the fixture."
This headache is typical if you're working with strict mock objects. I experienced this pain when working on a project using NMock. I couldn't find a clean separation between strict and loose mocks using NMock. There was only the concept of Strict Mocks and Stubs.
Slow Tests: "The tests take too long to run... They reduce the productivity of the person running the test. Instead, the developers wait until the next coffee break or another interruption before running them. Or, whenever they run the tests, they walk around and chat with other team members..."
The main disadvantages of using Fit are described here:
- The test scenarios need to be very well understood before we can build the Fit Fixture. We then need to translate each test's logic into a tabular representation; this isn't always a good fit.
- The tests need to employ the same SUT interaction logic in each test. To run several different styles of tests, we would probably have to build one or more different fixtures for each style of test. Building a new fixture is typically more complex than writing a few Test Methods.
- Fit tests aren't normally integrated into developers' regression tests that are run via xUnit. Instead, these test must be run separately - which introduces the possibility that they will not be run at each check-in.
"A concept from lean manufacturing that states that things should be produced only once a real demand for them exists. In a 'pull system,' upstream assembly lines produce only enough products to replace the items withdrawn from the pool that buffers them from the downstream assembly lines. In software development, this idea can be translated as follows: 'We should only write methods that have already been called by other software and only handle those cases that the other software actually needs.' This approach avoids speculation and the writing of unnecessary software, which is one of software development's key forms of inventory (which is considered waste in lean systems)."
I'm just about finished reading...
| ||Agile Web Development with Rails, 2nd Edition |
by Dave Thomas, David Hansson, Leon Breedt, Mike Clark, James Duncan Davidson, Justin Gehtland, Andreas Schwarz
Read more about this book...
This book focuses on the Ruby on Rails framework for developing web applications. It touches very lightly on the Ruby language itself, but mostly talks about things like Model View Controller, Active Record, Action Pack and how it's implemented in RoR's. The book starts off with a light primer on what MVC is, which I enjoyed, then moves on to how to install RoR, then jumps right into building a quick application using RoR. I enjoyed the discussion Testing and the concept of Migrations.
Before jumping right in to chapter one I quickly read through the first Appendix titled "Introduction to Ruby", which helped a little bit, but I probably would have done better if I had first read a book just on the Ruby language. I think I would have found it more interesting as well. There were times in the book where it got so deep into the nitty gritty details of the RoR framework that I just completely lost interest. I choose to read this book to get some high level ideas, but I wasn't as interested in the tiny details of the framework. There's tonnes of great ideas in this book, that I recognize being adopted quite a bit in the .NET community. Migrations and MVC being a couple of my favorites.
Here's a few excerpts that I enjoyed from this book...
Convention over Configuration
"Rails gives you lots of opportunities to override this basic workflow ... As it stands, our story illustrates convention over configuration, one of the fundamental parts of the philosophy of Rails. By providing convenient defaults and by applying certain conventions, Rails applications are typically written using little or no external configuration - things just knit themselves together in a natural way."
"Over the years, developers have come up with ways of dealing with this issue. One scheme is to keep the Data Definition Language (DDL) statements that define the schema in source form under version control. Whenever you change the schema, you edit this file to reflect the changes. You then drop your development database and re-create the schema from scratch by applying your DDL. If you need to roll back a week, the application code and the DDL that you check out from the version control system are in step: when you re-create the schema from the DDL, your database will have gone back in time.
Except... because you drop the database every time you apply the DDL, you lose any data in your development database. Wouldn't it be more convenient to be able to apply only those changes that are necessary to move a database from version X to version Y? this is exactly what Rails migrations let you do."
"In the old days, browsers were treated as really dumb devices. When you wrote a browser-based application, you'd send stuff down to the browser and then forget about that session. At some point, the user would fill in some form fields or click a hyperlink, and your application would get woken up by an incoming request. It would render a complete page back to the user, and the whole tedious process would start afresh...
Whenever you work with AJAX, it's good to start with the non-AJAX version of the application and then gradually introduce AJAX features."
No REST For The Wicked
"REST stands for REpresentational State Transfer, which is basically meaningless. What it really means is that you use HTTP verbs (GET, POST, DELETE, and so on) to send requests and responses between applications."
"Testing isn't just about whether something does what it should. We might also want to know whether it does it fast enough.
Before we get to deep into this, here's a warning. Most applications perform just fine most of the time, and when they do start to get slow, it's often in ways we would never have anticipated. For this reason, it's normally a bad idea to focus on performance early in development. Instead, we recommend using performance testing in two scenarios, both late in the development process."
"Ruby statement modifiers are a useful shortcut if the body of an if or while statement is just a single expression. Simply write the expression, followed by if or while and the condition."
The following is valid Ruby syntax:
puts "Danger, Will Robinson" if radiation > 3000
I would love to express the following C# syntax....
Thank you Mr. Aaron, today we just grabbed the latest beta version of Rhino.Mocks and out test times significantly dropped....
Our times before the update were 450ish seconds to run all the unit tests and create the report:
Our times after are 100ish seconds:
Defines Unit of Work as:
"Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems." - PoEAA
I've been playing with some different ideas on how you can implement a unit of work in a win forms application.
Here was the idea of the usage:
When the unit of work is asked to commit the new and modified instance would be committed to the person repository, in this case my imaginary black book.
Here's how it works... Person inherits from "DomainSuperType". In the layer super type the no argument constructor registers itself with the current unit of work. I really don't like this because it makes all the domain objects aware of the surrounding infrastructure, and makes it much more difficult to test.
Next all components have to be decorated with the "Serializable" attribute, so that I could manage dirty object tracking. This also sucks...
The unit of work delegates to a registry of units of work to retrieve the unit of work applicable to type ....
The unit of work registry creates a unit of work for type if one hasn't been started yet. Otherwise returns the already started unit of work. This registry is similar to an identity map using type T as the identifier.
The unit of work factory leverages the dependency resolver to retrieve an implementation of the repository applicable to type T.
Each time the unit of work factory is asked to create a new unit of work it creates a fresh instance of a work session.
Each registered instance immediately clones the original instance to keep track of changes between the original and the current working copy. For this to work properly the cloner has to perform a deep copy otherwise the dirty tracking wont work properly. To do the deep copy, i'm using serialization, hence the "serializable" attribute decorating each entity.
So far this implementation is just a spike on how to implement a unit of work, it's really not a great implementation but I'm hoping to solicit some feedback on ways that have worked for others.
So last week the guys and I at work started to spike ASP.NET MVC. We're starting up a new project, and decided to take advantage of the Preview 2 version of the so far released libraries. Our experiences so far have been.... hmmm... not as expected.
Here's a few things we've learned, hopefully they help someone else out. We're nant junkies, so the first thing we did to get going was automate the compiling, testing, running, deploying, and creation of the database with nant. We found that when running our project against the aspnet_compiler.exe that it didn't recognize some of the new C# 3.0 syntax.
The above code would raise an error with the aspnet_compiler.exe. Now this is valid C# 3.0, but the pre compiler didn't know what to do with the "var" keyword. Next, the precompiler didn't know where to find the "Form()" method on the Html helper class because, it's an extension method.
It's kind of an interesting idea that so many methods on the "HtmlHelper" class are extension methods. The solution to getting the aspnet_precompiler to recognize the C#3.0 syntax was to dump this block of xml in the web.config.
Next up... testing controllers. I think the guys and I were a little surprised at just how awkward it was to test a controller. I thought, a lot of time was spent making the controllers more testable. Our first pain point was the fact that "RenderView()" is a protected method on the Controller base class. Here's what I'm talking about...
So let's think... how can we test that when the Index action is invoked it calls "RenderView" with an argument value "Index"... So some people have suggested creating a Test Double. I say... booo... I use mock object frameworks so that I don't need to groom a garden of hand rolled test stubs. Here's what we came up with... first cut remember!
Ok... so it's slightly more testable. Each action on the controller executes a command, after first being initialized with ... The other thing to notice is that the OrderController inherits from BaseController. BaseController is actually an adapter that implements an IViewRenderer interface.
The OrderIndexCommand is initialized with an IViewRenderer.
If you haven't heard, JP's giving away a $70.00 book credit to Amazon. For more details check out his most recent post.
I really enjoy reading books, but if you're low on funds. Books can be quite pricey, especially tech books. This is a great offer, and anyone interested should definitely take the man up on his offer. Even if YOU don't need the books, or the credit, I'm sure you can think of someone who could. Let them know...
Why do I even care?
Because I know how hard it was to purchase books and support a family. I'm in much better shape now, and would love for someone else who needs a leg up to win an opportunity to be successful. Do you know someone that could use a little help?
Wow... I don't know what it is, but right after the ALT. NET conference I was pretty pumped up and excited, but these days I'm feeling a little low. It's amazing how many young, talented people there are out in the industry. It's more amazing to see how fast people are moving and growing.
The guys on my team, and I, try hard to stay up on what's new... and what the cool kids are doing. But these days' it's just making me dizzy... we've got the Eleutian Guys slingin' code like crazy. This PolyGlot programming thing has got me feeling like I need to go add more languages to my vocab. I'm getting sick of checking my gmail, because each time i do it looks like the ALT.NET mailing list has just puked all over my monitor.
There's new frameworks flying out like ASP.NET MVC, Moq, Prism, Silverlight, WPF... then debates about how to write tests, what's bdd, is the auto mocking container a smell. Then there's the hype around ruby and rails, and the comparisons between dynamic and statically typed languages.
It's got me a little dizzy, but now that I think about... it's kind of cool how fast the industry seems to be evolving!
I'm still reading...
Here's a few quotes from the book, that I found interesting:
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." - Donald E. Knuth
"Don't sacrifice sound architectural principles for performance. Strive to write good programs rather than fast ones. If a good program is not fast enough, its architecture will allow it to be optimized. Good programs embody the principle of information hiding: Where possible, they localize design decisions within individual modules, so individual decisions can be changed without affecting the remainder of the system."
A typical example of pre-mature optimization is thinking about "database calls" when working up in a UI layer. These are two completely separate architectural layers and should be developed without "optimization" constraints in mind.
"...we have to check if its a post back, to make sure we don't make another database hit. If we retrieve the contents of the page each time the page is requested that's going to be another database hit."
Relax... there are lots of techniques (lazy loading, identity map...) to improve performance if it's an issue. But optimizing the UI for database performance is weak, and will more than likely cause you to build a crippled UI layer before even hitting the lower layers.
"Often attempted optimizations have no measurable effect on performance; sometimes they make it worse."
If we take the above example, if you're constantly "optimizing" for database performance be weary of what it's costing you. E.g... ViewState, extra conditional code that's sooo freakin' impossible to understand, that no dev wants to come back and touch that code.
It can be pointless to try to find solutions to a problem that doesn't exist.
One of the underlying themes I noticed at ALT.NET was that there were a lot of people their, like myself, who were yearning for good mentoring. They wanted to be part of teams that had "senior" developers that could lead them, and push them to grow.
We all seek guidance, some of use are privileged to be guided by others and learn from the shared experience and some of us pave our own paths.
There is a very fine line between mentoring and molding, one that I think is important to distinguish. To be truly mentored by someone, means that your mentor will be able to offer you challenges that push you outside of comfort zone without telling you how. Your mentor should challenge you to be great, not tell you how it's done! A good mentor will empower you, and teach you how to think, not what to think. A good mentor knows how to learn just as much from you, as he knows how to teach you.
When you're being molded, you're shown how you're expected to do things. A blind mentor may do this to gain a sense of control, but in the process fails to trigger new ideas in those around them. This benefits no one. Not only is the mentor not gaining from allowing the protege from being creative and allowing new ideas to trigger greater ones, but the blind mentor locks his/herself down to only their own ideas and does not allow themselves to open up to change and trigger new ideas.
I'm sure mentoring is a tough thing, no one wants to wear the "Hi I'm your mentor" name tag. But perhaps there are mentors all around us. If we were to look at those around us more closely, and tried to understand what it is that each person can teach us, then you're surrounded by mentors. Everyone has something that they can teach you, the toughest part is trying to find out what that is.
"In any journey it is helpful to have a guide, someone who can help us in times of difficulty. Often, we do not venture forth due to fear. A good guide, a teacher, quells our fear and gives us confidence during our journey. An old Indian adage says: "When the student is ready, the teacher appears." Sri Chinmoy has a beautiful poem that talks about this journey."
You have a multitude of questions,
But there is only one answer:
The road is right in front of you,
And the guide is waiting for you.
I'm currently reading...
I thought I would share en excerpt that I read this morning on the bus... it's about my favorite topic: Implementation Inheritance.
"Inheritance is a powerful way to achieve code reuse, but it is not always the best tool for the job. Used inappropriately, it leads to fragile software. It is safe to use inheritance within a package, where the subclass and the superclass implementation are under the control of the same programmers. It is also safe to use inheritance when extending classes specifically designed and documented for extension. Inheriting from ordinary concrete classes across package boundaries, however, is dangerous. As a reminder, this book uses the word 'inheritance' to mean 'implementation inheritance' (when one class extends another). The problems discussed in this item do not apply to interface inheritance (when a class implements an interface or where one interface extends another)."
"Unlike method invocation, inheritance breaks encapsulation. In other words, a subclass depends on the implementation details of its superclass for its proper function."
So at lunch I decided to check my email, and I got one from Justice with a subject that read....
"Did you get one of these? Fwd: ALT.NET Seattle!"
It was a forward from David Laribee, one of the organizers of ALT.NET, that was sent out to all registered attendees. As I continued to read it said:
"We are *FULL* and there are, I'm sorry to say, no "plus ones" at this point."
My reaction was... GULP, my wife is going to kick my ***!
Then a magical thing happened... I saw another email in my inbox... the subject read "ALT.NET Seattle!" and it was from Mr. David Laribee himself!
I'm in, I'll see you cool kids this weekend in Seattle! If you're thinking about crashing the party, I would suggest that you get in touch with one of the organizers instead of pulling a mO... *sigh*
The email in it's entirety, for all the curious!
We're just about ready to launch into ALT.NET Open Spaces, Seattle. A few housekeeping notes:
- The space opens on Friday, 4/18 from 6pm to 8pm. Saturday we'll meet for sessions between 10am and 6pm. We'll wrap up on Sunday from 10am to 2pm.
- There is no shuttle service between the hotel (Marriott Town Center) and DigiPen (event location). Please arrange or offer rides if you can. It's Bring Your Own Ride, so be aware.
- Event details (location, maps, times) are always available at http://altdotnet.org/events/seattle/
- We are *FULL* and there are, I'm sorry to say, no "plus ones" at this point. We'll be doing a loose registration at the door and you have to be registered (you are if you're getting this message) to participate.
If you have any questions, please send me email. I'll do my best to answer promptly.
Looking forward to an exciting and productive meet-up!
So last night my wife and I booked our tickets to Seattle, Washington. I'm heading down this weekend in hopes that I'll be able to attend the ALT.NET conference. I'm currently sitting on the wait list to get in, but hopefully it all works out.
When the registration went up for the ALT.NET conference it was hard to predict what I would be doing and whether or not I would be able to attend. Now that it's a little closer to the date, it's a little easier to gage. Regardless of what happens we're super excited about visiting Seattle, and Redmond, Washington.
Cross your fingers for me!
Loading a subversion repository from a dump file isn't as hard as I thought it would be. It's as easy as:
> svnadmin path.to.repository.directory < repository.dump.file
You just have to make sure that:
- you've got subversion installed or that you can hit "svnadmin.exe" directly.
- the "path.to.repository.directory" has a repository created in it.
All that this seems to be doing is replaying every commit that ever happened on the original repository. This is pretty sweet, especially for a class room set up when the student afterwards want to go through different revisions to compare changes or things learned in class.
What a week!! Well as I expected it was awesome, intense, and career altering. My wife, daughter and I traveled to Austin, TX to take part in the Nothin But .NET boot camp. We love Austin! It's an amazing city, and the people are fantastic. We often hear about how friendly Canadians are, but honestly it was unbelievable how kind people are in Austin. Every where you go people seem to be having fun and loving life. We spoke with bus drivers, cab drivers, people sitting at the bus stop, people at restaurants, people downtown.
My wife and daughter traveled the city using transit while I was in class all week. Everyday my wife would tell me stories about how nice people were to her. She dislikes taking transit here in Calgary but really found it fun and a pleasant experience in Austin. The buses are pretty cool. For $1 USD you get a ticket that lasts for 24 hours. When you get on the bus you swipe it at the front and get on. Bus drivers were so friendly and told stories and jokes during the ride. They really made an extra effort to help people in wheel chairs get on the bus. I'd never seen it before, but seems to be common. Awesome!
A lot of people we met in Austin, aren't originally from Austin. It seems that there are a lot of people currently migrating there. We were fortunate to meet a pretty cool cab driver named Ed. He moved to the states from Brazil and told us a lot about the city of Austin.
The course itself was awesome. There were students there from Austin, Winnipeg, Houston, Denver, Calgary, Louisiana, and even as far as Brazil. It's amazing how close you seem to get over such a short time. The same thing seemed to happen in the Calgary course. The collaborative environment really gets people to drop their defenses, open up and be comfortable with their current skill set knowing that it's only where they are today, but not where they'll be tomorrow.
There were so many great conversations about so many different topics. Everyone seemed to have great opinions and ideas to further and push the .NET community. Everyone in the room was definitely passionate about developing better software.
It was pretty cool to meet Scott Bellware, and here some of his ideas about .NET and software development in general. At first I didn't really get it, but by the last night it clicked in. I remember saying in my head... "He's right!" Scott is a super passionate person, and questions everything. I remember making it a motto to "question everything" and he truly does that well. The .NET community definitely needs a voice like Scott, to keep us all on our toes to make sure we pay attention to what we're doing, to expose more effective ways of doing things.
I realize that as a young dev that I'm part of the next generation, and it's important to me to learn from the trail blazers and continue pave new paths when they've finished.
One of the key things that Scott talked about was the concept of Solubility. "It's so easy to read that it melts into your brain." The new style of writing unit tests that target specific contexts make it so much easier to jump in to a specific context and continue to write in new chapters of the novel. I really enjoy reading code and tests that read like chapters from a novel. It's a higher level abstraction that allows me to focus on the problem domain rather then the technical details. Let the compiler do the interpreting...
It was so much fun being a teaching assistant. I love answering questions and helping out, at first I was pretty nervous but after being able to fix a few small issues I felt better. One of the things I learned this week was that when I didn't know the answer or wasn't sure it was important to make sure I made that known. The last thing I want to do is pass along incorrect information or pretend to know more than I do. I found that by just communicating that I didn't know the answer to a problem, that chances were that someone else in the room did. This is one of the reasons why the open, collaborative work space is so important. You can save so much time by just asking for help.
When we left Austin to go home, we were pretty sad to leave. The further we got away from Austin, the more we talked about how we could totally move to Austin... I can't wait to go back and help out at the next boot camp!
The month of March was definitely a busy one. The month of April will be another busy one. Yesterday I started my first day at eCompliance. I left ThoughtWorks to pursue the world of the start-up. So far it's been a lot of fun. Day one on the job I was hitting things that most developers are sheltered from. Although, a bit scary at times... it's been a super fun ride so far.
I managed to knock off a few goals from my list, I finished the second exam to earn an MCTS designation, I finished reading xUnit Test Patterns, and my family and I booked tickets to fly down to Austin, Texas for a week.
Last year it was a huge dream for me to be able to attend the Nothin' But .NET boot camp, and this year I'm proud to say that I will have the opportunity to help TA at the upcoming boot camp in Austin. I'm super nervous, and humbled that this opportunity is available to me. The best part is when my wife and I sit down, and cross things off our list of goals, together!
Since my wife and I sat down and wrote out our list of goals, things started happening almost immediately. We slapped ours on the side of the fridge so that we can take a peek at it as we walk by. It's been invaluable to us, and has helped us with making tough decisions.
One of the things I've learned is that my lists tend to change, but our list is pretty much the same since it started. I would go full force trying to accomplish things off my list, even if they were no longer important to me. I've started to adjust my lists, and I don't feel as bad as I thought I would when I don't knock things off my old lists. Hopefully, it's a sign of adapting to changes rather then settling for less.
A wise man once suggested that I get listed, and now I suggest you do the same!
I had an interesting conversation the other day about expired knowledge. On the current project I'm working on I'm realizing that there are a lot of gaps in my knowledge of WebForms. The other day, I told the person that I was pairing with that this chaotic abstraction of the web is confusing to me. My lack of knowledge of WebForms is not because I haven't learned it yet, it's because I didn't really want to.
I remember the first time I heard the term "complex page life cycle". It had no meaning to me so I googled it to find out what it mean. oh man.. oh man... i remember reading through some MSDN docs about the sequence of events that fire as a page is constructed, and thought to myself. I'm not going to memorize this. This is crazy....
What is an advanced knowledge of webforms going to mean to you in 5 years? how about 10 years? how about 20?
I have no idea what the future holds for me, but I do know that I want to be in software for quite a while, so I do my best to focus on knowledge of software development that wont expire quickly. I would much rather spend my time studying, the intricacies of new programming paradigms rather than learning the intricacies of some new framework.
It sucks when you're doing a demo of your work to a person from business, and they're more impressed by shiny things in the UI, rather than how well tested and loosely coupled your design is.
It's like an owner teaching it's dog that it will be rewarded for certain types of behavior. If I'm rewarded by spending my time learning about how to use the cool new AJAX controls, and shunned for spending my time trying to understand what the Liskov Substitution Principal means, then what am I more likely to do?
What's the moral to this story... don't feel bad, like I do, that you don't know the intricacies of some specific technology. Strive to understand what it is you're doing, and why you're doing it like that.
My focus for this year is to study:
- object oriented programming
- test driven development
- design patterns
What about you?
I recently started to leverage extension methods in my unit tests as a way to create more readable and strongly typed unit tests. Here's an example:
This is a completely state based unit test that asserts that the result of the calculation is equal to 17. The actual assertion actually happens in an extension method. Defined below:
MbUnits Assert.AreEqual() method has several overloads. The one I use the most is the overload defined as follows:
The problem I have with this overload is that it's not strongly typed. So I could have written an Assertion that looked like:
This won't give me a compile error but will indicate a broken test with the following message.
Equal assertion failed: []!=[[Calculator.Domain.Number]]
This happens because the integer value type 17 is not equal to the Number reference type with an underlying value of 17. Also, this would have boxed the value type to a reference type to use the overload that accepts two objects. (which is also expensive)
By extending the assertion with a generic extension method, I get a more readable test with the strong typing of generics.
Hopefully, this saves you from some embarrassing moments with your pair!
I recently finished reading...
My desire to read this book was to understand what new language features C# 3.0 brings to the table. This book started to explain the C# language right from the very beginning up until now. So some of it was a great refresher and some of it was quite boring. It not only covers the new language features but covers several areas of the framework class libraries and new lib's that came with the .NET 3.5 stack.
I was hoping to find my coverage on the new language features to see different usages for things like extension methods and lambda's to try to get a sense for what I like and don't like. So far I'm not really a fan of the new query comprehension syntax. It's to SQL-ish for me... I prefer working directly against methods. But I might have to give it some time... enough ranting here's some of the things I've learned.
There's tonnes, and tonnes of discussion on this topic right now. I love how it's so much cleaner, and less verbose then anonymous delegates, but I see potential room for abuse. IMHO seeing lambda's tossed around all over your code base is no better then over using anonymous delegates. I love the new ideas that lambda's bring though...
"A lambda expression is an unnamed method written in place of a delegate instance. The compiler immediately converts the lambda expression to either:
- A delegate instance.
- An expression tree, of type Expression<T>, representing the code inside the lambda expression in a traversable object model. This allows the lambda expression to be interpreted later at runtime..." - C# 3.0 in a Nutshell
I love the idea of building up an expression tree of delegates that chain together to solve an equation. One of the ideas I'm working on is understanding how to leverage an expression tree of lambdas to solve trivial mathematical equations. Then possible traversing through the structure with a visitor to build out a display friendly version of the equation.
"The benefits of WPF are as follows:
- It supports sophisticated graphics, such as arbitrary transformations, 3D rendering, and true transparency.
- Its primary measurement unit is not pixel-based, so applications display correctly in any DPI
- It has extensive dynamic layout support, which means you can localize any application without danger of elements overlapping.
- Rendering uses DirectX and is fast, taking good advantage of graphics hardware acceleration.
- User interfaces can be described declaratively in XAML files that can be maintained independently of the "code-behind" files - this helps to separate appearance from functionality." - C# 3.0 in a Nutshell
"WCF is the communication infrastructure new to Framework 3.0. WCF is flexible and configurable enough to make both of its predecessors - Remoting and (.ASMX) Web Services - mostly redundant." - C# 3.0 in a Nutshell
"If you're dealing with data that's originated from or destined for an XML file, XmlConvert (the System.Xml namespace) provides the most suitable methods for formatting and parsing. The methods in XmlConvert handle the nuances of XML formatting without needing special format strings." - C# 3.0 in a Nutshell
"The compiler, upon parsing the yield return statement, writes 'behind the scenes,' a hidden nested enumerator class, and then refactors GetEnumerator to instantiate and return that class. Iterators are powerful and simple" - C# 3.0 in a Nutshell
"Its underlying hashtable works by converting each element' key into an integer hashcode - a pseudo unique value - and then applying an algorithm to convert the hashcode into a hash key. This hash key is used internally to determine which 'bucket' an entry belongs to. If the bucket contains more than one value, a linear search is performed on the bucket. A hashtable typically starts out maintaining a 1:1 ration of buckets to values, meaning that each bucket contains only one value. However, as more items are added to the hashtable, the load factor dynamically increases, in a manner designed to optimize insertion and retrieval performance as well as memory requirements." - C# 3.0 in a Nutshell
"The data contract serializer is the newest and the most versatile of the three serializatoin engines and is used by WCF. The serializer is particularly strong in two scenarios:
- When exchanging information through standards-compliant messaging protocols
- When you need high-version tolerance plus the option of preserving object references."
C# 3.0 in a Nutshell
"A Mutex is like a C# lock, but it can work across multiple processes. In other words, Mutex can be computer-wide as well as application-wide" - C# 3.0 in a Nutshell
"A Semaphore is like a nightclub: it has a certain capacity, enforced by a bouncer. Once it's full, no more people can enter and a queue build up outside. Then, for each person that leaves, one person enters from the head of the queue." - C# 3.0 in a Nutshell
"The Thread class provides GetData and SetData methods for storing nontransient isolated data in 'slots' whose values persist between method calls." - C# 3.0 in a Nutshell
Last week I went and checked out JP's latest presentation on Generics at the Calgary .NET User Group, and as usual it was awesome! He's definitely knee deep in C# 3.0, and was dropping lambda's and extension methods like it was old news... Here's some of the stuff I learned.
Extending the ISpecification interface via the use of Extension methods.
By accepting a Predicate delegate as the second argument you can now inline your lambdas and still take advantage of specifications. Client components can now take advantage of these extensions like this...
The base specification class becomes a quick and easy...
I just finished reading...
Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series)
by Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides
Read more about this title...
It's about time I read this book... This catalog contains 23 patterns with examples in C++. I enjoyed reading this book. I found at times that my mind started to drift off, but then there were moments when I would forget where I was and miss my bus stop. (Ok one moment!)
I enjoyed reading the discussion on OO more then anything else in this book. The examples are a little dated but for it's time the catalog is awesome. Although I've been wanting to read this book for a while I preferred "Head First Design Patterns", mostly because it was easy to read. (I call it the comic book for dev's)
As usual, here are some quotes from the book that I really enjoyed.
"When an abstraction can have one of several possible implementations, the usual way to accommodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. But this approach isn't always flexible enough. Inheritance binds an implementation to the abstraction permanently, which makes it difficult to modify, extend and reuse abstractions and implementations independently."
"Studies of expert programmers for conventional languages have shown that knowledge and experience isn't organized simply around syntax but in larger conceptual structures such as algorithms, data structures and idioms, and plans for fulfilling a particular goal. Designers probably don't think about the notation they're using for recording the design as much as they try to match the current design situation against plans, algorithms, data structures, and idioms they have learned in the past."
"These design patterns can also make you a better designer. They provide solutions to common problems. If you work with object-oriented systems long enough, you'll probably learn these design patters on your own. But reading the book will help you learn them much faster. Learning these patterns will help a novice act more like an expert."
"To continue to evolve, the software must be reorganized in a process known as refactoring. This is the phase in which frameworks often emerge. Refactoring involves tearing apart classes into special- and general-purpose components, moving operations up or down the class hierarchy, and rationalizing the interfaces of classes. This consolidation phase produces many new kinds of objects, often by decomposing existing objects and using object composition instead of inheritance. Hence black-box reuse replaces white-box reuse. The continual need to satisfy more requirements along with the need for more reuse propels object-oriented software through repeated phases of expansion and consolidation - expansion as new requirements are satisfied, and consolidation as the software becomes more general."
I've got a beef with enums. When I see them, I cringe... which is quite different from my days in C, where I couldn't live without enums and structs. That's another story...
"Flyweight: Use sharing to support large numbers of fine-grained objects efficiently" - Design Patterns
Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series)
by Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides
Read more about this title...
Why do some of us quickly jump to enums? In procedural languages it makes sense. It's giving a type code a human readable meaning. So instead of having to stare at type code 1, everywhere you can use State.Acknowledgement, which is a lot easier to understand ... what does 1 mean again?
But in an OO language, I feel dirty when I see enums. The argument of using it for bitwise operations and the Flags attribute is weak. Create a composite!
Weak... do you really want to use a bitwise & to check if a certain digit is enabled. I don't. I'm going to use the following 2 tests to squash the enum into a first class component, with some smarts to it.
My current NumberBuilder implementation looks like this (it sucks but it works):
I'm going to start off by creating some Flyweights.
My compiler is telling me that the Add method on my builder currently accepts a parameter of type "Digits", so I'm going to change the signature to accept a parameter of type IDigit.
Let's update the NumberBuilder implementation to:
I run the tests and they pass, sweet. But I'm not happy with the current implementation, so I look for other potential refactorings. I decide to forward the digit to append right to the number, the number can take care of how to append the digit, rather then having the builder doing so. The builder now looks like:
And Number looks like:
To wrap this up, Number aggregates digits, the enum got dropped and was replaced by a class. There's still more refactorings that can occur, but the point is that a full blown component is much easier to extend then an enum...
For more info check out "Replace Type Code with Class" from...
Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series)
by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts
Read more about this title...
Refactoring: Improving the Design of Existing Code (The Addison-Wesley Object Technology Series) by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts
Read more about this title...
This book is awesome and a must read for anyone who enjoys the art of refactoring as much as I do. The examples are crystal clear and the way the refactorings are done step by step makes it so much more understandable.
Here are a few excerpts that I enjoyed from this book.
"The problem with copying and pasting code comes when you have to change it later. If you are writing a program that you don't expect to change, then cut and paste is fine. If the program is long lived and likely to change, then cut and paste is a menace."
I've got to agree and disagree with the above statement. I think anytime you find yourself copying and pasting is a clear sign of duplication which should be improved. Removing duplication should be something we all strive for, and remember that inheritance is not the only way to remove duplication. Proper object composition, delegation and generics are all great ways to remove duplicate code.
Replace conditional with Polymorphism has to be by far one of my favorite refactorings. If you're seeing if-else statements scattered throughout your code base that's a smell. Switch's are no better... (booo switches...)
"Is renaming worth the effort? Absolutely. Good code should communicate what it is doing clearly, and variable names are a key to clear code. Never be afraid to change the names of things to improve clarity."
Amen, brother! Thank goodness for tools like Resharper and Rhino.Mocks. On my current project we're using NMock2 and I got burned several times doing a Rename Method because of the string literals used in NMock tests... My advice is just use Rhino Mocks... please... for my sake!
"You write code that tells the computer what to do, and it responds by doing exactly what you tell it. In time you close the gap between what you want it to do and what you tell it to do. Programming in this mode is all about saying exactly what you want. But there is another use of your source code. Someone will try to read your code in a few months' time to make some changes. We easily forget that extra user of the code, yet that user is actually the most important."
"The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor."
I often heard the term "smell" used as a way to describe something funky in a code base or team but I had no idea where the term came from... until know!
"If it stinks, change it." - Gradma Beck, discussing child-rearing philosophy
The chapter on code smells is awesome, it's offers a catalog of code smells like:
* Duplicate Code
* Long Methods
* Large Classes
* Long Parameter Lists
* Divergent Changes
* Shotgun Surgery
* Feature Envy
* Data Clumps
* Primitive Obsession
* Switch Statements
* Parallel Inheritance Hierarchies
* Lazy Class
* Speculative Generality - "Oh, I think we need the ability to do this kind of thing someday."
* Temporary Fields
* Message Chains
* Middle Man
* Inappropriate Intimacy
* Alternative Classes with Different Interfaces
* Incomplete Library Classes
* Data Classes
* Refused Bequest - "Subclasses get to inherit the methods and data of their parents. But what if they don't want or need what they are given?"
If you only read one chapter in this book, I suggest Chapter 3. "Bad Smells in Code". I really like how Resharper uses the same refactoring names as those mentioned in this book. Anyway's, what are you waiting for go read this book.
Today I read...
A friend recommended this book, and I'm glad I listened to him. I found that when I started reading, I had trouble putting it down so I read the whole thing. The book starts off...
"A Nobody named Ordinary who lived in the land of Familiar."
After that, I realized a lot of this book was speaking about me. It explained the different people in my life and why they behave the way they do. I'm having trouble explaining why I enjoyed this book so much, maybe it's because right now I feel "stuck".
I feel like I've got something in me that's screaming to get out, but I just can't figure out what it is. Some day's I think it's my inner creativity burning to get out, and if I don't feel like I'm able to think creatively and try different things then I'm a sleep or that I might lose that "potential".
I know you can't see it yet, but I will become what I am.
One of the things that keeps me pumped up throughout my day is the opportunity to solve problems creatively. When the opportunity isn't there I feel like I can barely stay awake. Lately I've been struggling to stay awake. My passion for software development is low right now. My motivation to learn new things, and code is still there... but starting to dwindle away.
I'm working on a good project right now. The architecture is laid out, and big changes are a no no. The client is happy, so any suggested changes are kind of looked at with raised eye brows. I feel like a spec developer who gets handed a 7 page document for a story card that I have to implement. It's mostly just creating new screens and updating stored proc's (so far). (I very much dislike having to spend my time in the land of SQL, I am an object bigot.) So for a new dev, it's a pretty cozy job. For me it's not quite my "sweet spot". (I should tell you that it's only been about a month so far.)
Zzzz... I'm finding it difficult to find new and interesting things to blog about, and it almost seems forced these days. It seems like if I want to keep any sort of artistic creativity alive, I've got to do it on my own time. Not on work time!
I'm not complaining about my job, I'm just yearning for the past. Last year was a tonne of fun, at my old job. There was no one to blame but ourselves when things didn't work out. There was no pointing fingers at the people in another department on another floor. We were the team and there was no other floor. We were a tiny team that got to work on some big problems and in the process we got to flex our creative muscles.
Like any muscle if you don't exercise it regularly, it becomes weak. Right now my creative muscles feel rather weak. Today I sat my butt down to write some code, I had plans on demonstrating some ideas I thought of while riding the bus. But once I got started I found myself getting upset, and frustrated with myself. I can't explain it, I was just mad that I wasn't moving as fast as i wanted to be. My ideas were a tangled mess, and I just couldn't sort it out. I was just annoyed and disappointed with myself. (mO, mO, mO... breathe buddy... breathe!)
One of the reasons I was drawn to software development was because...
I suck at drawing!
I've always enjoyed art, music, and literature. When I found something that allowed me to be creative, and something that I thought I was pretty good at, I held on to it. But lately everything seems so familiar, so comfortable, so boring... Zzzz...
I can only imagine what my team members might think if they read this post. I only wish they could see how we developed software during the last few months of my last job. I remember during my phone interview with ThoughtWorks saying that
"If it's not ThoughtWorks, then I'm not leaving my job. I like the guys I work with and I'm having a lot of fun."
If I liked the guys I worked with and I was having fun, then why did I leave? Let's face it... I tell myself it was for the opportunity to grow and face new challenges. Well, I was growing and facing challenges where I was. In the end I realize it was for the money. I was not in a comfortable place, and instead of pushing through, I returned to the land of familiar. So there's the decision... comfort and familiarity or the "dream".
I admit that there were times when I was discouraged about the progress of my old team, but after now job hopping for a few years I see that it had been one of the greatest and most accelerated learning experiences of my life. I couldn't wait to get out of the Waste Land, and not have to worry about money. Now that I'm out, I see how the time in the waste land was actually a season of preparation, but I don't think I stayed long enough to appreciate it.
I've always wondered how much other people make, financially. Not so much because I'm greedy, but more because I don't want to look foolish when I'm asked "What's your expecting salary range?"
Here it is... the big secret most people seem to hold on to.
- June. 15, 2004 - December. 15, 2006
- Starting Salary: $30, 000.00 CAD/Year
- Ending Salary: $45, 000.00 CAD/Year
Imaging Dynamics Corporation
- December. 18, 2006 - February. 04, 2007
- Starting Salary: $43, 000.00 CAD/Year
- Ending Salary: $43, 000.00 CAD/Year
- February. 12, 2007 - January. 11, 2008
- Starting Salary: $40, 000.00 CAD/Year
- Ending Salary: $43, 000.00 CAD/Year
January. 16, 2008 - Present
- Starting Salary: $55, 000.00 CAD/Year
If anything this should satisfy the person who's been googling "How much money does a software developer make?"
Let's have a quick chat about deferring execution. Take a look at the following test:
When I run this test I get the following output:
It says that the expectation set on the xml gateway was never satisfied. So the call to the method "AllElementsNamed()" with an input parameter with a value of "Book" was not made.
Let's take a look at the implementation that failed this test.
Can you spot the error? Really?
There is no error, the reason this test fails is because of something that C# 2.0 offered for free that very few people actually talk about, and that's deferred execution. The iteration through the loop never occurs because the client of the BooksGateway component never actually begins iterating. In this case the client component is our unit test.
The above line never actually starts to walk the underlying collection therefore causes the expectation violation to occur. Traversal through the collection is put off until the last possible moment necessary. What this also means is that each time the traversal through the collection re-starts it will actually rebuild the internal collection to walk through. This works great for immutable types but can cause a bit of a head ache with types that change through out its lifetime, since new instances are brought back out of persistence. In this case, each time we walk the underlying collection we're actually re-reading the books from an xml file.
If we re-write the test like this...
The test now passes...
It's so important to properly protect your internals of an object, especially collections.
I'm going rant for a bit about why the following piece of code drives me a little nutty!
Why is this so wrong... because it does not keep the ruffians out.
When you expose a collection as a property on a component you expose the innards of the component.
Clients of the component can inject state that was not meant to be there. Does that suck? YUP!
So how do we deal with this? You separate the behavior of add new exclusive members from checking the exclusive members roster. When you're viewing the roster, you're doing so in a read only manner. Clients who are checking out the roster should not have access to sneaking in new exclusive members.
Enter the IEnumerable interface. All collections types implement the IEnumerable interface, it's contract allows consumers to walk a collection but not sneak members in. Or does it? Let's take a look at a revised contract for the Country Club.
Looks alright for now. Let's peak at an implementation or the contract...
IEnumerable doesn't have an add method so I guess clients shouldn't be able to sneak in now right? Let's see what those ruffians come up with...
They did it again, those ruffians are a persistent bunch. They guessed that the roster of members were composed in a collection of type List, and they were right! They snuck in again!
We can keep those ruffians out by building an instance of a type that implements the IEnumerable interface but doesn't hand out our internal collection. The following code does just that:
The above code compiles down to a full blown Enumerable type. Kind of like the code below, you can go check out the IL produced from the above and see what it translates too...
One additional thing that the yield return keyword offers is deferred execution. This concept is getting a lot more attention now in C# 3.0, but it was already available in C#2.0. More on that later...
If the purpose of exposing the IList interface on a type instead of the IEnumerable interface is to leverage the sorting methods then I suggest you factor out a separate interface specifically for traversing a collection and being able to query it. I spoke of a RichEnumerable interface that allowed you to do so, but the new language features in C# 3.0 and specifically the IQueryable interface looks like it might make this much easier to traverse a collection and sort and query it as needed.
New interfaces to check out:
- IGrouping<TKey, TElement>
- ILookup<TKey, TElement>
My personal preference is to drop the properties... In my mind when I see a call to a method, I think this is invoking and action or triggering some sort of behavior, and in this example it is. We're building up a type that we serve back to a client to allow them to traverse our internals without completely handing it out. Anyway's, I wont fight the battle with properties today... but maybe I can save that for a later rant.
CHECK OUT THE CODE!
WebForms is an awkward marriage between a Page Controller and a Template View. In the Web Forms model the Template View (aspx page) inherits from the Page Controller (code behind).
Patterns of Enterprise Application Architecture defines the Page Controller as:
"An object that handles a request for a specific page or action on a web site." - PoEAA
In this example I've separated the Page Controller from the Template View, because... mostly because I was bored and thought this would be a great way to better understand the patterns. So let's get started...
I defined a layer super type for all page controllers defined as :
The IPageController could have very well been called and Page Command because in this implementation I'm not concerned about having separate behaviors for GET and POST method requests. If this example were to evolve I might choose to separate the "Execute()" method into "ProcessGetRequest()" and "ProcessPostRequest()".
The IPageController type inherits IHttpHandler in order to register this page controller with ASP.NET to receive all requests for a particular path. In this case this handler is registered in the web.config for all requests to the "DisplayAllCustomers.aspx" page.
If I wanted to get a little more nitty, gritty I could have specified only GET Http method's are handled by this handler.
Moving on.... The PageController base type for all controllers looks like:
And finally our "DisplayAllCustomersController" component looks like:
And voila all requests to "DisplayAllCustomers.aspx" are handled by the DisplayAllCustomersController which pulls information from the model and fires it off to the template view to be rendered.
The Template View Pattern is defined as:
"Renders information into HTML by embedding markers in an HTML page." - PoEAA
Our template view for "AllCustomers.aspx" looks like this:
This separates the Template view from having any knowledge of the Page Controller. The Page controller has the responsibility of pulling information from the model to pass along to the appropriate view.
All access to the current context and the ASP.NET pipeline has been isolated to the HttpGateway which abstracts the ASP.NET facilities available through a condensed client interface.
Now that I think about it, another step that I could have taken would have to shield the page controllers from having any knowledge of "IHttpHandler", which would have further isolated the ASP.NET infrastructure from the rest of the web presentation layer.
Patterns of Enterprise Application Architecture defines a Gateway as:
"An object that encapsulates access to an external system or resource." - PoEAA
If you haven't already you should go buy and read, then re-read, then re-read "Patterns of Enterprise Application Architecture by Martin Fowler"
Patterns of Enterprise Application Architecture (The Addison-Wesley Signature Series)
by Martin Fowler
Read more about this title...
DOWNLOAD THE CODE
Hackers and Painters: Big Ideas from the Computer Age
by Paul Graham
Read more about this title...
This was not what I expected, but then again I wasn't really sure what I expected.
But I liked it, the first chapter kind of caught me off guard, but some of the analogies and comparisons make a lot of sense. You can tell that Mr. Paul Graham sure is a thinker!
Here are a few excerpts from the book that I found enjoyable:
"Big companies win by sucking less than other big companies."
"You learn to paint mostly by doing it. Ditto for hacking. Most hackers don't learn to hack by taking college courses in programming. They learn by writing programs of their own at age thirteen. Even in college classes, you learn to hack mostly by hacking."
"Maybe it would be good for hackers to act more like painters, and regularly start over from scratch, instead of continuing to work for years on one project, and trying to incorporate all their later ideas as revisions."
"If I could get people to remember just one quote about programming, it would be the one at the beginning of Structure and Interpretation of Computer Programs.
Programs should be written for people to read, and only incidentally for machines to execute."
"When you catch bugs early, you also get fewer compound bugs. Compound bugs are two separate bugs that interact: you trip going downstairs, and when you reach for the handrail it comes off in your hand."
"Mistakes are natural. Instead of treating them as disasters, make them easy to acknowledge and easy to fix. Leonardo more or less invented the sketch, as a way to make drawing bear a greater weight of exploration. Open source software has fewer bugs because it admits the possibility of bugs."
"Of all tyrannies, a tyranny exercised for the good of its victims may be the most oppressive. - C.S. Lewis"
"One of my first drawing teachers told me: if you're bored when you're drawing something, the drawing will look boring."
"Indeed, there is even a saying among painters: 'A painting is never finished. You just stop working on it.'"
There is so much great content in this book that just provokes thought. I highly encourage you to go check it out, it's definitely worth reading and re-reading.
Pragmatic Version Control: Using Subversion (The Pragmatic Starter Kit Series)(2nd Edition)
by Mike Mason
Read more about this title...
If you're an svn or tortoise junkie I recommend that you check out this book. Although most of the information provided in this book can probably be found in the SVN documentation, I much preferred reading this top to bottom. This book walks you through several different project scenarios and shows you how to effectively use svn as your source control system.
The appendices also offers a lot of very helpful information on setup and third party tools.
Some must have tools for svn are:
I love that visual svn takes care of things like moving files, add and deleting it really simplifies the check in process.
Tortoise is a great windows explorer shell that provides a wicked abstraction over the svn shell.
Since reading the book I've found that I'm using tortoise less for checkin's and updates. Here's a couple of simple commands to get you started:
Commit (check in):
If you're going to practice any form of unit testing you need to learn about the different types of tests. I have yet to read XUnit Test Patterns, but I'm sure this will offer a great deal more detail then this post. Also, I'm anxiously awaiting "The Art Of Unit Testing"
Unit tests are blocks of code that exercise very specific areas of a code base to ensure the it is meeting it's responsibility (NOT responsibilities in the plural sense. See Single Responsibility Principal). At it's core its asserting that a very specific result or behavior is met. Unit tests can be broken down into two types.
Black Box Testing (State)
The first is the traditional state based (black box) unit tests. These are unit tests that assert that components of the system exert a behavior that expected from the perspective of a client component. It cares less about the actual implementation of the component and more about the result. These types of tests tend to be easier to refactor and are a great way to start learning about test driven development or unit testing in general. The unit tests give you the confidence to go in to the trenches and make significant changes to the underlying implementation. This allows you to evolve a code base with confidence and precision. (And remember software development is an evolution. Using the same architecture and tools that you did from several years ago could indicate a smell.)
White Box Testing (Interaction)
This type of unit test is more focused on the interaction of components then the result. It's verifying expectations that components are working as expected with it's dependencies under different conditions. It's a way to simulate different environment conditions without actually having to exercise the component in that environment. The canonical example is to mock or stub out an interaction with a database or third party component.
It's called white box testing because it's like you can see clearly through the box to see what's going on inside. It might make more sense to refer to this as glass box testing.
Integration tests are tests that sweep across a system. They exercise the system from top down, to ensure that it is behaving as expected in a production like environment. This is a great place to weed out contracts that have not been implemented, and help to identify different environment scenarios that may need further unit testing. These tests actually hit the third party components and exercise the full system. These tests typically take a little longer depending on the environment conditions such as hitting a database.
There are frameworks available, such as Fit, that allow business analysts to define test criteria that can then exercise the system top down. The problem with some of these frameworks is that they can implicitly allow the BA to start designing how the system is implemented if taken as a literal design spec. I much prefer writing top down tests rather then implementing fit-like fixtures.
One of the books I've read this month is....
Extreme Programming Explained: Embrace Change (2nd Edition) (The XP Series)
by Kent Beck, Cynthia Andres
Read more about this title...
I really enjoyed reading this book. It paints a picture of what an ideal XP team can look like and talks about the principals, practices and values of XP. I'd like to share some excerpts from the book that really stuck out and hand an impact on me.
"If you have six weeks to get a project done, the only thing you can control is your own behavior. Will you get six weeks' worth of work done or less? you can't control others' expectations. You can tell them what you know about the project so their expectations have a chance of matching reality. My terror of deadlines vanished when I learned this lesson. It's not my job to "manage" someone else's expectations. It's their job to manage their own expectations. It's my job to do my best and to communicate clearly."
One of the things I learned about myself is that I hate being late. This isn't a great trait to have in the world of software development. When I'm handed a deadline I become so eager to meet it that in the process of racing to the deadline quality is compromised. I can't control deadlines or others expectations but I can control my own behavior and if I work consistently as hard as I can without letting go of quality.
"I chose practices for XP because they meet both business and personal needs. There are other human needs; such as rest, exercise, and socialization; that don't need to be met in the work environment. Time away from the team gives each individual more energy and perspective to bring back to the team. Limiting work hours allows time for these other human needs and enhances each person's contributions while he is with the team."
It sucks how XP and Agile have become buzzwords in the industry that mean more to the marketing department then to the software developers. I've said it before and I'll say it again...
"You aren't doing Agile. YOU ARE AGILE!"
"Part of the challenge of team software development is balancing the needs of the individual with the needs of the team. The team's needs may meet your own long-term individual goals, so are worth some amount of sacrifice. Always sacrificing your own needs for the team's doesn't work. If I need privacy, I am responsible for find a ways to get my need met in a way that doesn't hurt the team. The magic of great teams is that after the team members develop trust they find that they are free to be more themselves as a result of their work together."
You've got to sacrifice something, regardless of context you're talking about, in order to succeed. What's important is deciding on what you're willing to sacrifice in order to get closer to your end goals. I have found that pushing the people outside of their comfort zone a little bit not only helped me in growing but also the team as a whole. I also learned that it's important to slow down and reflect. The up and down rhythm of an XP team is balanced by the different members of a team, and with trust it's much easier to maintain that balance.
E.G. Team member A might be a hardcore, heads down, must punch out code as efficiently as possible. Team member B may be more of a let's take it a little slower and sit back and think about the problem at hand kind of guy. With trust the two team members will be able to develop a rhythm that keeps the project going at a sustainable pace without sacrificing quality.
"I trust two metrics to measure the health of XP teams. The first is the number of defects found after development. An XP team should have dramatically fewer defects in its first deployment and make rapid progress from there. Some XP teams that have been on the path of improvement for several years see only a handful of defects per year. No defect is acceptable; each is an opportunity for the team to learn and improve."
Test-driven development/design rather then design in your head driven code. The test is a clear statement of truth. It documents the design that would otherwise be locked up in your head and is very black of white about whether or not the subject under test satisfies the test specification or behavior that is expected. If the team is not disciplined even the best of the best XP teams can forget about the principals behind the practices, and stop following the practices. One of the most important things about unit tests is the early feedback. I want to know as soon as possible when a component in the system is not behaving as expected. By waiting for QA to pick out bugs, then log a bug, then assign a developer to look at the bug does not deliver early feedback, I consider this waste! It's a vicious cycle that can be reduced greatly.
"The problem with reviews is that most reviews and raises are based on individual goals and achievements, but XP focuses on team performance. If a programmer spends half of his time pairing with others, how can you evaluate his individual performance? How much incentive does he have to help others if he will be evaluated on individual performance?"
Out of all the chapters in this book I think chapter 3 is my favorite. It's titled "Values, Principles, and Practices", and to me it speaks the loudest of what is XP and why would we want to consider using it as a methodology for building and delivering software.
I highly recommend this book!