Tuesday, December 31, 2013

2013 in Review

The end of the year is a good time to reflect. It gives us a chance to look at how we've grown and how we can make improvements for the following year. It's been a really good year for me. I'm not where I expected to be, but that's okay. I think I'm actually in a better place than I had planned.

Things I've Done
It's been a busy year. I love teaching, and I love watching people learn. I've had a lot of opportunities for that.

Speaking
I spoke at 19 events this year and gave a total of 27 presentations (details here). In addition, I gave my 100th presentation since I started speaking publicly in January 2010 (pretty good for 4 years work).

I managed to make it to 4 states this year (California, Nevada, Arizona, and Utah), and I'm looking to branch out further. I met a ton of great people at the various events. Code Camps are really great because it gives you a chance to spend a full day (or even a couple of days) with people. My network of developers keeps expanding, and I'm planning on continuing that expansion.

Silicon Valley Code Camp - October 2013
Blogging
I didn't write as many technical articles on my blog as I had hoped. Even so, I still managed to publish 63 articles. These are a combination of technical articles, announcements, and book reviews. I've been getting over 3,000 hits a month since April (with a few months over 4,000). This is double what I was getting the previous year.

Here are the top three articles from the year:
And for some reason (still), I'm on the first page of Google results when looking for MVVM Design Pattern. I'm not complaining, just surprised.

Pluralsight Authoring
The unplanned part of the year was creating courses for Pluralsight. I talked to some folks I know that have authored courses for Pluralsight, so I decided to give it a try. It has gone way further than I ever expected. This year I had 5 courses published (details here). I actually produced 6 courses, but the last one hasn't published yet -- maybe later this week.

The response that I've received from people watching my courses has been really good. And it's great to be able to reach thousands of developers through a single medium.

YouTubing
During my 2012 review, I said that I was going to produce some YouTube videos. And I did (well, a few anyway). I currently have 4 videos on my channel. And I would probably have more if I wasn't concentrating on making Pluralsight videos. I'm planning on bulking up my YouTube channel during 2014.

Things I've Learned
I am a constant learner. My preferred method is through books, but I've picked up some interesting things through presentations and podcasts.

I reviewed 8 books this year (details here). These were on various topics, including asynchronous programming, refactoring, test driven development, JavaScript, agile development, user interface design, Windows Store Apps, and ASP.NET MVC.

I didn't quite make it to my goal of 1 book per month. But I was close: I read a 9th book that I didn't review, and I'm halfway through another. We'll see how many books I get through next year.

I've been stretching my ways of thinking. I've started to learn functional programming. I was inspired by attending presentations from some really smart developers (who I'm happy to call friends as well). And I've also been working through a book on Haskell along with the Euler problems.

Whatever the method, I make sure that I'm never standing still. And one of the best ways to learn is to teach. In creating my presentations and videos, I've had to dig into the details of the topics and expand my own knowledge. And I also have developers ask me questions on topics. When I don't know the answer, I roll up my sleeves and find out.

Cool Stuff
I've had some really great opportunities this year, and some really cool stuff has come from it.

I was renewed as a Microsoft MVP for C#. This has given me the chance to attend the Microsoft MVP Summit in Washington (actually, because of a scheduling change, I got to attend 2 summits: one in February and another in November).

At the MVP Summit, I got to talk to MVPs from all over the world (in addition to seeing some really cool NDA stuff). This gave me a chance to expand my network even further, and now I have new friends in Sweden, Australia, and Washington. And I also got to meet up with friends I know from around the country from various Code Camps.

I also got an award for the C# Interfaces course that I did for Pluralsight. Since it was #1 for the month of July, I was given the Crystal Microphone. That was an unexpected surprise. I'm really happy that thousands of people have been able to benefit from the course.

And that really gets to the point of what keeps me going. I'm not looking for recognition (although that's really cool). I like to help other developers. Here are a few of the comments that keep me going. I'm not putting in names because these comments have come through various public and private forums.

Regarding a Clean Code presentation:
I immediately applied incremental refactoring on the project I am working on at work and I am making it a general rule of thumb to look for needed refactoring whenever I touch a source code file for a feature addition or defect fix.
And here's another comment from a presentation:
This session was fantastic. I have been using Lambda's for quite some time but now I know how it functions internally. The example with event handlers was something I never would have thought of. Jeremy, thank you for such a nice presentation.
And here's one more from a Code Camp this year:
Thanks again for another great class (generics). My only regret is that we get you only for an hour. Your explanations are clear and your examples are concise. Your delivery is fun, light, understandable, and conversational, even when your subject matter is anything but. Your classes are one of the highlights of attending [this Code Camp].
More comments can been seen on my SpeakerRate page. And, of course, just drop me a note if you'd like me to come speak at your event.

Things I Didn't Get To
There are some things that I didn't get to. As mentioned earlier, I didn't read as many books as I wanted, and I didn't produce as many videos as I planned. But that's okay.

I'm also still struggling with the Agile Mindset (which I talked about earlier). I still can't solve a Rubik's Cube, and I still find myself limiting myself unnecessarily. But this is a personal growth thing that I'm putting at the top of the list for the coming year. I recognize how I limit myself with the fixed mindset, but I haven't always been able to overcome it. I don't limit other people; I shouldn't limit myself.

I still have a problem with names. I've never been very good with names, and when I speak in different places (often returning to the same event a year later), I have trouble keeping track. I'm pretty good with faces, so I recognize people but can't place the name. I usually tell people, "I need to meet you 5 times before I remember your name." It's not always that bad, but I do get it eventually. I don't know if there's a solution for this, but I'll keep trying.

I'm not the only one with this problem. At the last MVP Summit, I ran into someone who looked familiar. He thought I looked familiar, too. And neither of us could remember where we met before. We had talked at some previous developer event, but we weren't sure which one. The important thing is that we recognized each other, and it let us start up a conversation (and we'll probably both remember when we see each other again).

More To Come
So, it's been an interesting year. At the beginning of the year, I was planning on doing some classroom developer training and working on contract projects. Instead, the classroom training didn't work out, and I ended up producing a couple of courses for Pluralsight and then was asked to produce some more.

2014 should be an exciting year. I'm starting to fill in my speaking calendar (7 events scheduled so far). And I'm looking forward to what's next.

My plan is to find a way to help development teams get better. I'd love to be in a consulting / mentoring position that helps a company implement projects and gets the development team up-to-speed on technologies and processes. These aren't always the latest and greatest; sometimes it is just getting a good handle on the intermediate-level stuff that helps us work efficiently.

I know what I'm good at: making intermediate-to-advanced level topics accessible to developers of all skill levels. I love exploiting that talent, and I love watching people learn.

Move forward. Learn constantly. And above all...

Happy Coding!

Wednesday, December 18, 2013

I Can Write That Method with 1 Line of Code

I've worked with developers who prided themselves with terseness -- writing a function with the absolutely fewest lines of code possible.

Are fewer lines actually better?
I'll stick with my standard answer: "It depends." Unfortunately, many times, fewer lines of code comes at the cost of readability and maintainability -- and as you know, these are very big concerns of mine.

Let's take a look at some code to see if we can find a good balance. The code is taken from "IEnumerable, ISaveable, IDontGetIt: Interfaces in .NET". Now, I have a tendency to be a bit verbose when I'm starting an application. This helps with debugging, especially in the early stages.

Here's how the method stands in the downloaded code (from the RepositoryFactory.cs file). We'll refer to this as the 5-line version:


This method dynamically loads a type from an assembly based on configuration. In this case, it returns a concrete repository class that implements the IPersonRepository interface. Let's do a quick step through this method to see what each line does:
  1. We pull a value out of the configuration file. This value is the assembly-qualified name of the type we want to load.
  2. Based on the assembly-qualified name (from #1), we use the GetType method to generate a CLR Type object.
  3. With a Type object, we can use the Activator class to create an actual instance of that Type. The CreateInstance method returns an "object" that we stick into the "repoInstance" variable.
  4. Since we need something that implements the IPersonRepository interface, we cast our "object" to "IPersonRepository".
  5. Finally, we return the repository, which is an IPersonRepository.
That's a lot of steps, and it's okay if you don't understand exactly what's going on. What we want to focus on is the number of intermediate variables that we have in this method. We actually have 4 variables: repoTypeName, repoType, repoInstance, and repo.

Getting Rid of Intermediate Variables
We can eliminate some of these intermediate variables by inlining them -- basically, we just replace the variable usage with its assignment.

The easiest thing to do is to combine lines 3 and 4 to get rid of the intermediate "repoInstance" variable:


So, we immediately cast the return value from the CreateInstance method to an "IPersonRepository".

But then, do we really need the "repo" variable? All we do is return it in the next line. So, let's combine lines 3 and 4:


This gives us a fairly compact method.

But Why Stop There?
Let's keep going. We can get rid of the "repoTypeName" variable by combining lines 1 and 2:


We just take the "AppSettings" statement and use it directly as a parameter for the "GetType" method. Now we're down to 2 lines of code, and we only have 1 intermediate variable.

Can we get this down to just 1 line?


Of course we can. But it's a little difficult to read since it's stretched out. Let's add a few line breaks:


This is still a single line of code (at least in the source -- what it gets compiled to is a different issue). Now, it's easier to see everything. And the terseness-obsessed developer would be proud.

Is This a Good Idea?
Now that we've whittled things down to 1 line of code, we need to stop and ask ourselves if this is a good idea. Let's look at this code from a couple different perspectives.

Readability
The number one problem I have with the terse code is readability. The degree of readability will depend on the experience of our developers. If our developers have not worked much with reflection, then this code is nearly indecipherable. The advantage with the intermediate variables is that we get some clues as to what is going on in each step based on the variable names (even if we disregard the variable types themselves).

"repoTypeName" lets us know that the value coming out of configuration is the name of a Type. "repoType" lets us know that this is a CLR Type object. "repoInstance" lets us know that we now have an instance of a particular type. And so on...

Maintainability
What if something goes wrong with this code? Let's set a breakpoint:


Uh oh. It doesn't look like this breakpoint is going to do us much good. At least with the intermediate variables, we'll be able to set good breakpoints, and we can see the values that are produced during each step.

Performance
The 1 line version has a small performance benefit. We can see this by looking at the IL that is generated.

Here's the IL for the 1-line version:


And here's the IL for the 5-line version:


If we look at the "meat", we see that the same instructions are run in each version:
  1. call to "get_AppSettings". This gets the AppSettings property from the ConfigurationManager.
  2. ldstr for "RepositoryType". This is the string literal for the setting we want to load.
  3. callvirt to "get_Item(string)". This gets the value that we're looking for from configuration.
  4. call to "GetType". This is the Type.GetType call from our code.
  5. call to "CreateInstance". This is the Activator.CreateInstance call from our code.
  6. isinst for "IPersonRepository". This is the cast to the IPersonRepository interface.
  7. ret. This returns the final value.
The difference between the IL output is in that the 5-line version has the intermediate variables. These are the "stloc" and "ldloc" calls that are interspersed in the code.

So, technically, the 1-line version will be a little faster because it does not deal with these intermediate variables.

But (and this is a BIG BUT), the slowest parts of this method are the reflection calls ("GetType" and "CreateInstance"). These are orders of magnitude slower that the variable code. So, in this case, we really should not worry about the differences in performance. Any slight gain we might get will be overshadowed by the slowness of the reflection code.

Finding the Balance
So, how do we find the balance?

Here's my approach: I start out with the verbose (5-line) method. During the development and early testing process, I want to make sure that the intermediate values are what I expect. So, I like having the extra variables (to put in the Watch window) and extra lines (to add breakpoints).

But once I'm past this, I'd like to refactor things down a bit. My balance point for this method is the 3-line version:


I like this for a couple of reasons. First, I can easily verify (with a breakpoint or watch) that the value I pull out of configuration is what I expect it to be. This is the brittlest part of this method -- configuration is just text in an XML file, and this is very easy to typo or just enter wrong values.

Next, I can verify that the dynamically-loaded assembly is actually available. The "GetType" method uses reflection to load up the specified assembly and get the type information out. If the assembly is not available (or the assembly is available but does not contain the expected type), this step will fail. Again, this is easy to breakpoint, and if there is an exception, it will point right to this line of code.

I'm good with combining the rest of the method into a single line. In my opinion, this is still readable. And we can easily break this into separate lines if we do happen to have problems in this section.

Know Your Team
A big part of this is to understand the skill levels of the people you work with (or the people who will be working with the code). Whenever I'm given a choice between dumbing-down code and making developers better, I will always choose to make the developers better. But sometimes we do not have control over that.

We need to code at a level that the developers understand. So, if I am in an environment where reflection is an unfamiliar topic, then I might just stick with the original 5-line version.

So, know yourself, know your team, and strike the balance that's appropriate for your environment.

Happy Coding!

Sunday, December 15, 2013

I'm Available to Speak in 2014 - Don't Miss Your Chance

I love speaking at developer events, user groups, and code camps. I've presented over 100 sessions in the last 4 years, and it's always a lot of fun.

Back in October, I spoke at the Silicon Valley Code Camp (the largest code camp in the US). My Clean Code session was awesome, if I do say so myself. We had a lot of fun, and there were even people standing in the doorway.


Available in 2014
ineta community speakers program I'm looking to fill in my speaking calendar for 2014. So if you have a user group or developer event you'd like to hear me speak at, just drop me a note. I'm also a member of INETA, so you can send me requests through their website.

If you'd like an idea of where I've spoken, I have a complete list on my website.

I speak on a variety of topics. My goal is to make intermediate and advanced topics understandable by developers of all skill levels.

I'll be glad to speak on topics that I've covered in my Pluralsight courses:
  • C# Interfaces
  • BackgroundWorker Component
  • Design Patterns
  • Dependency Injection
  • Practical Reflection
  • Localization and Globalization - publishing soon
And I've also got lots of topics that have been favorites over the years:
  • Learn to Love Lambdas
  • Get Func-y: Delegates in .NET
  • Clean Code: Homicidal Maniacs Read Code, Too!
  • T, Earl Grey, Hot: Generics in .NET
  • Intro to XAML: Don't Fear the Markup
  • Data Templates and Value Converters in XAML
I'd love to come speak at your event. And if you see me at an event, please be sure to come up and say, "Hi".

Happy Coding!

Saturday, December 14, 2013

Windows 8 Syncing: Cool or Creepy?

I'm the first to admit that I have not had a good time with Windows 8. Probably part of the reason is that I've been using it on a non-touch laptop only. I like many of the features (such as the awesome Task Manager), but I've mostly been fighting with the Modern App side. It seems like the Pictures app comes up when all I want is the desktop Preview application. And the Video app does not recognize the files on my Mac partition, but Media Player on the desktop works fine.

This laptop was the only Windows 8 device that I've had in my collection of devices.

A Little Creepy
It was the only device until recently, that is. A few week ago, I got a Surface 2 tablet, and I must admit that Modern Apps are much better with touch. I've spent much more time learning the apps that I had previously ignored on my laptop. (Disclaimer: I got the Surface 2 at a very steep discount.)

But my first experience was just a little bit creepy. When I was setting up the Surface 2, I logged in with my Microsoft account (which is the same account I use on my laptop). That's when I found that the lock screen on my Surface was the same as the lock screen on my laptop (a picture of my cat, Toby).


That was unexpected (and a little bit creepy). I would not be surprised if settings were stored in the cloud with my Microsoft account, but I didn't expect that a lock screen photo would be automatically uploaded and associated with my account.

But I got over that pretty quickly. My next experience was this last week.

Cool or Creepy?
This past week, I finished up my next Pluralsight course which is about localization. In my demos, I changed the language on my OS so that I could show how that impacted the languages that were used by Internet Explorer.

I ended up leaving the language set to French. This really didn't impact the laptop that I was working on because you need to logout/login for the setting to take effect at the OS level. I didn't really think much more about it.

When I went back to my Surface later in the day, I went to type in a web address and found this:

This is the French AZERTY keyboard (as opposed to the QWERTY keyboard). Changing the language on one machine affected the keyboard layout on a completely different machine. When I took a closer look, the language on some of the icons had changed on my Start screen as well:

Mail

Calendar

I'm not sure I like this too much. I know that these sync settings can be changed, but I like to use the default settings for a while before I make any customization. This default behavior seemed just a little bit creepy -- like a bit of my local computer had leaked into the cloud.

(And to emphasize this: while I was writing this post, I changed the keyboard layout on the Surface to French so that I could take a screenshot, and my laptop keyboard changed to the same layout as I was typing.)

So I could see how this could be really cool or really creepy. If I had multiple PCs, it would be nice that they all had the same settings, layout, experience, etc. But with the PC and tablet, I find that I want different settings on each device.

A Good Upgrade Experience
Since I just finished a Pluralsight course, I figured it was a good time to upgrade to Windows 8.1 (before I start my next course). The upgrade experience was painless, just a bit slow. Fortunately, I set this to install when I didn't need my computer.

As a side note: The language and region settings screen is completely different from Windows 8; I'm glad that I finished up my course with the old "dialog" screens as opposed to the new "Modern" screens. It was much easier to show the dialogs on the video.

I've been fighting with parts of Windows 8 for a while. Having the Surface as a touch device has helped me get used to the Modern app paradigm, but it's still not a great experience on a non-touch device. I'm sure that I'll find the balance somewhere.

Happy Coding!