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!

Friday, November 22, 2013

New Pluralsight Course: Practical Reflection in .NET

My latest course is now available on Pluralsight: Practical Reflection in .NET.

Practical Reflection in .NET
Reflection is an extremely powerful feature of .NET. But there is a big difference between what we can do and what we should do. We'll take a quick look at what reflection is capable of and then narrow our focus to practical uses: balancing flexibility, safety, and performance.
When I first saw reflection, I thought it was really cool (and a bit scary, too). And at the time, I didn't think that I would ever use it in my own applications. It really looked like a tool for people who build developer tools or have an extremely specialized situation. But I was wrong.

Reflection is useful for everyday developers, too. Now, it's true that I only use a very small subset of features that reflection offers, but that's probably a good thing. Reflection has some drawbacks -- primarily speed and safety, so we probably want to limit how much we use anyway.

Real World Reflection
I showed a bit of reflection in the C# Interfaces course. In the Dynamic Loading section, we loaded an assembly based on configuration information, and then created an instance of a type. This is reflection. I skipped over the details of reflection since we were focusing on interfaces.

In the latest course, we take a closer look at the reflection parts of this sample so that we can really understand what's going on. This includes looking at the assembly-qualified names that we used in the configuration file, as well as the Type class that loads a type based on that, and the Activator class that we used to create an instance of that type.

Adding Flexibility
Another example shows how we can dynamically load assemblies from the file system and pick out the types that we want. Why would we ever want to do this? Well, the scenario is a rules engine that allows our clients to create their own custom business rules by simply building classes that implement a particular interface. Then they can drop the resulting assemblies into a particular folder that the application picks up automatically. This allows for greater flexibility of our application.

And this technique can be expanded beyond this scenario as well.

Uh-Oh
The last section of the course covers that scarier parts of reflection. It turns out that nothing in our assemblies is secret. If someone has the assembly, he can look at all of our variables, strings, classes, and functions -- even if they are marked "private". But we shouldn't panic about this, we just need to keep it in mind when we're writing our applications.

There are several techniques that we can use to make sure that our confidential information stays confidential. If you want to learn more about these techniques, be sure to watch the course ;-)

Wrap Up
Pluralsight offers tons of great training courses, and they've been expanding immensely over the last year. Pluralsight offers a 10-day free trial that gives you 200 minutes to use however you like. I've also got some free trials that offer 1 week of unlimited usage. So, drop me an email if you're interested.

This is my 5th published course, and I'm working hard on my next one. I've had a lot of fun producing these, and I love to hear from people who have found them valuable (and also from people who have some suggestions -- I'm always trying to make things better).

Happy Coding!

Sunday, November 3, 2013

November 2013 Speaking Engagement: Desert Code Camp

Desert Code Camp in Chandler, AZ is less than a week away. This will be my 6th time out there, and it is always a lot of fun.

If you can make the time, be sure to come out. There are a ton of great sessions (including mine), lots of developers to talk to, and some really good food if you can stick around for the dinner (and there's beer, too).

Saturday, November 9, 2013
Desert Code Camp
Chandler, AZ
http://nov2013.desertcodecamp.com/

I'll be presenting 3 sessions.

Learn to Love Lambdas
I really like talking about lambda expressions. It's one of the first sessions that I ever did. This time around, the sample application and presentation have been updated based on giving this presentation 15 times.
Desert Code Camp session link

Clean Code: Homicidal Maniacs Read Code, Too!
I'm still having a lot of fun with this session. At the Silicon Valley Code Camp, I had folks standing in the doorway to watch (thanks, "doorway developers"). We can all make our code more readable, and we'll look at some really easy ways of doing that.
Desert Code Camp session link

Abstract Art: Using Patterns to Solve Real Problems
This is a brand new session. Getting abstraction right is tricky. If we have too little abstraction, then our code is difficult to read and maintain. If we have too much abstraction, then our code is difficult to read and maintain. We'll help you identify which type of programmer you are, and how to overcome your natural reactions. And of course, we'll have lots of fun as well.
Desert Code Camp session link

I've got some really cheesy free giveaways, so be sure to come to at least one of my sessions if you're in the area. And if you can't make it to my sessions, be sure to stop by at some point to say hi.

Happy Coding!

Tuesday, October 29, 2013

Functional Practice: Euler Problem #1

I've learned about Euler problems quite a while back. If you're not familiar with them, you can check out Project Euler.

These are very mathematically focused problems, and I was thinking about using them as practice problems for C#. Many people have done that; here's one example: http://www.mathblog.dk/project-euler-solutions/.

When I was looking at the problems, though, I always felt that my C# solutions would be a bit of a mess -- lots of if/else, while, switch, and so on. The solution is not functional or elegant (which always makes me think of this song).

But these seem like a great place to start using functional programming. Since I'm learning functional programming with Haskell, that's the language I'll use for my solutions.

Now, I'm not going to blog about all of the Euler problems (there are a lot of solutions out there). I'm just going to go over my thinking to solve the first problem. This will show how learning about functional programming will let you start to think a bit differently if you come from the OO world.

Euler Problem #1
Here's the first problem:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
This doesn't sound that hard. We'll start by trying to replicate the sample: the natural numbers below 10.

Thinking Functionally
What I found myself doing immediately was breaking this problem down into different parts. We need the natural numbers below a certain value. We need to find the ones that are multiples of 3. We need to find the ones that are multiples of 5. We need to sum things up.

This is a great place to use a list in Haskell.

First, let's get a list of all the natural numbers less than 10. We'll use a list comprehension with a range:
[x | x <- [1..9]]
And here's the output
[1,2,3,4,5,6,7,8,9]
That's a good start.  Now we need to filter things a bit. Let's add the modulo function (mod) to get the values evenly divisible by 3:
[x | x <- [1..9], mod x 3 == 0]
 The "mod" function takes 2 parameters. This may look a little strange, so we'll change this to use infix notation by using a backtick around the function name:
[x | x <- [1..9], x `mod` 3 == 0]
This seems a little less strange. And here's the output:
[3,6,9]
And since we want multiples of 5 along with multiples of 3, we can "or" these together with "||". Here's how that looks:
[x | x <- [1..9], x `mod` 3 == 0 || x `mod` 5 == 0]
And here's the output:
[3,5,6,9]
Success! This matches the list from the sample. Now we just have to sum these numbers. Fortunately, we can just pass a list to the "sum" function.
sum [x | x <- [1..9], x `mod` 3 == 0 || x `mod` 5 == 0]
And the output:
23
This matches the sample case. Now we just need to swap out the "below 10" for "below 1000":
sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]
And the answer:
233168
Note: I've verified this is correct by looking at the answer to Euler Problem #1.

Making a Reusable Function
The last thing that I want to do is create a reusable function. (I'm not really sure what use I would have for this, but anyway...) So, let's parameterize this with the "below this number" value (ignore any line breaks you might see).
euler1 belowThis = sum [x | x <- [1..(belowThis-1)], x `mod` 3 == 0 || x `mod` 5 == 0]
Basically, we created a named function "euler1" with a parameter for our "belowThis" number. Since ranges are inclusive, we subtract one from the value before creating our original list.

Now we can use this function with the sample:
euler1 10
23
Or with the target value:
euler1 1000
233168
That's pretty cool.

To create this function, we just started with the inside and worked our way out. And this is a big difference between thinking functionally and thinking procedurally. If I were to try this with C#, I would probably just "brute force" it. You can see an example of that here: http://www.mathblog.dk/project-euler-problem-1/.

But instead, we have something functional and elegant. And also a good way to stretch a bit to learn functional programming. And I'm already starting to see how I can use these techniques to make my everyday programming (in C#) much better.

I'll leave the rest of the Euler Problems as an exercise for the reader.

Happy Coding!

Monday, October 28, 2013

Shameless Promotion

Three of my Pluralsight courses are currently in the Top 100 as of 10/28/2013 (subject to change):


(I guess there's not much love for the BackgroundWorker Component.) You can see all of my courses in one spot on my author page.

I have more courses coming. If you have topics you'd like to see me cover, feel free to leave a comment. As mentioned before, the topics I select are based on several factors including (1) whether I know anything about the topic (this one is kind of important) and (2) whether Pluralsight already has a course covering the topic.

Pluralsight has over 1,000 courses with a ton of great content. Check the Course Library for some really good resources.

Happy Coding!

Tuesday, October 22, 2013

Unblocking Downloaded Visual Studio Projects

As a developer, I download sample projects quite frequently. Usually, when opening these projects, Visual Studio will give the following warning:


Now, we can simply click the "OK" button here. But there may be other problems. This is especially true if the solution includes compiled DLLs. These files may be blocked by Windows since they were downloaded from the internet.

Unblocking Files
The easiest solution is to unblock the files before opening the solution in Visual Studio. Here are the steps:
  1. Locate the original ZIP file that you downloaded from the internet.
  2. Right-click on the ZIP file and choose "Properties".
  3. At the bottom, you may see a "Security" section that says "This file came from another computer and might be blocked to help protect this computer."

  4. Click the "Unblock" button.
  5. Unzip the files and open the solution in Visual Studio.
  6. Before opening any specific project, go to the "Build" menu item and select "Rebuild Solution".
This usually takes care of the problems. (And, of course, only do this with files that come from a trustworthy source.)

Happy Coding!

Monday, October 21, 2013

New Pluralsight Course: Dependency Injection On-Ramp

My latest course is now available on Pluralsight: Dependency Injection On-Ramp.

Dependency Injection On-Ramp
What is Dependency Injection? The answers to the question seem to cause more confusion than help. This course will get us started on the road to understanding. We'll take an example-based approach to see the problems caused by tightly-coupled code. We'll add Dependency Injection to trade that tight-coupling for loose-coupling. And that loose-coupling makes our applications much easier to extend, maintain, and test. Finally, we'll see how Dependency Injection Containers can provide benefits that would be difficult to implement ourselves. This just scratches the surface. Once we're done, we'll be ready to start our journey on the Dependency Injection superhighway.
I've really enjoyed presenting on Dependency Injection over the last year -- I've given my live presentation 12 times since October 2012.

One of the reasons I really like this topic is because I've found it extremely useful in my own development. It took me a while to get the hang of it and to see the usefulness. But once it clicked (the "a-ha" moment (no, not that "a-ha" moment (but that's a good one, too (I miss the '80s)))), it's hard to imagine building complex applications any other way.

My goal is to give a short-cut to that "a-ha" moment. We can't cover everything we need to know about Dependency Injection in such a short time, but we can get a good understanding of the basic concepts and, more importantly, see real code that shows why we may want to use it in our own applications.

This may be my best course yet. Check it out and let me know what you think.

Happy Coding!

Saturday, October 19, 2013

A Foo Bar Example I Actually Like

I really, really dislike "foo bar" examples. You can read about my worst foo bar experience here: Session Spotlight: IEnumerable, ISaveable, IDontGetIt.

There's 2 primary reason for this. First, I like real-world examples -- something that I can hold on to. "Foo" doesn't mean anything (that's why it's used), so I have a difficult time relating. The second reason is that "foo bar" makes me think of FUBAR (which may actually be appropriate).

Higher Order Functions
As recently noted, I'm learning functional programming with Haskell. It is a different way of thinking, and I'm starting to get the hang of it. I'm reading about higher order functions right now.

A higher order function is a function that takes another function as a parameter. To relate this to the C# world, this is similar to passing a predicate/delegate/lambda as a parameter to a method (like a LINQ method such as "Where"). But this seems more natural in a functional language.

Here's the function that we need: zipWith':


The scary thing is that I actually understand this. It uses a combination of a higher order function, recursion, pattern matching, and list heads/tails.

Rather than explain this line by line, let's look at an example of using this method:


This shows a call to zipWith that has the "+" function as the first parameter, then we have 2 lists of integers. This method will apply the function to the items of each list. So, it will add ("+") the first item of the first list ("1") to the first item of the second list ("4"). Then it will add the second items of each list, and so on.

Here's the output:


This is a list consisting of 1+4, 2+5, and 3+6. The 7 at the end of the second list is ignored since there is no corresponding item in the first list.

Foo Bar Baz
So, you've made it this far. Here's the foo bar example:


This has a different function: ++. This will concatenate 2 lists together. Since strings are lists of characters, this will concatenate the strings from the first list with the strings from the second list.

Here's the output:



The sin of using a foo bar example has been forgiven.

Happy Coding!

Thursday, October 17, 2013

How Do I Change Someone Else's Code?

I had an interesting question come up at my Clean Code session at Silicon Valley Code Camp:
How do I change someone else's code?
This question came up as we were talking about refactoring code to improve the readability. And the question was not coming from the technical standpoint, it was coming from the interpersonal standpoint. So, the question could really be stated several different ways:
How do I deal with a developer who is possessive about the changes made to "his" (or "her") code?
How do I tell a developer that his/her code could be more readable?
Let's start with the first question.

Code Ownership
If people are possessive of "their" code in the codebase, this is a sign of a larger issue.

Note: I'm approaching this from a standpoint of developers on a team working for a company just so we have an idea of the environment. But this applies to other types of teams as well.

Our focus really should be on the business -- how the applications we build move the business forward. And the most productive environments I've worked in have this mindset.

In the agile world (and I'm reluctant to use that word since a lot of people who are "Agile" really aren't), everyone on the team is responsible for the code. If someone sees a problem in an application, he is empowered to fix it (or alert someone about it if he is not capable of fixing it himself) -- and arguably, he would be irresponsible to not do anything about it.

So, if you find yourself in a situation where you can't touch a certain module because "that's Jim's code", it might be time to bring in someone to help with the dynamics of the team.

We don't always have control over the team, but we do have control over ourselves. If you find that you're offended that someone changed "your" code, then it's time to take a step back and re-evaluate your own attitude.

Controlling the Ego
Developers are known for having large egos. This really isn't surprising because at its heart, development is more of a creative process than a technical process. The last thing that an artist wants to hear is that you think his painting is ugly. Developers generally react the same way.

But we need to take a step back and look at what we're really doing: we are building tools that propel a business forward. And we don't even own the code we write (from a legal standpoint), the company owns it. This means that the company can do whatever it wants with the code, including rewriting it, breaking it, using it incorrectly, or even never using it at all. So, we cannot get personally attached to any particular function that we create.

I won't say that this is an easy thing to do as a developer. I put a lot of thought and effort into the software that I write. When I see that it is not being used or being used improperly, it really annoys me. But then I take a step back. In my experience, there is very little benefit that comes out getting worked up over these things. I voice my opinion and then let it go (sometimes more successfully than others).

Learn from Other Developers
The same holds true if another developer makes changes to code that you originally wrote. Instead of having a kneejerk reaction, understand that the other developer is not calling your painting ugly. He (hopefully) has the same goal that we all do, to propel the business forward.

So, stop and look at the changes that were made. If you think they are good, learn from them. If you think they are bad, talk to the other developer. Communication goes a very long way in the development world. We don't always approach problems the same way (actually, we probably never approach problems the same way). It's good to understand what someone else is thinking. I've used this several times as a learning experience. And sometimes by working together, we come up with something that neither one would have come up with separately.

It's All in the Approach
So, now let's deal with the second question: How do I tell a developer that his/her code could be more readable?

A great way to approach this is to ask the developer to explain the code. "Hey, Jim, I'm having a little trouble understanding this block of code. Could you help me out?"

If he asks why you're looking at "his" code, tell him that you're just trying to get a better understanding of the system overall.

This may or may not work. It all depends on the other developer. We don't have any control over how other developers react. Just remember to keep your own reactions in check.

If he does explain the code, then you can offer some suggestions to make it more clear to someone just walking up to the code for the first time. Hopefully, you'll be able to work together on making the code better.

Sometimes We're Stuck
If we are part of a dysfunctional development team, sometimes there's nothing we can directly do about it.

But there is a big difference between being *on* a dysfunctional team and being *part of* a dysfunctional team. It is very easy to be overwhelmed by the things going on around you and let them affect you. I've had that experience. I let the problems of a team I was working with get the better of me, and it affected my attitude. I was lucky enough to have someone point this out to me, so I was able to readjust how I was reacting to things.

Attitude is Infectious
Just like a negative attitude is infectious, so is a positive attitude. We can't control others, but we can control ourselves. I've found that if I take a certain attitude toward development (focusing on the business, checking my ego, constant learning), it rubs off on other members of the team.

We *can* change the attitudes on our team. It starts with us re-evaluating our own attitudes. From there, we set a good example, pump out some excellent code, and focus on the goal. Others will want to follow. (And if that doesn't work, polish up the resume. If this is your approach to development, I want to work with you.)

Happy Coding!

Wednesday, October 16, 2013

Functional Programming with Haskell

So, I've been dancing around learning a functional language for a while. And although most of the people I know would like me to learn F#, I've decided to start with Haskell (sorry, Mathias).

So, I started reading Learn You a Haskell for Great Good! by Miran Lipovača (Amazon link).

Why Functional Programming?
I've heard from several folks that it's a really good idea to try to learn one new programming language a year. The goal isn't to make the language our "main" language but just to become competent with it and understand how it works.

A further recommendation is to learn a language that uses a different paradigm. For example, if we are C# developers (an imperative OO language), then learning Java (another imperative OO language) won't do us that much good. But if we pick up a functional language, it will force us to start thinking about problems differently.

And the programming techniques that we learn can help us in our "main" language. C# started as an OO language, but it's evolved into an all-purpose language and has many functional elements (delegates, lambdas, LINQ, etc.). When learning these functional elements, we don't usually approach them from a purely functional standpoint.

My hope is that by learning a purely functional language, I'll have a better grasp on the idioms and techniques of functional programming, and that will make me more effective as a C# developer.

Why Haskell?
Why did I choose Haskell over F#? Well, there are 2 reasons.

First, I already had the Haskell book. It's been in my heap for a long time (according to Amazon, I've had this book since April 2011).

Second, I wanted to break away from the .NET framework. I am concerned that if I started with F#, I would get wrapped up in things like "What IL does this generate?" and "How does this F# library integrate with a C# application?" As a first step, I want to focus on the functional paradigms.

I fully expect that I will take these learnings into the F# world. And after reading just a couple of chapters, I've picked up a few good things. I got a good head start at the Silicon Valley Code Camp by attending Mathias Brandewinder's "F# for the C# Developer" (Code Camp link). And the concepts of tuples and implicit typing now make a lot of sense.

More to Come
Stay tuned for more functional stuff. I'm already starting to see the coolness around immutability and "no side effects." And the idea that a function *must* return something seems strange to a C# developer at first, but it makes total sense when functions are the primary objects that we're dealing with. I'm looking forward to diving deeper into the concepts of composing functions. And near the end of the book, there are chapters on monoids and monads. That should be interesting since I have no idea what those are.

I'm looking forward to stretching the way that I think about programming.

Happy Coding!

Tuesday, October 8, 2013

Fixed Mindset vs. Agile Mindset

I was impacted pretty sharply by a podcast that I listened to a couple weeks ago: Hanselminutes #389 - The Agile Mindset with Linda Rising. If you haven't heard this conversation, you should go listen to it right now.

Based on this, I went out and watched a keynote given by Linda Rising (in the links of the podcast): The Power of the Agile Mindset.

This got me thinking about my attitudes toward others and toward myself.

The Short Version
The short version (if you don't want to listen to these talks) is that there are two basic mindsets: a fixed mindset and a growth (or agile) mindset.

The fixed mindset says that we have a specific potential that we can live up to. If we succeed at something, it's because we are smart or are meeting our potential. If we fail at something, maybe we just aren't smart enough. But the general idea is that everyone can be grouped by what he/she can be good at and not good at. Someone can learn something new, but there's a ceiling at which he/she will stop getting better. One very telling result is that people with a fixed mindset will often meet failure with helplessness -- "I failed; I guess I'm just not good enough."

The growth/agile mindset says that we are all capable of constantly learning. If we succeed at something, it's because we worked at it. If we fail at something, that's okay. We can use it as a learning experience and do better next time. With this mindset, we continually improve at whatever we work at.

Now there are limits. Not everyone can be an Einstein or a Bach or a Michael Jordan. But we can learn to be competent (and possibly excel) at whatever we set our minds to. And there isn't a "hard cap" on what we can learn. We can keep getting better even if it's just in small steps.

This is a really bad summary, so go and click on the links at the top of the article to find out from the expert.

Mindset in Business
In the Hanselmintues podcast, there was a discussion of how certain companies have the fixed mindset and others have the agile mindset. I've seen this first-hand (although I never thought about it this way).

I was at a company that had two distinct teams and two distinct approaches to software development. I was (thankfully) on the team with the agile mindset. We were constantly learning from our previous projects, looking for things that we could do better, and helping each other grow. From the way that we treated each other, it was obvious that our team embraced the agile mindset. We saw potential growth in each one of our team members.

The other team had a fixed mindset. This team was always looking for the tool or process that would make their development idiot-proof. This really bothered me. If I was in charge of that team, I would have focused on how to make the developers better -- to find out where the gaps were and bring everyone up a level. But it seemed to me (as an outside observer) that the management team had given up on improving the developers. The mindset was that the developers were "only so good" -- they had reached their potential as developers.

I have always treated other developers with an agile mindset. That's not really surprising since I spend so much time helping other developers get better. If I didn't believe this, then I wouldn't spend so much time speaking and writing and teaching.

Mindset in Myself
I did find something surprising about myself though. Even though I treat others with the agile mindset (the potential to continuously get better), I treat myself with the fixed mindset.

I've never really struggled with something. When I was growing up, I was told that I was smart. I did well in school. I did well in sports. I did put a lot of work in. For example, I practiced basketball a lot when I was in high school. But I never struggled with it. I was never overcoming challenges, I was simply putting in time.

There are things that I consider myself to be "not good at." These are things that I have not put much effort into. Music is one of these things. I play the keyboard and guitar very basically. I don't play a lot. And I considered myself to "not be a natural" when it comes to music. Maybe I was missing a trait that would allow me to play really well. And I never really put in a lot of time to learn.

So, I've managed to put limits on myself in some areas but not others. For example, in development, I'm constantly learning, usually through books (that's how I learn best). When I'm speaking, I elicit feedback from the people who attend, and I try to incorporate their suggestions. When I completely blow a presentation (which has happened a couple of times), I try to figure out what I did wrong so that it doesn't happen again. I think that this makes me a better presenter as time goes on.

The Rubik's Cube
I grew up in the era of the Rubik's Cube. If you've never seen one, here you go:


The goal is to get the each side to be a solid color (at the same time). I was never good at this. There were 2 ways that I could solve it: (1) follow step-by-step directions, or (2) take it apart. When I followed the directions, I wasn't really learning the concepts behind the cube, just following the numbers.

Since then, I've been content to think "my brain doesn't work that way." I never thought that I could learn to solve it.

This came up a few weeks back. I was standing around talking with a group of devs after a user group. Someone picked up a Rubik's Cube on a desk and proceeded to solve it in a few minutes. I admitted that I'm not capable (and I don't think I ever would be).

Guitar Hero
So, let's go the other way. Many years back, I saw Guitar Hero (the video game) and decided that it looked like fun. I even went out and bought a PlayStation 2 so I could play it.

The first time I tried to play, I was awful. The beginner level only uses 3 buttons (out of 5) and goes very slowly. But still, I was awful. After playing for a while, I simply turned if off and thought "well, that was a waste of money."

But for some reason I went back to it. And over the years I got really good (which isn't that hard if you have free time). I got to the point where I could not play the beginner level anymore because it went too slowly. And I continued to play through many more iterations of the game (I think I have almost all of them). And when I started a new version, I would start on the "Hard" level.

I even used this to my advantage. The first time I spoke publicly was at the So Cal Code Camp in Orange County in January 2010. I was nervous as heck, and I wasn't sure that I could actually go through with the presentations that I had planned. There was a speaker dinner the night before at Dave and Buster's, and I ended up at the Guitar Hero game there. I played a bit, did very well, and other people commented on it. There was even a teenager who asked to play head-to-head with me. That boosted my confidence -- I could perform well in public. And I was successful in my presentations the next day.

My Challenge
Many times I find myself getting frustrated at things or thinking "I'm not good enough." There's no logical reason for this based on my past performance, but that fixed mindset keeps creeping back in.

So, I'm challenging myself. I will learn how to solve a Rubik's Cube. I know that doesn't sound like a very big challenge, but it really is. In order to solve the cube consistently, I will need to break out of the mindset that says "my brain doesn't work that way."

So, the next time you see me at an event, ask me how I'm doing with that. Hopefully, I'll pull a cube out of my pocket and solve it right in front of you.

The fixed mindset vs. the agile mindset is not simply about how we treat other people. It's also about how we treat ourselves. Keep learning and keep growing.

Happy Coding!

Book Review: Designing with the Mind in Mind

User interaction design is one of those things that I'm fairly decent at, but I don't excel at it (yet). In that vein, I've read several design books over the last few years including Don't Make Me Think (Steve Krug), Universal Principles of Design (Lidwell, Holden, and Butler), and, one of my favorites, The Design of Everyday Things (Donald A. Norman). For more on these books, you can refer to the UX Design section of my Bookshelf.

To continue my exploration, I recently read Designing with the Mind in Mind: Simple Guide to Understanding User Interface Design Rules by Jeff Johnson (Amazon Link). Like most of the design books that I have, this one is fairly short (under 200 pages), but it is packed with lots of useful information.

This book is primarily about how humans perceive the world, and how we can use that to our advantage when building our user interfaces. It also uses studies about how memory, recognition, and process affect how we interact with the world.

Chapters
The chapter titles themselves are a list of how humans work:

  1. We Perceive What We Expect
  2. Our Vision is Optimized to See Structure
  3. We Seek and Use Visual Structure
  4. Reading is Unnatural
  5. Our Color Vision is Limited
  6. Our Peripheral Vision is Poor
  7. Our Attention is Limited; Our Memory is Imperfect
  8. Limits on Attention Shape Thought and Action
  9. Recognition is Easy; Recall is Hard
  10. Learning from Experience and Performing Learned Actions are Easy;
    Problem Solving and Calculation are Hard
  11. Many Factors Affect Learning
  12. We Have Time Requirements

In each chapter, Johnson gives specific examples of these traits and how our application design can play on the strengths and weaknesses of each.  Here are few that stuck out to me.

Gestalt Principles
Chapter 2 ("Our Vision is Optimized to See Structure") covers the Gestalt principles of human perception. Apparently, these are fairly widely-known (and I've recognized some of them in my own design work), but this is the first time I've seen them delineated.

For example, the Proximity principle states that relative distances between objects determines how we group them mentally. Look at the following picture.


We tend to see the blue stars as 3 rows, and we tend to see the orange stars as being in 3 columns. We can use this in our UI design to make sure that things that go together are actually perceived as belonging together.

The Continuity principles states that we often perceive things as continuous even if it's broken in the middle. As an example, we'll consider a slider bar (this one is from Windows Media Player).


The volume slider is made up of 3 parts: the blue line on the left, the circle in the middle, and the grey line on the right. But the tendency of our brain is to see a single line with the circle on top of it. Now, whoever designed this particular slider added something to enhance this perception. Notice that the circle has a dark line going through the middle of it. This gives the added perception that the circle is semi-transparent, and we are seeing the continuous line underneath it.

The other Gestalt principles (similarity, closure, symmetry, figure/ground, and common fate) all have similar examples.

These principles seem obvious once you see them stated. But unfortunately, this chapter also contains several examples of applications that do not follow these principles, which leads to difficulty in using them.

How Fast Does Our Brain Work?
Another chapter that I found especially interesting was Chapter 12 ("We Have Time Requirements"). This takes a look at how long it takes the brain to perceive things, how long it takes us to process information, how long our attention is really dedicated to a single task, and so forth.

The chapter contains an interesting list of perceptual and cognitive functions and the duration of each. This includes things like the shortest gap that we can detect in sound (1 millisecond), minimum noticeable lag in ink as someone draws with a stylus (10 milliseconds), the time required for a skilled reader's brain to comprehend a printed word (150 milliseconds), duration of unbroken attention to a single task / "unit task" (6-30 seconds), and time to choose a lifetime career (20 years).

The most interesting part has to do with the time of a "unit task". This is covered quite extensively. Unit tasks are small (such as filling in login information). We will dedicate 6-30 seconds to a task before our brain jumps away. Now, it may jump right back, or it may get distracted by something else. Our goal as application designers is to try to keep our tasks within this time window.

For example, rather than having someone fill out an entire tax form in one big scrolling screen, we should break this process down into smaller tasks in a wizard-type interface. This allows us to concentrate on one small task at a time. When we click "Next" our brain may wander (or take a quick breather), but we're right back to concentration on the next task.

Wrap Up
We looked at just 2 of the chapters here. But I found each chapter interesting. I learned quite a bit about how the human mind works. And more specifically, how I can apply that knowledge to how I design my applications.

I know that my personal web site is in pretty bad shape right now (especially the home page). But this book helped me pinpoint several specific problems. I've been planning on updating things for a while, but this will give me the push to do it in the (hopefully) not-too-distant future.

Designing with the Mind in Mind is a great book for anyone wanting to better understand their users (and how their brains work). Once we understand our users, we are better prepared to create excellent experiences for them in our software.

Happy Coding!

Thursday, October 3, 2013

MVP Award 2013

Microsoft has honored me by renewing my MVP Award for Visual C# for a second year. I got my 2013 "disk" today:


If you're unfamiliar with the MVP program, Microsoft recognizes those people who are active in the development community (or, more broadly, the technical community -- the program covers much more than just the developer tools).

I've been recognized for my speaking engagements and articles -- helping developers expand their knowledge in the world of .NET. I consider this to be a great honor, and I've really enjoyed meeting other MVPs from around the world.

But even without this type of recognition, I would continue to do what I do. I love helping other developers. And what really keeps me going is watching people learn and knowing that I've made someone's job a little bit easier.

When you learn something useful, be sure to pass it on.

Happy Coding!

Thursday, September 26, 2013

Silicon Valley Code Camp - October 2013

Silicon Valley Code Camp is a little over a week away! If you're in the Bay Area, be sure to carve out some time to stop by. Last year almost 2,500 people attended, and this year looks to be even bigger.

There are tones of interesting people to meet, some famous people speaking, and a HUGE assortment of sessions to choose from on all different development topics. If you have anything to do with technology, there's probably something to interest you.

Silicon Valley Code Camp
October 5 & 6, 2013
http://www.siliconvalley-codecamp.com/

And if you're there, be sure to hunt me down (if you can find me in the crowd). And stop in to one of my sessions:

Clean Code: Homicidal Maniacs Read Code, Too
Session Description
Saturday, October 5th at 1:45 p.m.

Dependency Injection: A Practical Introduction
Session Description
Saturday, October 5th at 3:30 p.m.

I'm looking forward to seeing a bunch of my old friends and making new ones. See you there!

Happy Coding!

New Pluralsight Course: Design Patterns On-Ramp

My latest course is now available on Pluralight: Design Patterns On-Ramp.

Design Patterns On-Ramp
You already use Design Patterns but probably don't know it. In this course, we'll take a look at several everyday programming scenarios that are implementations of Design Patterns. Once we start to recognize patterns, we're well on our way to using them effectively. Our goals are to get comfortable with the basic concepts, to see how they are useful, and to discover that design patterns are relevant to all programmers, not just architects and system designers. When we're done, you'll be ready to explore the rich and wonderful world of Design Patterns.
This is a great way to get started with Design Patterns. Plus, you get to learn a little about me, including my video game habits and the kind of music I listen to.

I'm currently working on my next course: Dependency Injection On-Ramp. And I'm still looking for topics for future courses.

Enjoy the new course, and I'd love to hear your feedback.

Happy Coding!

Monday, September 23, 2013

Applying the Interface Segregation Principle to a Repository

Repositories appear in many of my example applications. This is because it's a fairly easy problem to describe and understand. Last month, we took a look at whether we really need this in our applications: Do I Really Need a Repository?

My friend, Jim, replied with the following:
This is a great point, so let's take a closer look at this.

A Generic Repository
Before looking at the Interface Segregation Principle, let's update the existing interface to use generic parameters.  Here's our original interface from the last article:


This is an example of a CRUD Repository -- where CRUD stands for Create, Read, Update, and Delete. (Another common repository type is CQRS -- Command Query Responsibility Separation -- we'll talk about this in a bit.)

If we add generic parameters to this, we can get this interface to work with more than just Person objects. Everywhere we see "Person", we'll replace with "T", and everywhere we see "string" (which is the type for the primary key), we'll replace with "TKey". Then we just update the method names so that they make sense for any types.

Here's our updated generic repository interface:


This interface will work with any types we have (Customers, Orders, Products, etc.) as well as whatever key types we have (int, string, GUID, etc.).

Now let's look at how we can apply the Interface Segregation Principle to this.

The Interface Segregation Principle
The Interface Segregation Principle is one of the S.O.L.I.D. principles of Object-Oriented Design (specifically, the "I"). Here's what the principle states:
Clients should not be forced to depend upon methods that they do not use. Interfaces belong to clients, not to hierarchies.
What this means is that we should make our interfaces granular so that we only get the methods that we actually need.

When this repository interface is used in the sample applications, we generally only use the "Read" portions. Because of this, we really should not saddle our client object with the update methods (Create, Update, Delete) since it does not use them.

To apply the Interface Segregation Principle, we just need to segregate out the Read operations into a different interface.

Here's what that could look like:


This way, our application that only does Read operations uses this more granular interface. And it only needs to depend on the methods it actually uses.

If we do need a full CRUD repository, then we can simply inherit from this interface and add the other methods:


Because IRepository inherits IReadOnlyRepository, it includes the GetItems() and GetItem() methods, and then adds the other operations. This lets us be selective about the specific interface, and we only need to depend on the methods we actually use.

A CQRS Repository
But what about Jim's suggestion of having an ILoader and ISaver? This has a simplified set of methods. Here's what those interfaces look like:


We can easily imagine that the Loader would work very similar to our read-only repository. This would handle our "Read" (or "Query") operation. The Saver would handle the operations that update the data (the "Command" operations).

This actually follows the pattern of a CQRS repository. As mentioned above, CQRS stands for Command Query Responsibility Separation. This means that we keep the Command operations (the Saver) separate from the Query operations (the Loader).

What About Implementation?
One thing to notice is that the Saver has a much simpler interface. When we have the CRUD repository, we had separate methods for Create, Update, and Delete operations. With the ISaver interface, we have a single Save() method.

So, how do we know what operations we need to perform on the actual data store: Insert, Update, or Delete? That all depends on how we're storing our data.

One possibility is to only have Insert operations on our data store. We always insert the most recent record into the data store (with a current timestamp). If we have a deleted record, we insert the most recent record with a delete flag set to "true". When pulling data out, we make sure that we're fetching the most current record, but we have the full history in the database. This is fairly easy to implement in a document database. It can also be used with a relational database, however, the pattern isn't quite as common with RDBMS.

If we are using a typical RDBMS data store technique, we actually want to make Insert, Update, or Delete calls as appropriate (along with potentially logging the changes in separate change-tracking tables). But how do we know which operation we need to call on a particular record? That's where things get a bit more complex.

One solution that I've used is to use a business object framework that includes change tracking on the application objects. I've used CSLA.NET very successfully (http://www.cslanet.com/). This is a business object framework that works very well for the types of apps that we often build for companies (get data out of a database, let the user change it, put it back into the database). CSLA includes tons of useful features including change tracking, validation, authorization, and it works on a variety of platforms (web, desktop, mobile).

Using a framework such as this, we simply call "Save" on the business object, and the framework figures out which of the actual update operations to call depending on whether the record is new, changed, or deleted. (As a side note, this is a good example of the Facade design pattern where a complex API is hidden behind a simpler interface.)

Implementing this type of functionality yourself is not trivial, which is why we should look to see if there's an existing implementation that we can take advantage of.

Wrap Up
So, if we determine that we do need a repository (Do I Really Need a Repository?), our job is not necessarily done. We need to consider what type of repository will work best in our situation (CRUD vs. CQRS), and we also need to keep in mind whether we're including more methods in our interface than we actually need. If we find that we are not using all of the methods (or we find that we're using some of the methods in one class and other methods in others), we should think about splitting up our interface so that we have the right level of granularity. This is what the Interface Segregation Principle is all about.

This gives us quite a bit to think about. As always, we need to weigh the options and come up with the best solution for our particular environment.

Happy Coding!