Showing posts with label Design Patterns. Show all posts
Showing posts with label Design Patterns. Show all posts

Wednesday, October 29, 2014

Pluralsight Learning Path: Getting to Great with C#

Pluralsight has a lot of courses (like hundreds and hundreds). So it can be daunting to figure out where you need to start. To help get people pointed in a direction that works for them, Pluralsight has a collection of Learning Paths that highlight a set of courses to help you meet a goal -- whether you're working toward certification or want to learn to build a particular type of application.

A new learning path was published today: Getting to Great with C#.

Getting to Great with C#
  • Object-Oriented Programming Fundamentals in C#
  • Defensive Coding in C#
  • Clean Code: Writing Code for Humans
  • C# Interfaces*
  • Abstract Art: Getting Things "Just Right"*
  • Dependency Injection On-Ramp*
  • SOLID Principles of Object Oriented Design
  • Design Patterns On-Ramp*
  • Design Patterns Library
Be sure to follow the link (here it is again)  to get the details on the goals of the learning path and descriptions of all the courses.

The really cool part: I authored 4 of these courses (marked with *). I've had courses included in other learning paths, but I'm excited and honored to have so many of my courses included in a single collection (plus, I know the other authors and courses, and I'm in very good company).

Happy Coding!

Tuesday, April 22, 2014

Education Day, San Francisco - May 3, 2014

My friend Theo Jungeblut and I are putting together a full day of awesome for Saturday, May 3, 2014 in San Francisco, CA.

Clean Code: Principles, Patterns, and Practices for Better Code
You already code. Now it's time to take the next steps to becoming a better developer. Those steps are not difficult; we just need to put them into practice. The end result is code that is easier to maintain, easier to test, and easier to extend. Through lots of examples and hands-on labs, we'll learn about software design principles and the patterns that help us implement them. We'll see how Dependency Injection helps us create loosely-coupled code. And we'll spend a bit of time looking at Software Craftsmanship: ensuring that our code is readable by humans while still easy to maintain and test.
This is a full day event. Cost is only $39, and that includes lunch. For full details and to register for the event, visit Eventbrite: Clean Code: Principles, Patterns, and Practices for Better Code.

A big thanks to Bay.NET and Mathias Brandewinder for setting this up. I'm looking forward to a great event. Hope to see you there.

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!

Thursday, September 26, 2013

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!

Tuesday, August 20, 2013

More Pluralsight Courses Coming - What Topics Do You Want to See?

I've recently published 2 Pluralsight courses: one on C# Interfaces and one on the BackgroundWorker Component (also check my Pluralsight author page).

I'm working on more courses over the coming months. Currently in progress: Design Patterns On-Ramp. The goal of this course is to get comfortable with Design Patterns and see that we already use patterns everyday even if we don't realize it. This is a gentle introduction to get you ready for a deeper dive into the topic.

Be sure to check back; I'll post more information once this course is published.

What Topics Do You Want to See?
I have several slots to fill in my schedule. So what topics would you like to see me put into a Pluralsight course? Leave your suggestions in the comments, and I'll take them under consideration. In addition to a topic, try to include a specific angle. For example: "Design Patterns for the everyday developer".

I'm not an expert in everything, and topics that I speak and write about are technologies or principles that I've worked with in production code. In addition, the Pluralsight library is quite extensive; many topics are already covered. So don't be surprised if your topic is not selected; it's nothing personal.

I'm looking forward to hearing your suggestions.

Happy Coding!

Sunday, August 18, 2013

Do I Really Need a Repository?

I use the Repository pattern in a number of my presentations, whether talking about Interfaces, Generics, or Dependency Injection. The primary reason I use this is because it's a very easy problem to describe: we need to access data from different data sources (Web Service, SQL, Oracle, NoSQL, XML, CSV), and we want to keep the complexity out of our core application code.

But the question often comes up: Do I really need a Repository in my application?

And I'll give my standard answer: It depends.

Let's take a closer look at the Repository pattern and how it fits (or doesn't fit) with some scenarios that I've dealt with.

What is a Repository?
We'll start with a definition of the Repository pattern:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. 
[Fowler, et al. Patterns of Enterprise Application Architecture. Addison-Wesley, 2003.]
The idea behind having a repository is to insulate the application from the data access code. Here's a fairly typical interface that shows a CRUD (Create, Read, Update, Delete) repository:


This means that from our application code, we simply call "Repository.GetPeople()" to get a collection of Person objects from the data store. Our application code does not need to know what's on the other side of that "GetPeople" call. It could be a SQL query; it could be a service call; it could be reading from a local file. The application is insulated from that knowledge.

[Editor's Note: For more exploration of Repositories, see "Applying the Interface Segregation Principle to a Repository".]

But do we really need this in our application?

Add Abstraction as You Need It
Developers generally fall into two groups: over-abstractors and under-abstractors. Neither group is better than the other; they are just natural tendencies. But the challenge for both groups is to find just the right level of abstraction which is generally somewhere in-between.  (For a closer look, see Abstraction: The Goldilocks Principle.)

By nature, I am an under-abstractor. This is because early in my career, I supported an application that was severely over-abstracted. The application was extremely difficult to maintain, and even the senior devs had trouble getting expected behavior out of the code base. So, my first inclination is to limit abstraction as much as possible.

But I've learned some good lessons over the years, which included creating an under-abstracted application that was difficult to maintain. So now I'm always looking to find the balance. Here is the best advice that I've come across so far:
Add abstraction as you need it.
And this literally means "as you need it", not "because you think you might need it at some point in the future." This has helped keep me out of a lot of trouble, and it's also helped me when working with teammates who are over-abstractors by nature.

How does this apply to repositories?

Add a Repository When You Need It
A Repository is a layer of abstraction. So, let's look at some times when we might or might not need an explicit repository.

Scenario 1: No Repository
I worked for many years in corporate development in a fixed environment. All of our custom-built applications used Microsoft SQL Server for data. That was it. And having that consistency made it very easy to support our application portfolio.

But what this also meant is that we did not usually need an explicit Repository. It was very unlikely that we would swap out the data storage layer; it was always SQL Server. So, we did not have a repository.

Now, even though we didn't have a physical repository layer, we still kept all of our data access code nicely corralled. We did not have SQL queries scattered across the code base; we kept them in well-defined parts of our business layer.

Scenario 2: Repository
But there was a time when I needed to add a Repository. One of my applications imported data from a third-party application. That application was going through an upgrade and some changes. One of those changes was switching from Microsoft SQL Server to an Oracle Database.

So, for this application, I added a Repository layer. This allowed me to prepare the application for the switch-over once that third-party application went into production. Based on a configuration change, I could switch the application from using a SQL Server repository to an Oracle repository. This meant that I could develop, test, and deploy my updated code before the switch-over happened. And the upgrade process went very smoothly.

Scenario 3: Maybe Repository
Another reason we may want to add a repository is to facilitate automated testing. With a repository layer in place, it's easy to swap out a fake or mock repository that we can use for testing. But whether we need this will be based on how our objects are laid out.

For example, we may be working with smart-entities; a smart-entity is basically a collection of properties with retrieval and update capabilities. In this case, there really isn't anything to test. The data access methods populate the properties and update the data store. Since we don't really have any logic to test in these entities, we would not get much advantage by adding a repository layer.

On the other hand, we may be working with robust business objects; a robust business object is one which has business logic (business rules and validation) built in. In this case, we do have logic that we want to check in automated tests. A repository layer would make those tests easier, so we would get an advantage from that.

Wrap Up
Do we really need to have a repository in our application? It depends. A repository is a layer of abstraction. If we add abstraction where we don't need it, then we add unnecessary complexity to our application. So, let's add abstraction as we need it.

We've seen two main reasons why we may want to add a repository layer: (1) to swap-out data access code for different data stores, and (2) to facilitate unit testing. If either of these apply, then we should consider adding a repository.

I use the Repository pattern in my presentations because it is an easily-understandable abstraction. But whether we actually need it in our own applications depends on our environment. In most of the applications I've written, I have not needed it. But in the few where I have needed it, it has been a great asset.

Happy Coding!

Tuesday, April 16, 2013

Dependency Injection: The Service Locator Pattern

The Service Locator pattern (or anti-pattern) is one of the many Dependency Injection patterns that allow us to create loosely-coupled code.  I mentioned this pattern just a bit in my review of Mark Seemann's excellent book Dependency Injection in .NET (Jeremy's Book Review).

Seemann refers to the Service Locator as an anti-pattern -- meaning that we probably don't want to use it in most cases because there are better patterns out there.  But he also notes that he used the pattern for many years before coming to grips with its shortcomings.

As mentioned in the book review, I have also used the Service Locator, and I was a little surprised when it was referred to as an anti-pattern.  But in reading Seemann's description of the shortcomings, I had no choice but to agree.  I had actually come across these shortcomings in my own code, but in that environment, it made sense to continue to use the pattern.

So let's compare the Service Locator to one of the other DI patterns (specifically, the Constructor Injection pattern).  This will point out the problems that I ran across -- which also happen to be the problems that Seemann mentions in his book.

Constructor Injection
We'll start by taking a look at the Constructor Injection pattern.  For a detailed description of Constructor Injection, refer to my presentation "Dependency Injection: A Practical Introduction".

The basics of Constructor Injection is that we pass the dependencies that a class needs as parameters in the constructor.  Here's an example:


In this constructor, we are injecting an IPersonService and a CatalogOrder.  The constructor then assigns these to local fields that can be used by the class.  Whatever creates this object is responsible for supplying these dependencies.  Generally, this is done in the composition root and often involves a Dependency Injection container.

Now, let's compare this to the Service Locator.

Service Locator
The Service Locator varies a bit from Constructor Injection.  As mentioned above, with Constructor Injection, something else is responsible for resolving the dependencies that are needed by the class.

In contrast, when using the Service Locator, the class itself is responsible for resolving its dependencies by asking for them from the Service Locator.  This can be a DI container or some other object or method that can return dependencies.  In our sample, we'll use a DI container (Unity).

Here's a sample constructor:


Notice that the constructor is passed the entire DI container (although there are other ways to get the service locator into the object).  Then the object uses the service locator to pick out its own dependencies.  This takes the control away from the composition root and gives it to the object itself.

Note that just because you are using a DI container doesn't mean that you are using the Service Locator pattern.  The Service Locator is defined by how the container is used (i.e., whether the object is resolving its own dependencies).

On the surface the Service Locator appears to hit all of the points of Dependency Injection: it allows for extensibility; it allows for the swapping out of test doubles; it allows for late binding.  This is why it is considered by many to be a valid DI pattern.

But it has a major shortcoming: It hides the dependencies that are being used.

This might not seem like a big problem, but let's take a look at some unit tests to show the shortcoming in action.

Initial Unit Tests
We'll start by unit testing the constructor that uses Constructor Injection.  Here's our test:


Notice here that when we instantiate our CatalogViewModel, we must provide the both the IPersonService (_personService) and the CatalogOrder (_currentOrder).  If we didn't provide both of these parameters, the test code would not build.  As a side note, both of these dependencies (_personService and _currentOrder) are mock objects that are created in the test setup (not shown).

This test builds and passes with our current code.

Now let's look at the same test for the constructor that uses the Service Locator:


In this test, we must pass in a populated Unity container (called "_locator" in this case).  As noted in the comments, our "_locator" has both an IPersonService and a CurrentOrder registered in its catalog (these are added in the test setup).

This test builds and passes with our current code.

The Problem with Hiding Dependencies
With Constructor Injection, we can easily see that we have 2 dependencies just by looking at the constructor.  However, with the Service Locator, we don't have visibility to the dependencies from the outside (meaning, looking at the public API signatures of the class).

Let's see what happens when we add a 3rd dependency.  Our Constructor Injection implementation now looks like this:


The first thing that happens is that we get a build failure of our unit test.  Note the squigglies below:


Build failures are good.  They give you immediate feedback that something is wrong.  In this case, we can see that we have a missing dependency since the constructor wants a 3rd parameter.  We would see this same error throughout our code base wherever we try to construct a CatalogViewModel.  And we know exactly what to fix.

But what about the Service Locator.  Let's add another dependency:


If we rebuild our application, everything builds fine -- including the existing unit test for the constructor that uses the Service Locator.  The problem is when we run the tests.

Since our tests do not know about the 3rd dependency, the test setup does not load it into the Unity container.  So, this test will throw an exception (when it tries to resolve the "CurrentUser" from the container).  In addition, all other tests we have that are creating this object will fail with the same exception.

This is the equivalent of a runtime error.  Whenever we have a choice between a compile-time error and and runtime error, we should pick the compile-time error.

Wrap Up
As we've seen the Service Locator pattern is a valid DI pattern in that it addresses the issues that we are trying to resolve with Dependency Injection.  However, it does have a flaw: it keeps the actual dependencies hidden.

When we have a choice between the Service Locator and Constructor Injection, we should favor Constructor Injection.  Constructor Injection makes the dependencies completely obvious to whomever is using the class.  And if the dependencies need to change, the result is build failures -- we don't have errors accidentally slipping into compiled code.

I have used the Service Locator pattern in production code.  And it did work.  But I did run into the issue described here.  When we added another dependency to an object, the unit tests would build successfully but then all fail (it's a bit disconcerting when you have 30 unit tests fail at once).  The test failures were not a problem with the code, they were a problem with the test setup.  Since the dependency was hidden by the Service Locator, it wasn't until we received these failures that we realized we needed to go in and add the dependencies in the setup.

So, if you're willing to live with the shortcoming, you can consider the Service Locator a DI pattern.  For everyone else, consider it an anti-pattern.  As with everything, we need to understand the pros and cons of each tool that we use so that we can make informed choices.  This is how we build maintainable, extensible code.

Happy Coding!

Thursday, February 14, 2013

Book Review: Working Effectively with Legacy Code

I just finished reading Working Effectively with Legacy Code by Michael C. Feathers (Amazon link).  I'll dispense with the standard review since this book has been around since 2005 and has many reviews and recommendations.

The short recommendation: Read this book.  Even if you aren't working with existing code that needs to be updated, the techniques can be used to recognize potential issues on new code that you're writing.  And if you are trying to untangle an existing code base, this book is invaluable.

Refactoring for Testability
The best way to describe this book is "refactoring for testability".  The idea behind this is that if you need to make modifications to code, you need to first have tests in place.  If you do not have tests for the existing code, then if your changes break the current functionality, you won't know about it.  With tests in place, you will know if you break something as soon as you make those changes.

This is a "Do no harm" approach.  The code that you are walking up to is working code (you're adding features, not necessarily fixing bugs).  The last thing you want to do is to remove the "working" part.

This is especially critical if you are working with code that you didn't write yourself (or even code you did write yourself several years ago).  You need to recognize that if you are going to be successful in working with unfamiliar code, you need to make small changes one step at a time.

Three Parts
The book is broken down into 3 parts.

Part I: The Mechanics of Change
Part one focuses on why we need to make changes to code, how unit testing can help us make confident changes, and several tools and techniques (such as finding/creating "seams", refactoring tools, and mocking). This is a high-level overview of why we need to start working this way (refactoring for testability).

Part II: Changing Software
Part two focuses on specific problems that you may encounter in the code -- things that make the code hard to get into a test harness.  Personally, I just like reading the chapter titles.  Here are a few:
  • I Don't Have Much Time and I Have to Change It
  • I Need to Make a Change, but I Don't Know What Tests to Write
  • Dependencies on Libraries Are Killing Me
  • I Don't Understand the Code Well Enough to Change It
  • My Application Has No Structure
  • My Test Code Is in the Way
  • My Project Is Not Object Oriented. How Do I Make Safe Changes?
  • This Class Is Too Big and I Don't Want It to Get Any Bigger
  • I Need to Change a Monster Method and I Can't Write Tests for It
  • How Do I Know That I'm Not Breaking Anything?
Part III: Dependency-Breaking Techniques
Part three consists of a catalog of 24 techniques that you can use to bring code under test.  These are all presented in a short (usually 3-5 page) format with an example and specific steps to follow.  These techniques are referenced in Part II, so you'll probably be familiar with the concepts.

Some examples:
  • Break Out Method Object
  • Encapsulate Global References
  • Expose Static Method
  • Extract Implementer
  • Extract Interface
  • Parameterize Constructor
  • Pull Up Feature
  • Push Down Dependency
  • Subclass and Override Method
This seems kind of "design-patterny" in the sense of having a catalog of well-named techniques.  These techniques aren't perfect.  Michael Feathers notes in several places that some of these techniques actually make your code "worse" structurally.  But they are still valuable because they increase the testability.  The theory is that the more you work with the code, these bad structural patterns will be refactored into more organized code.  But the point is that these changes are all made incrementally -- one, small change at a time.

An Example
One chapter that especially jumped out at me (not sure why -- probably because I've seen this before) is "I'm Changing the Same Code All Over the Place."  This has to do with reducing the duplication of code between 2 classes.

What I really liked about this chapter is that it shows the reduction in duplication is small steps.  There is no, "just extract everything to a superclass and you'll be fine."  Instead, it starts by figuring out what the commonalities are between the classes -- starting with properties and methods.

The first step was to create a superclass with *one* common method.  Then the implementation methods (in each class) are updated to make them more similar (by extracting out a method to make the body of the common method identical).  Then this implementation can be moved up to the superclass with only the differences (the extracted method) in each subclass.

The next step was to move the common properties up to the superclass.  Then the refactoring continues one step at a time.  When we are left with some unique properties in each class, the question is can we combine these into a common collection.

I don't expect that this description will make much sense out of context.  The point is that instead of thinking about the refactoring in big chunks, we are thinking about it in very small steps.  At each step, we can make sure that the tests still work as expected.  And if a test fails, we can immediately know what happened.  If we were to do a "big blast" change and the tests fail, we won't know specifically what the problem is.

As someone who has rolled back big chunks of changes (because it didn't work and I wasn't quite sure why), I really appreciate this approach.

Wrap Up
To wrap things up, whether you need to modify an existing code base or you are just looking at techniques to make your code more testable, Working Effectively with Legacy Code is an excellent read.  Note: none of the examples are in C#, but they are in C-family languages (C, C++, and Java), but C# is mentioned in many of the techniques.  (There's also one Ruby example for a technique that deals with dynamic languages.)  If you are comfortable reading C#, you should be able to understand the examples just fine.

I'm always looking to improve my coding techniques, and I'm sure that I will be thumbing through this book many times in the coming years.

Happy Coding!

Sunday, December 9, 2012

Five Months In: Working with Prism in WPF

Several months ago, I put down some initial thoughts regarding Prism: First Impressions: Working with Prism in WPF.  Now that I've been working with Prism for five months, I thought it was time for a follow-up.

It turns out that my opinions haven't changed much from those first impressions.  Prism is working out very well for the project I'm working on.  Taking advantage of the modularity (and the independence of each module) has allowed us to quickly modify and add to our task workflows.  We've managed to keep good separation and isolation which has made unit testing much easier.  The navigation objects are working as expected.  And the helper objects make the code much more compact, readable, and maintainable.

Prerequisites
I have confirmed my opinion that Prism is not for beginning programmers; there are a number of intermediate topics that are necessary to understand.  What is interesting is that I have articles or presentations that are centered around these prerequisites.  I didn't plan for this, it just turns out that the topics I've written about happen to revolve around the foundational knowledge required for Prism.

Here's the list from the previous article along with links to my materials:
These articles are a good place to get started.  By understanding these topics, you will be better prepared to work with Prism in your applications.

Useful Features
In the previous article, I mentioned a number of features that I liked.  That list is still accurate.  I'll go into a little more detail on 2 of these features.

DelegateCommand
The DelegateCommand allows you to create an ICommand object with much less code.  Commanding is used to data bind to buttons in the UI.  Let's compare some code.

To implement ICommand yourself is not very complicated.  But there is a lot of boiler-plate code in a custom object.  Here's a sample command implementation (this is taken from the Dependency Injection session samples):


As we can see, there is quite a bit of code here, but we really only care about the last line (that assigns to the People property of the ViewModel).  The rest is plumbing.

Compare this to using a DelegateCommand from the Prism framework:


This allows us to do the same thing (assign a value to the People property), but we can do this with just one line of code (the DelegateCommand constructor) instead of needing to create a custom class.  The parameter of the DelegateCommand constructor is the "Execute" we want to perform ("Execute" is part of the ICommand interface).

ICommand has another method: "CanExecute".  This returns true or false depending on whether the command can be executed.  In our example, this always returns "true".  But sometimes this is more complicated -- such as if we need to check a property or run some code.  The DelegateCommand constructor takes a second parameter which is a delegate for "CanExecute".  If you do not provide one, then "CanExecute" is always true.

As you can see, DelegateCommand makes our code much more compact.  And if we don't want to use a lambda expression (or if our Execute is several lines of code), then we can use a standard delegate method instead.  The result is that it is easier to see the intent of our code.  Instead of looking through a custom command object for the Execute method, we have the code right here in the constructor (or a pointer to it in the case of a named delegate).

When you have a number of commands in the application, this makes a huge difference in the amount of code that needs to be written as well as the readability of that code.

NotificationObject
NotificationObject is another class that is provided by the Prism framework.  This class implements the INotifyPropertyChanged interface.  This interface needs to be implemented in order for data binding to work as expected in XAML.  The interface itself is not hard to implement (just a few lines of boiler-plate code).  The difference between NotificationObject and manual implementation has to do with the RaisePropertyChanged methods that are available.

When implementing INotifyPropertyChanged, you generally make a call to RaisePropertyChanged in the setter for a Property, such as this:


The RaisePropertyChanged method will alert the UI that the underlying property has been updated and that the UI should refresh the binding.  Notice that this version of RaisePropertyChanged takes a string parameter.

In contrast, NotificationObject provides a RaisePropertyChanged method that takes an Expression.  This lets us write code like this:

Your first thought might be, "I don't see much of a difference."  But there is.  Instead of using a string, we use an expression with the actual Property.  This means that we get IntelliSense when we are creating this method.  It also means we will get a compiler error if we type the property name incorrectly.  And most importantly, if we rename our property, our refactoring tools will automatically update the RaisePropertyChanged method as well.  Using properties over strings is definitely the way to go.

Nothing You Can't Do Yourself
I had an interesting conversation with someone about Prism.  He asked me what I liked about it, and I told him that I really liked the DelegateCommand.  His response was that you could create a DelegateCommand object yourself -- it's only about 15 lines of code.  And he is absolutely correct.

Prism doesn't perform any magic.  It consists of a set of helper classes and methods that you could implement yourself.  But we don't have to.  The Patterns & Practices team has implemented these for us and put them together in a package that is easy to use.

If you don't like any of the implementations, you are free to change them.  Prism comes with all of the source code (including unit tests).  So you can enhance or re-implement any of the features.  My experience is that the features are well-implemented and have met my needs.

What About Windows 8?
My one disappointment around Prism is that it looks like there won't be an implementation for Windows Store Applications.  Prism covers a lot of platforms: WPF, Silverlight 5, and Windows Phone 7.5.  The latest rumors are that there will be a different guidance package from the Patterns & Practices team for Windows Store Applications, and I have not been able to hunt down a beta or a release date at this point.

If you are developing Windows 8 desktop application with WPF, then Prism will work just fine.  But for Windows Store Applications, we will need to wait for another solution.

[UPDATE: There has been announcement regarding guidance for Windows Store Apps.  More info: Update on Windows 8 Guidance]

Wrap Up
As I mentioned, my opinion of Prism has not changed much from my initial impressions of working with it.  It has been a very good framework for my current project, and I will keep it in mind for future projects.  If you are working on fairly straight-forward applications or applications with just a few screens, then Prism may be more than you need.  But if you are working on modular or enterprise-level applications, it may be just what the doctor ordered.

Happy Coding!

Saturday, October 20, 2012

Abstraction: The Goldilocks Principle

Abstractions are an important part of object-oriented programming.  One of the primary principles is to program to an abstraction rather than a concrete type.  But that leads to a question: What is the right level of abstraction for our applications?  If we have too much abstraction, then our applications can become difficult to understand and maintain.  If we have too little abstraction, then our applications can become difficult to understand and maintain.  This means that there is some "sweet spot" right in the middle.  We'll call this the Goldilocks level of abstraction: "Just Right."

So, what is the right level?  Unfortunately, there are no hard-and-fast rules that are appropriate for all development scenarios.  Like so many other decisions that we have to make in software development, the correct answer is "it depends."  No one really likes this answer (especially when you're just getting started and are looking for guidance), but it's the reality of our field.

Here are a few steps that we can use to get started.

Step 1: Know Your Tools
The first step to figuring out what abstractions to use is to understand what types of abstractions are available.  This is what I focus on in my technical presentations.  I speak about delegates, design patterns, interfaces, generics, and dependency injection (among other things).  You can get information on these from my website: http://www.jeremybytes.com/Demos.aspx.  The goal of these presentations is to provide an overview of the technologies and how they are used.  This includes examples such as how to use delegates to implement the Strategy pattern or how to use interfaces with the Repository and Decorator patterns.

We need to understand our tools before we can use them.  I try to show these technologies in such a way that if we run into them in someone else's code, they don't just look like magic incantations.  If we can start looking at other people's code, we can get a better feel for how these tools are used in the real world.

A while back, I wrote an article about this: Design Patterns: Understand Your Tools.  Although that pertains specifically to design patterns, the principle extends to all of the tools we use.  We need to know the benefits and limitations to everything in our toolbox.  Only then can we make an informed choice.

I remember seeing a woodworking show on television where the host used only a router (a carpentry router, not a network router).  He showed interesting and unintended uses for the router as he used it as a cutting tool and a shaping tool and a sanding tool.  He pushed the tool to its limits.  But at the same time, he was limiting himself.  He could use it as a cutting tool, but not as effectively as a band saw or a jigsaw or a table saw.  I understand why this may be appealing: power tools are expensive.  But in the software world, many of the "tools" that we use are simply ideas (such as design patterns or delegates or interfaces).  There isn't a monetary investment required, but we do need to make a time investment to learn them.

Step 2: Know Your Environment
The next step is to understand your environment.  Whether we are working for a company writing business applications, doing custom builds for customers, or writing shrink-wrap software, this means that we need to understand our users and the system requirements.  We need to know what things are likely to change and which are not.

As an example, I worked for many years building line-of-business applications for a company that used Microsoft SQL Server.  At that company, we always used SQL Server.  Out of the 20 or so applications that I worked on, the data store was SQL Server.  Because of this, we did not spend time abstracting the data access code so that it could easily use a different data store.  Note: we did have proper layering and isolation of the data access code (meaning, all of our database calls were isolated to specific data access methods in a specific layer of the application).

On the other hand, I worked on several applications that used business rules for processing data.  These rules were volatile and would change frequently.  Because of this, we created rule interfaces that made it very easy to plug-in new rule types.

I should mention that these applications could have benefited from abstraction of the database layer to facilitate unit testing.  We were not doing unit testing.  In my next article, I will talk more about unit testing (and my particular history with it), and why it really is something we should all be doing.

Step 3: Learn the Smells
A common term that we hear in the developer community is "code smells". This basically comes with experience.  As a developer, you look at a bit of code and something doesn't "smell" right -- it just feels off. Sometimes you can't put your finger on something specific; there's just something that makes you uncomfortable.

There are a couple of ways to learn code smells.  The preferred way is through mentorship.  Find a developer with more experience than you and learn from him/her.  As a young developer, I had access to some really smart people on my development team.  And by listening to them, I saved myself a lot of pain over the years.  If you can learn from someone else, then be sure to take advantage of it.

The less preferred (but very effective) way of learning code smells is through trial and error.  I had plenty of this as a young developer as well.  I took approaches to applications that I later regretted.  And in that environment, I got to live with that regret -- whenever we released a piece of software, we also became primary support for that software.  This is a great way to encourage developers to produce highly stable code that is really "done" before release.  While these applications were fully functional from a user standpoint, they were more difficult to maintain and add new features than I would have liked.  But that's another reality of software development: constant learning.  If we don't look at code that we wrote six months ago and say "What was I thinking?", then we probably haven't learned anything in the meantime.

Step 4: Abstract as You Need It
I've been burned by poorly designed applications in the past -- abstractions that added complexity to the application without very much (if any) benefit.  As a result, my initial reaction is to lean toward low-abstraction as an initial state.  I was happy to come across the advice to "add abstraction as you need it".  This is an extremely good approach if you don't (yet) know the environment or what things are likely to change.

As an example, let's go back to database abstractions.  It turns out that while working at the company that used SQL Server, I had an application that needed to convert from SQL Server to Oracle.  The Oracle database was part of a third-party vendor product.  For this application, I added a fully-abstracted repository that was able to talk to either SQL Server or the Oracle database.  But I just did this for one application when I needed it.

Too Much Abstraction
As mentioned above, too much abstraction can make an application difficult to understand and maintain.  I encountered an application that had a very high level of abstraction.  There were new objects at each layer (even if the object had exactly the same properties as one in another layer).  The result of this abstraction meant that if someone wanted to add a new field to the UI (and have it stored in the database), the developer would need to modify 17 different code files.  In addition, much of the application was wired-up at runtime (rather than compile time), meaning that if you missed a change to a file, you didn't find out about it until you got a runtime error.  And since the files were extremely decoupled, it was very difficult to hook up the debugger to the appropriate assemblies.

Too Little Abstraction
At the other end of the spectrum, too little abstraction can make an application difficult to understand and maintain.  Another application that I encountered had 2600 lines of code in a single method.  It was almost impossible to follow the logic (lots of nested if/else conditions in big blocks of code).  And figuring out the proper place to make a change was nearly impossible.

"Just Right" Abstraction
My biggest concern as a developer is finding the right balance -- the Goldilocks Principle: not too much, not too little, but "just right".  I've been programming professionally for 12 years now, so I've had the benefit of seeing some really good code and some really bad code (as well as writing some really good code and some really bad code).

Depending on what kind of development work we do, we can end up spending a lot of time supporting and maintaining someone else's code.  When I'm writing code, I try to think of the person who will be coming after me.  And I ask myself a few key questions.  Will this abstraction make sense to someone else?  Will this abstraction make the code easier or harder to maintain?  How does this fit in with the approach used in the rest of this application?  If you are working in a team environment, don't be afraid to grab another developer and talk through a couple of different options.  Having another perspective can make the decision a lot easier.

The best piece of advice I've heard that helps me write maintainable code: Always assume that the person who has to maintain your code is a homicidal maniac who knows where you live.

One other area that will impact how much abstraction you add to your code is unit testing.  Abstraction often helps us isolate code so that we can make more practical tests.  I'll be putting down my experiences and thoughts regarding unit testing in the next article.  Until then...

Happy Coding!

Thursday, October 11, 2012

Session Spotlight - Dependency Injection: A Practical Introduction

I'll be speaking at SoCal Code Camp (Los Angeles) on October 13 & 14.  If you're not signed up yet, head over to the website and let them know that you're coming: http://www.socalcodecamp.com/.

Also, I've got a brand new session: Dependency Injection: A Practical Introduction

How Do We Get Started With Dependency Injection?
One of the big problems with getting started with Dependency Injection (DI) is that there are a lot of different opinions on exactly what DI is and the best ways to use it.  At its core, DI is just a set of patterns for adding good abstraction to our code.  The objects we create should be focused on doing one thing and doing it well.  If there is functionality that is not core to the the object, then we "outsource" it to another class.  This external class is a dependency (our primary object depends on this other class to provide a functional whole in our application).

Dependency Injection gives us a way to keep these external dependencies separate from our objects.  Rather than the object being responsible for creating/managing the dependency, we "inject" it from the outside.  This makes sure that our classes are loosely coupled which gives us good maintainability, extensibility, and testability.

In this session, I combine my personal experience using DI with the excellent information provided by Mark Seemann in Dependency Injection in .NET (I posted a review on this book a few weeks back).

DI is an enormous topic. I have picked out a few key areas (like examining tight-coupling and loose-coupling) and design patterns that will give us a good starting point for the world of DI.  (As a side note, the sample code also gives a quick example of using the Model-View-ViewModel (MVVM) design pattern.)

If you can't make it out to the SoCal Code Camp, you have another chance to see this session at the Desert Code Camp (in the Phoenix, AZ area) in November.  And as always, the code samples and walkthrough are posted on my website.

Hope to see you at an upcoming event.

Happy Coding!

Monday, September 3, 2012

Book Review: Dependency Injection in .NET

I just finished reading Dependency Injection in .NET by Mark Seemann (Amazon link).  This is an excellent description of Dependency Injection (DI), the associated patterns, and several of the main DI frameworks.  Seemann has pulled together a wide range of resources (books, magazine articles, blog posts) and created a comprehensive work.  It is apparent that this is based on a ton of research and personal experience in the DI world.

This turned out to be a good and timely read for me.  A couple months ago, I started working on a WPF project using Prism, and Dependency Injection plays a big role in that.  A colleague of mine (and former co-worker) highly recommended this book, and so I picked up a copy.  (Disclaimer: I am a "book person"; that is how I learn best.  Other people have different learning methods, so feel free to take this from a "book person" perspective.)

Part 1
Part 1 is an overview of Dependency Injection.  Seemann describes what DI is, and also dispels some misconceptions about DI.  He covers the benefits of DI including late binding, extensibility, parallel development, maintainability, and testability.  He also lays a foundation by showing good and bad examples of implementing DI and how each impacts achieving the desired benefits.  Finally, he introduces the topics that will be used in the rest of the book, including the design patterns, DI features, and the DI containers that are available.

Part 2
Part 2 covers the patterns and anti-patterns in DI.  The patterns include Constructor Injection, Property Injection, Method Injection, and Ambient Context.  Seemann does a good job of covering these patterns including both the benefits and the drawbacks of each.  It becomes apparent very quickly that he favors Constructor Injection wherever possible and that the other patterns should be used only when Constructor Injection is not possible.  (As a side note: I came to this same opinion in my fairly-short time working with DI.)

The anti-patterns include Control Freak, Bastard Injection, Constrained Construction, and Service Locator. Of these, the Service Locator is the most controversial.  Many people consider Service Locator to be a valid DI pattern (rather than an anti-pattern).  Seemann himself admits that he promoted the use of Service Locator for many years. He eventually came to the point where the shortcomings of the pattern outweighed the benefits.  Prism (the Microsoft Patterns and Practices application guidance) has a service locator baked in (to reference either Unity or MEF for DI out-of-the-box).  In my experience with Prism, we have used the service locator pattern, and I can see the benefits and shortcomings.  At this point in the project, the scale leans towards the benefits, and we are willing to work with the drawbacks.

Part 2 also has a chapter on "DI Refactorings".  This is a very practical review of what types of DI situations you'll run across in the real world -- like dealing with cyclic dependencies and short-lived dependencies.  These are great topics to cover.  Because the DI containers that we normally work with add the layer of abstraction, sometimes we forget about some potential issues (by assuming that the container is dealing with it).

Part 3
Part 3 covers some big DI topics: Object Composition, Object Lifetime, and Interception.  Object Composition has to do with how we use DI to compose our objects.  Seemann shows examples for how to compose objects with various technologies -- from easy implementations with console and WPF applications, to difficult implementations with ASP.NET applications and PowerShell commandlets.

Object Lifetime has to do with how the dependencies themselves are managed.  Do you always return the same instance of a dependency no matter who asks for it (Singleton)?  Or do you return a new instance of a dependency each time (Transient)?  Or do something inbetween?  Seemann covers the various lifetimes and the pros and cons for each.  As with everything, we need to consider our particular situation and select the right answer for the task at hand.

Finally, Seemann covers Interception.  This is the idea of using the DI container to inject cross-cutting concerns into our application.  For example, we could have the container inject logging or error handling into each of our dependencies.  This was a very interesting topic to read about.  He also covers Aspect Oriented Programming (AOP) and compares/contrasts it with using DI to cover the same concerns.

Part 4
Part 4 covers several DI containers.  What I really liked about this section is that Seemann uses the same examples in each chapter.  This means that instead of focusing on the example itself, we can focus on the differences in the container implementations.  The containers covered are not exhaustive (5 containers), but they are some of the most widely-used ones.

The containers include Castle Windsor, StructureMap, Spring.NET, Autofac, and Unity.  Using each container, examples cover configuration, managing lifetime, interception, and how working with difficult APIs (the difficult APIs refers to the dependencies that we are registering/resolving, not the container APIs themselves).  Not all containers support all features out-of-the-box, and Seemann shows some possible work-arounds for the features that are not implemented directly by the container.  The end result is that most of the containers work pretty much the same (which is good), but there are slight variations.  The container you select can be based on personal preference or particular needs (for example Spring.NET is actually a much larger framework that includes DI functionality; you may want to use Spring.NET for those other features or because you also use Spring in the Java world).

Lastly, Part 4 covers MEF (Managed Extensibility Framework).  While MEF is not a DI container, it is often used for DI purposes.  (This is true of the Prism framework -- it supports using MEF as a DI container.)  Seemann shows that while MEF can be used for DI, it probably should not be.  Again, this is a controversial topic: I have seen blog articles where people moved from Unity to MEF for DI and see no reason why anyone would want to start a new project with Unity.  Seemann lays out some very good points regarding how DI is implemented using MEF and how it varies greatly from the other containers.

Resources
Where Dependency Injection in .NET really shines is in its use of external references.  Many sections point to books, magazine articles or blog articles where you can research topics further.  Seemann has gone to a lot of work to collect these resources together in one place.  I will be spending a lot of time going through the links collected at the back of the book.  On a good note (personally), I found that several of the books mentioned are already in my collection.

Wrap Up
Dependency Injection in .NET is an excellent resource.  There are not very many DI books on the market, and it is great to see that this particular book is so well executed.  I would recommend this to any developer who is interested in improving his/her use of Dependency Injection.

Happy Coding!

Wednesday, August 1, 2012

Los Angeles .NET Developers Group

If you're in the Los Angeles area, I'll be speaking at the Los Angeles .NET Devleopers Group on Monday, August 6th.  More info is available here: http://www.ladotnet.org/events/74859482/.

The topic is "Learn the Lingo: Design Patterns".  We'll take a look at what design patterns are, why they are important to us, and how we already use them in our everyday code without even realizing it.  In addition to the benefits, we'll take a look at the costs to help us determine when we should be using various patterns.  Once we are familiar with Design Patterns, we can start to use them deliberately and hopefully get to the point where we are using them automatically (where appropriate, of course).  Hope to see you there.

Happy Coding!

Sunday, July 22, 2012

First Impressions: Working with Prism in WPF

Three weeks ago, I started working with Prism on a WPF application.  Here are a few of my first thoughts:

The Good
Prism is an extremely powerful framework.  It provides classes to help you manage all parts of your WPF application (or Silverlight or Windows Phone 7 -- I'm sure that Metro will be coming soon).  So far, I've worked with the following features:
  • Modules / Module Catalog
  • UI Composition  / Regions / Region Manager
  • Navigation
  • Dependency Injection
  • Event Aggregation
  • Other "Helper" Objects
The Bad
Prism is not for beginning programmers.  If you do not have a solid grasp on intermediate .NET topics, then much of the Prism framework is going to look like magic incantations.  This can only lead to misuse of the framework classes, and most likely this misuse will lead to not getting the benefits (such as good separation of concerns, re-use, and testability).

Before using Prism, you should have a good foundation with the following topics:
  • Dependency Injection / Inversion of Control
  • Interfaces
  • Delegates / Func<T> / Action<T>
  • Lambda Expressions
  • Events and Event Handlers
  • Model-View-ViewModel (MVVM)
  • Various other Design Patterns
As a side note, the documentation ("A Developer's Guide to Microsoft Prism 4" -- available as a PDF or as a tree-book) has an appendix dedicated to the primary design patterns used by Prism.  This includes Adapter, Application Controller Pattern, Command Pattern, Composite and Composite View, Dependency Injection Pattern, Event Aggregator Pattern, Facade Pattern, Inversion of Control Pattern, Observer Pattern, Presentation Model Pattern, Registry Pattern, Repository Pattern, Separated Interface and Plug-In, and Service Locator Pattern.

Good Collection of Features
Prism is an extremely powerful framework and has gone through several iterations and refinements.  The current version (4.1) even includes support for Silverlight 5.  The Patterns & Practices team has obviously put a lot of work into the framework, and my experience so far has been bug-free (from the framework perspective at least -- I'm working on making my own code bug-free).  Let's take a closer look at the features that I've experienced so far:

Modules / Module Catalog
Modules allow you to separate your application functionality into discrete units that can be "plugged in" to the application.  The modules can (should?) be designed to be application agnostic and self-contained.  This means that they can be re-used in other applications.  For example, if you have a need for Customer Maintenance, this could be its own module.  If you have proper separation of concerns, then this module could be used in multiple applications.

For the application I am working on, we have modularized most of the application "screens".  These are being tied together through a work flow.  As a (fictional) example, to take a customer order over the phone, you could start with the Customer module (either entering new customer data or selecting an existing customer), moving on to a Shopping Cart module (where products and quantities are selected), then to a Shipping module, then to a Payment module.  If these modules are designed to work in isolation, then they can be reused in the same application in different work flows.

The Module Catalog keeps track of all of the modules in the application.  This can be set explicitly by specifying types and assemblies, or it can be done much more dynamically.  In our project, the bootstrapper process (that loads the module catalog) searches all of the assemblies in a particular folder and catalogs / initializes any modules that it finds in there.

UI Composition / Regions / Region Manager
The Region Manager is another very powerful tool.  It lets you associate different Views with different Regions of the UI.  This allows you to bring several Views together into a single "screen" for the user.  Different Views can interact with each other (through the Event Aggregator) and still remain programmatically isolated.  The idea is very similar to how a Master Page in an ASP.NET application allows you to have multiple web forms shown in different areas of a single "page".

Navigation
The Navigation infrastructure adds quite a bit of functionality to moving between views.  For example, what do you do if you have unsaved data in a View and the user wants to navigate to another View?  WPF does not have anything built in for this scenario, but Prism does.

Prism offers the IConfirmNavigationRequest interface that can be added to your Views or ViewModels (as a side note, many of the Prism features can be added to either the View or the ViewModel and they behave the same -- this gives you great flexibility depending on whether you are coding View-first or ViewModel-first in your application).  This interface has a ConfirmNavigationRequest method.

When using the Navigation infrastructure, you call "RequestNavigate" (notice the word "request").  The method parameters include a callback that runs when the navigation completes successfully.  But, when RequestNavigate is called, ConfirmNavigationRequest is fired on the View/ViewModel that you are navigating from.  This gives that View/ViewModel the chance to confirm or cancel the navigation.  For example, if the current View/ViewModel has unsaved data, it can prompt the user to Save, Discard Changes, or Cancel.  Cancel would then cancel the navigation, and the current View would remain in place.  Otherwise, the "from" View/ViewModel can simply call the callback, and navigation completes normally.

There are also other methods in the interface (part of INavigationAware and IConfirmNavigationRequest) that allow you to run code "OnNavigatedFrom" (to clean up any resources in the current View/ViewModel) or "OnNavigatedTo" (to initialize the new View/ViewModel).

This functionality is very powerful, and if you did not use what comes with Prism, you would probably end up building a lot of this yourself.  I speak from experience: I implemented a much simpler ICloseQueryable interface on a simple form manager used in a non-Prism application (for more information, see XAML App Review - Part 2: Form Manager).

Dependency Injection
You won't be able to use Prism effectively without dependency injection.  In order to have good separation of concerns for the modularity, MVVM presentation pattern, and other cross-cutting concerns, Prism needs a dependency injection container.  Prism ships with implementations for using Unity (from Patterns & Practices) and MEF (built into .NET 4.0), but you can build your own implementations for using a different DI container (or just cruise the web; I'm sure other people have created implementations for the most popular DI containers).

I've been working with Unity on our project.  With Unity, you can use both Constructor Injection (where the dependencies are specified as parameters in the constructor) and Property Injection (where public properties are flagged as "Dependency" and automatically resolved).

Dependency Injection lets your Views/ViewModels get access to the cross-cutting classes in your application.  For example, you could have an Authorization or Logging service/class that gets injected into each View/ViewModel.  This way, if the Module is used in a different application, the ViewModels will automatically get the cross-cutting services that are registered for that application.

In a Prism application you will (hopefully) make heavy use of interfaces.  For example, the ViewModel could have a dependency on a Model interface, and this dependency could be injected with constructor injection.  This gives you the flexibility of swapping out the Model when you want to unit test the ViewModel.

In this scenario, the application would use the DI container to associate the IModel with the concrete Model (with "RegisterType" if you're using Unity).  If this registration is done at the Module level, then the dependency can be correctly injected everywhere it is used. In the unit tests, you could create a mock of IModel that is registered with the test container.  This makes it very easy to unit test your ViewModel without having to worry about a specific implementation of that Model (such as one that needs a network connection to a service).

I'll be talking more about Unit Testing with Prism and Unity in a future article.  That's an interesting topic in and of itself.

Event Aggregation
With all the loose-coupling that is going on in Prism, it could be very difficult to communicate between modules.  This is where the EventAggregator comes in.  The EventAggregator allows one module to Publish an event (with a particular payload), and any other module can Subscribe to that event.  The two modules do not need to know directly about one another.  One is simply publishing an event, and the other is simply listening for an event.  Neither cares about where the event is coming from nor where it's going.

The EventAggregator takes things another step beyond the normal eventing model in .NET.  The Subscribe method also gives you the opportunity put in a condition based on the payload.  For example, you could say that you want to Subscribe to a StockUpdateEvent, but only if the payload has a StockTickerID of "GM".  The event is published normally, but your event handler only fires if the payload has that particular value in it.

Other "Helper" Objects
Prism also provides helper objects that are designed to make life easier (often by reducing boiler-plate code).  Two of my favorites are NotificationObject and DelegateCommand.

The NotificationObject (Prism) is a base class that implements INotifyPropertyChanged (.NET).  Pretty much all of your ViewModels and/or Models will need to implement INotifyPropertyChanged in order for the data binding to behave as expected.  NotifcationObject is a concrete class that implements INotifyPropertyChanged, so you don't need to include the boiler-plate code for that interface in every single object.

DelegateCommand (Prism) simplifies commanding and the implementation of ICommand (.NET).  Commanding is a much larger topic, but the usual process is to create a class that implements the ICommand interface (this can be a class embedded in the class that uses it or a completely separate class).  ICommand has 2 primary methods: Execute (which is the command code) and CanExecute (which determines whether the command can be run -- this can enable/disable a button tied to the command based on a particular state).

DelegateCommand replaces this separate class with a constructor that takes 1 or 2 delegates as parameters. The first delegate is the code for the command to run ("Execute") and the second delegate is for the "CanExecute" (if you don't provide this, it will always be "true").  Again, this class helps to cut down the boiler-plate code of creating an ICommand object and eliminates the need for a separate type.  Since it is part of your class, the delegates also have access to the internal members/state of the containing class.

Putting It All Together
These features all come together with the goal of making the application easier to maintain, more testable, and reusable.

One main thing to note: you don't have to use all of these features.  If you decide that you do not want to use the Region Manager or Navigation, that's fine.  If you don't want to use the Event Aggregator, that's fine, too.  You can use just the features that you want.  Also Prism does not assume that you are using the MVVM pattern; you don't need to use MVVM, but Prism provides helpers to make the pattern easier to implement.  And even though the features are mostly optional, I think that you'll find yourself using most of these features for any non-trivial application.

I've read about Prism (and previously about the Composite Application Guidance for WPF) and have found it interesting.  At the time, I was concerned about a lot of the apparent magic that is going on (and I am still concerned about this).  It is imperative that you have a good handle on the foundational principles used in Prism before you get started.  If you have a good foundation, then you can build very solid (yet de-coupled, maintainable, testable, and modular) applications.

Three weeks is not that long to have worked with a framework such as Prism.  I'm amazed at how much more I know about Prism than I did prior to this project; much of this is due to a couple of folks on the team who have used Prism successfully in prior projects.  There's still some learning to do on the finer points, and we are still tweaking our implementations a bit, but the larger functionality has fallen into place.

[Update: Here are some thoughts after working with Prism for a while: Five Months In: Working with Prism in WPF]

Happy Coding!

Friday, May 25, 2012

Next, Please! - A Closer Look at IEnumerable (Part 5 - Usage Tips & Wrap-up)

This is a continuation of "Next, Please! - A Closer Look at IEnumerable".  The articles in the series are collected together here: JeremyBytes - Downloads.

Last time, we took a look at the Strategy pattern and then used that pattern to create a StrategicSequence that allows us to pass in whatever algorithm we want to generate the sequence.  This gives us an class that can be extended without modifying the class directly and gives the application (client) the opportunity to select which algorithm to use.

Today, we'll explore some tips for using classes that implement IEnumerable<T> (whether they are classes we create ourselves or classes from the .NET Framework).

IEnumerable<T> Tips
As we've seen, IEnumerable<T> is a fairly simple interface that gives us access to a lot of functionality.  But, there are a number of things we should take into consideration when we decide on how to use that functionality in our applications.

Tip: Don't Modify Collection Items in a foreach Loop
This is actually a "don't ever do this" rather than a "tip".  When using a foreach loop (or using the enumerator more directly), it is very tempting to modify the items as you are iterating them.  However, this only causes problems (some more obvious than others).

First, what happens if we try to add or remove an item in a foreach loop?  Consider the following code:


The idea behind this code is that we iterate through our people collection (with a foreach loop).  If the FirstName property of the person is "John", then we want to remove that person from the collection.  Then we want to add that person object to the list box of our UI.

But we are not allowed to add or remove items from a List<T> while we are enumerating it.  This code will compile just fine, but if we try to run it, we get the following Exception:
System.InvalidOperationException: "Collection was modified; enumeration operation may not execute."
So adding and removing items is not allowed.  What about modifying items?  That's where things get a bit interesting.  Let's look at the following code:


Inside the foreach loop, we first add the "person" to the list box of our UI.  Then if the FirstName property is "John", we change it to "Test".  We would expect that we would see the "John" items in the list box (since we add thems before changing them).  But here is the output:


As you can see, "Test" is showing up in our output!  This is not the output we would expect from this code.  The strangeness is a result of trying to update a collection while we are iterating that collection.

Based on these problems, we never want to modify a collection as we are iterating it.  In most situations, it is fairly easy to come up with another solution that accomplishes our same goals by handling the modification outside of the iteration.  Note: "for" loops do not exhibit this same issue since they do not use the enumerator; this is sometimes a good solution (but not always).

Tip: Avoid Creating A Custom Class
In our samples from Part 3 and Part 4, we created classes that return a sequence of numbers.  I purposely chose this type of sequence because we could base our "MoveNext()" on a calculation of some type.  In most situations, though, there is no need to create a custom class that implements IEnumerable<T>.

As mentioned in Part 1, almost every .NET collection implements the IEnumerable interface.  This includes arrays, generic lists, linked lists, queues, stacks, and dictionaries.  Generally speaking, if you find yourself in a situation where you need an IEnumerable implementation (because you need to iterate through a set of items), you will probably also need the more advanced collection functionality that you get with one of these framework classes.

In most scenarios, we should start by looking at the .NET collection classes.  One of these classes will mostly likely fulfill our needs.

Tip: Use a Custom Class to Hide Functionality
Sometimes the .NET collections have more functionality than we want to expose in our application.  For example, let's say that we need a collection that we can iterate through, but we don't want to use "List<T>" because we don't want the collection items to be directly modifiable.

Here's an example how we can use a custom class to wrap a List<T> object and hide its functionality:


We have a custom class that implements IEnumerable<T> (so we'll get our iteration functionality).  The class contains a private list that is not visible externally.  The list gets initialized by the class constructor.

Notice the GetEnumerator() method.  Instead of implementing our own IEnumerator<T> class or using "yield return", we are simply calling the internal list's GetEnumerator() method.  This is perfectly valid.  And it makes sense to do it in this situation -- the IEnumerator is already implemented by an object in our class, so there is no reason for us to create a custom implementation.

The result of this class is that we have a list of objects that we can iterate through, but we have no way to modify the collection externally.  Note that we are also hiding the other List<T> members in the private class (such as IndexOf), but we still have access to all of the IEnumerable<T> extension methods, such as Single() and Where(), if we are searching for particular items in the collection.

Tip: Use a Custom Class to Reduce Overhead
Sometimes we don't need all of the functionality provided by a collection object.  In that case, we can create a custom class that implements IEnumerable<T> that only has the functionality that we need.  This is exactly what we did with our sequence classes: IntegerSequence, FibonacciSequence, and StrategicSequence.

We did not need any of the overhead associated with a collection since our values are calculated as we need them.  Granted, our example is a rather contrived one.  But it demonstrates that it is possible and practical to have a class that implements IEnumerable<T> without other collection-type functionality.

IEnumerable<T> Review
The last several articles have shown a lot of different aspects of IEnumerable<T>.  Let's do a quick review:

IEnumerable<T> Interface Members
We started by looking at the IEnumerable<T> and IEnumerator<T> interfaces. We saw the methods and properties (such as GetEnumerator(), Current, and MoveNext()) that are specified in each.

Iterator Pattern
The Iterator pattern is described by the Gang of Four as a way to get items one-by-one from a collection -- "Next, Please!"  The IEnumerable<T> interface describes an implementation of this pattern.

foreach Loop
We can use a "foreach" loop to iterate through the items contained in any class that implements IEnumerable<T>.  This is an easier way to interact with the class then if we were to explicitly call the GetEnumerator() method along with MoveNext() and Current.

Extension Methods
Extension methods give us a way to add functionality to a class without modifying the class directly.  From a syntactic standpoint, extension methods behave as if they are native methods of the class.

IEnumerable<T> and LINQ
LINQ (Language INtegrated Query) provides us with a myriad of extension methods on the IEnumerable<T> interface.  This gives us the ability to write queries and perform all types of functions against any class that implements IEnumerable<T>, including (but not limited to) filtering, sorting, aggregation, and grouping.

Implementing IEnumerable<T>: IntegerSequence
Our first custom implementation of IEnumerable<T> let us take a look at the members of IEnumerable<T> and IEnumerator<T>.  We saw what each member is designed for, and we used the members to create a class that returns a series of consecutive positive integers.

yield return
"yield return" provides us with shortcut syntax when implementing an enumerator.  It lets us create a method that retains its state between calls.  Using this, we can mimic a full implementation of the IEnumerator<T> class with a single method.

Implementing IEnumerable<T>: FibonacciSequence
Our second custom implementation of IEnumerable<T> was a bit more complex.  We used what we learned from the simple IntegerSequence and created a class that returns the Fibonacci sequence, where each value is the sum of the previous two values.

Strategy Pattern
The Strategy pattern is described by the Gang of Four as a way to create a set of encapsulated, interchangeable algorithms.  We took a look at the advantages of using the pattern as well as some of the negative consequences.

The StrategicSequence Class
Our final custom implementation of IEnumerable<T> let us explore the Strategy pattern in a bit more detail.  The StrategicSequence class accepts a strategy (the algorithm for calculated the sequence) as a constructor parameter.  This lets us externalize the algorithms into separate classes.  We created the IntegerStrategy, FibonacciStrategy, and SquareStrategy that implemented these algorithms.  And we saw the advantages that this gave to our particular application.

Wrap Up
In summary: IEnumerable<T> is awesome!  Okay, I might be a little too excited about an interface, but it offers us a ton of functionality with very little effort.  Implementing the interface ourselves is not that difficult, and even better, there are lots of implementations already provided for us in the .NET framework.

I find myself using the LINQ extension methods all of the time.  It's so easy to just drop in a Where() method to do a filter of a collection, or an OrderBy() to sort the list, or a Single() to pick out a specific item. And all we need to take advantage of this functionality is a class that implements IEnumerable<T> and a good understanding of lambda expressions (but we've already got that, right?).

Hopefully you are as excited about IEnumerable<T> as I am (or at least a bit more interested than you were when we started).  Learning the features included in the .NET framework lets us take advantage of extremely powerful functionality that is already there just waiting for us.

Happy Coding!

Thursday, May 24, 2012

Next, Please! - A Closer Look at IEnumerable (Part 4 - Strategic Sequence)

This is a continuation of "Next, Please! - A Closer Look at IEnumerable".  The articles in the series are collected together here: JeremyBytes - Downloads.

Last time, we created the IntegerSequence and FibonacciSequence classes that both implemented IEnumerable<T>.  We saw how we could implement these with separate classes that implement IEnumerator<T> (IntegerEnumerator and FibonacciEnumerator) or with the "yield return" statement.

This time, we'll see how we can use the Strategy pattern to create a single IEnumerable<T> to which we can pass a specific sequence algorithm.  This will allow us to easily add other sequence algorithms in the future.

The sample code can be downloaded from here: JeremyBytes - Downloads.

The Strategy Pattern
The Strategy pattern is one of the Gang of Four design patterns.  Here is the GoF description of the Strategy pattern:
"Define a family of algorithms, encapsulate each one, and make them interchangeable.  Strategy lets the algorithm vary independently from clients that use it." [Gamma, Helm, Johnson, and Vlissides. Design Patterns. Addison-Wesley, 1995.]
This means that rather than having the algorithm hard-coded with the class, it is passed in (often as a constructor parameter).  This allows us to create different algorithms that are all interchangeable and can be used with the same class.

Benefits of Strategy
One of the benefits of the Strategy pattern is that it passes control of which algorithm will be used from the class to the client using the class.  This means that the client is responsible for picking which strategy to use and then passing it to the class that will use it.  We'll see how this works in just a bit.

The Strategy pattern also allows us to create multiple implementations of the same behavior.  This means that we can have different algorithms that ultimately perform the same function but have different priorities -- perhaps optimizing for speed or memory usage, depending on what is important to the client.  For example, a mobile application may want an algorithm designed to minimize network usage while an intranet application wants to maximize speed without a concern for usage of the internal high-speed network.

Consequences of Strategy
As we've discussed previously (Design Patterns: Understand Your Tools), design patterns have both pros and cons.  One of the consequences of the Strategy pattern is that the client must be aware of the different strategies that are available.  Often in non-strategy implementations, the client passes a string or enum to select an algorithm, but it has no direct knowledge of the algorithms themselves.  When using the Strategy pattern, the client is responsible for instantiating the strategy class, and so it must be aware of what classes are available.

Another consequence is that we generally end up with an increased number of classes.  As always, we need to weigh the benefits and consequences before we decide to implement a specific pattern.

Strategy and the Sequence Classes
What we saw in Part 3 is that the IntegerSequence and FibonacciSequence classes varied only in terms of the specific IEnumerator<T> concrete type that they "new" up.  This makes it a good candidate for us to create a more generic class and then pass in that concrete type.

The client will need to be aware of the various concrete types.  This is okay in our case because the client was already responsible for choosing the specific IEnumerable<T> concrete type.  With regard to having more objects, we are willing to accept this since we'll have isolated and easily-interchangeable classes.

As a reminder, the Strategy Pattern is a design pattern; it does not specify a particular implementation.  The implementation we use here is just one way to implement the pattern.  There are countless others.

The StrategicSequence Class
Let's do some planning before we implement the StrategicSequence class.  Let's start by looking at the IntegerSequence class from the last article:


To make this conducive to the Strategy pattern, we'll do a couple of things.  First, we will create a private variable for the strategy (which will mirror the IntegerEnumerator in this case).  Then we will update our constructor to accept that strategy as a parameter.

Things get a little more complicated here: we need to figure out how to get the "NumberOfValues" value into the strategy.  We could do this with the strategy constructor (like we have above in the IntegerEnumerator constructor), but this may not be the best choice.  What we will do instead is create a "NumberOfValues" property in the strategy that we can use to set this value.

IStrategicEnumerator Interface
Since each of our strategy classes needs to have a property for "NumberOfValues", it makes sense for us to create an interface that includes this property.  In the sample solution, the SequenceLibrary project contains a folder called StrategicEnumerators.  We'll add a new class under this folder: right-click the folder, select "Add", then "Class", then type "IStrategicEnumerator.cs" in the dialog.

Then we'll update the file as follows:


Notice that IStrategicEnumerator is an interface that also specifies the IEnumerator<int> interface.  This is so that we will get all of the properties and methods contained in IEnumerator<T> in addition to the NumberOfValues property.

IntegerStrategy Class
Next, we'll add our first strategy class that will implement the IStrategicEnumerator interface.  This will be "IntegerStrategy" that will mirror the functionality of the IntegerEnumerator class that we implemented last time.  (Note: if this were a "real life" application, we would probably just re-purpose the IntegerEnumerator class.  But in this case, we'll leave the original in tact so we can refer to the code if we want.)

Add the "IntegerStrategy" class under the StrategicEnumerators folder, add "using System.Collections", and specify the IStrategicEnumerator interface:


Just like last time, we'll right-click on "IStrategicEnumerator" and select "Implement Interface" to let Visual Studio stub out the properties and methods for us.  Note that the NumberOfValues property is implemented as well as the properties and methods of IEnumerator<T>.

After a little re-ordering, and converting "NumberOfValues" to an automatic property, we end up with the following:


For our implementation, we can copy from the IntegerEnumerator class that we created previously.  Here are the fields and properties (including "_position"):


And here are the methods:


Other than "NumberOfValues" being a property rather than a field, all of the other code is the same.

StrategicSequence Class
Now that we have our first strategy class, let's create the class that can use it.  The StrategicSequence class will allow us to pass in whichever concrete strategy that we want.

Follow these steps:
  1. Add the new "StrategicSequence" class to the root of the project.
  2. Add "using System.Collections".
  3. Add "using SequenceLibrary.StrategicEnumerators" (where IStrategicEnumerator is located).
  4. Make the class public.
  5. Specify that StrategicSequence implements "IEnumerable<int>".
  6. Implement the IEnumerable<T> interface.
That gets us a good start.  Let's look at the completed code:


Let's compare this to the original IntegerSequence.  First, we have a new private field to hold the strategy.  Next, we have the NumberOfValues property (just like before).  Then, the constructor takes both a strategy and the number of values, and it updates the appropriate class values.

GetEnumerator() is a bit different.  Here, we set the NumberOfValues property of the strategy based on the NumberOfValues property of our StrategicSequence class.  Then we return the strategy -- this is valid since the strategy implements the IEnumerator<int> interface.

This gives us a working sequence class that implements the Strategy pattern.

Using the StrategicSequence Class
Now let's flip over to the console application to see the output of our class.  We'll need to add a using statement for "SequenceLibrary.StrategicEnumerators" (since that is where our strategy class is).

Here's our updated code:


First, we create an instance of our strategy by calling "new IntegerStrategy()".  Then we create a new StrategicSequence and pass in our strategy and the number of values.  The rest of our code is exactly the same as before.

And we get the expected output:


But the advantage of using the strategy pattern is that we can create multiple algorithms that are all interchangeable.

Additional Strategies
Now that we get the idea, we can create additional strategies.  We won't go through all of the code details here since the implementations will mirror what we did with the IntegerStrategy.  You can check the download for the completed code.  The "Starter" solution contains these strategies in the "StrategicEnumerators" folder.  You can add them to the SequenceLibrary project, by right-clicking on the StrategicEnumerators folder, select "Add", then "Existing Item" and then locate the 2 files: FibonacciStrategy.cs and SquareStrategy.cs.

FibonacciStrategy contains the algorithm for the Fibonacci Sequence.  Again, this is very similar to the FibonacciEnumerator class that we implemented previously (with a few updates such as changing the _numberOfValues field to the NumberOfValues property).

SquareStrategy contains an algorithm that returns a series of squares (by returning "_position * _position").

Error Handling
The FibonacciStrategy and SquareStrategy classes contain a check ensure that we do not overflow Int32.  As we saw last time, this occurs after 47 values in the Fibonacci Sequence.  For the sequence of squares, this occurs after about 50,000 values.  We don't have to worry about this error check for the IntegerStrategy since there is a one-to-one relationship between the returned integer value and the total number of values returned (meaning, we can't overflow the return value without overflowing the NumberOfValues first).

As a side note, the reason that we are using "int" for the Fibonacci Sequence instead of a "long" is so that we will have the same generic type ("int") across all of our strategies.  We could change this to a "long" for all of our classes if we wish; I left it as "int" for simplicity.

Using the FibonacciStrategy
In order to use the FibonacciStrategy in our console app, we only need change the concrete type for our IStrategicEnumerator:


Which gives us the following output:


It is just as easy to switch this over to the "SquareStrategy".

Benefits of the StrategicSequence
We get a few different benefits from implementing the Strategy pattern in our StrategicSequence class.  First, our sequence class has been made extensible by abstracting out the algorithm (the "strategy").  This means that we can easily create new strategies for other sequences -- such as a a prime number strategy or even a random number strategy.

Next, the client (the console application in our case) gets to decide which strategy will be used.  Even though our console application is making this decision at compile time, we can easily move this decision to run time. Picture the following application:


In this case, we have a set of radio buttons that let us pick which algorithm we want to use to generate our sequence.  Based on this selection, the client will "new" up the appropriate strategy and pass it to the StrategicSequence class.  (Note: this application is not included in the code download; it is left as an exercise for the reader.)

Although the Strategy pattern is designed around having multiple strategies available for the client to select from, we can also think about how our code would work when using an Inversion of Control (IoC) container.  In this scenario, the container would be responsible for instantiating the appropriate strategy based on configuration (similar to how we handled dynamically loading a repository in the final sample of IEnumerable, ISaveable, IDontGetIt: Interfaces in .NET).  Then the strategy will be passed to the sequence class.

Things to Think About
There are a couple of things to think about regarding our implementation of the Strategy pattern.  The biggest concern is that the NumberOfValues property in the strategy is a publicly exposed property.  This means that we can alter this value directly in our client application -- including while the sequence is being generated.

Consider the following:


This results in the sequence returning 5 values instead of the originally-specified 12.

Another option would be to make NumberOfValues a constructor parameter (similar to our original FibonacciEnumerator class).  In this scenario, NumberOfValues could be a private field of the strategy class rather than a publicly exposed property.  It would be used as follows:


The advantage to this implementation is that we can no longer modify the NumberOfValues while the sequence is being iterated.  But there are a couple of disadvantages.  First, the usage is not as intuitive -- instead of passing the NumberOfValues to the StrategicSequence constructor, we pass it to the strategy object constructor.  This strikes me as being the wrong place for this value; it makes more sense to tell the sequence how many values you want rather than telling the strategy.

Another disadvantage is that you cannot put a constructor into an interface.  This means that by using interfaces, we cannot enforce that each strategy class would include a constructor with 1 parameter.  This would become a convention rather than something that would cause a compiler error.

Because of these disadvantages, I decided to go with the first option (the publicly exposed property).  I am willing to risk the possibility that someone would modify the sequence length based on the other options.  I'm sure that there are other options as well.  Be sure to drop me a note if you have a better implementation.

Next Time
Today, we took a look at the Strategy pattern and how we can use it to create a StrategicSequence.  This shifts the control of what type of sequence is generated to the client.  We also have an easy way to plug in new sequence algorithms.  Since StrategicSequence implements IEnumerable<T>, we still get all of the advantages of that interface.

Next time, we'll review the IEnumerable<T> interface, the advantages that the interface provides, and what we've done with various implementations of the interface.  Until then...

Happy Coding!