Refactoring to Patterns: Factory and Strategy Patterns

This is a hands on article on how to refactor to design patterns, in specific for this article, factory and strategy design patterns.

Introduction

Developers in .NET sometimes come from scripting language environments that are not strong on Object Oriented methodologies. OO methodologies like refactoring and using design patterns can be intimidating and the value for the developer is hard to see. What developers new to the OO world, and even more seasoned developers need to understand is that good design is not beyond scope in any project. Good habits simply must be learned that will make the developer a better designer.

In that mind set, I am submitting the first of several "how to" real world examples, used in my professional life, on how to use patterns in a simple, easy to follow manner. Many of us have ended up either writing or working on in-line, scripting based code. Taking some ideologies from refactoring methodology, this is not necessarily a bad thing. Of course, when you are first writing an algorithm or a series of logic statements, it seems easier to start with if....then....else. But as you continue to expand this code to more complex forms, this model can quickly become unmanageable. This is where refactoring and design pattern methodology can play an important and useful part in simplifying, enhancing and making code more useable (and understandable) to those who practice good OO design.

Using the code

This first effort will detail the use of a factory and several strategy patterns. I have a long series of if....then....else statements, that contain algorithms that can be broken into classes. These algorithms use data from outside the statements, and based on this data will execute separate logic statements from similar data.

The variable i is the switch or deciding logic for which the statement gets executed. Let us assume that the if....then....else block is quite long and has complex processing inside each statement. Let us also assume that i is a constant or a value that is not changeable outside of the parameters of the code.

The first logical step might be to extract the if....then....else algorithms out into classes, keeping in mind the rules of encapsulation, and making sure to pass into the class only those information which is absolutely needed. That is to say that if you are passing around a heavy data object, but use only a small amount of data from the parameters of that object, it stands to reason that the constructors of your new classes (or methods on that class containing your logic) would not accept the whole object, but only those parameter variable values that were absolutely necessary, keeping in mind that no state was needed to be maintained on the said object. This gives a more visible and obvious code flow, and prevents problems with unexpected modifications of the object or code.

But for this exercise, we are assuming that we are only passing around simple primitives, and no stateful object is implied. (If we were using a stateful object another design pattern might be more applicable, we will cover this in another article.)

First, since all our algorithm classes need a base structure to allow them to be called in a similar fashion, we need to create a parent or abstract class. This class allows us to create a very similar way to call different classes that contain different algorithm logic in a similar manner. We will use this functionality later, to allow these classes, which are the beginnings of strategy pattern classes, to be created in a factory class, that can generate the code as we need to use it. The methods on the strategy classes will pass back an integer, which is the result of the algorithmic computation.

Your strategy classes could pass back any data you wanted, access a database, modify a passed object somehow, or perhaps create different objects based on the algorithm. (for more information see the DoFactory site for PatternStrategy.) Generally though, in the strictest sense of the strategy pattern, your strategy should fulfill some logical work for whatever code is passed into it. Let's say each class from the if....then....else needs to perform simple arithmetic on the integer returned in a different way. Notice that we have inherited from AbstractArithmiticStrategy. This provides us with a way to call the same method when pulling from the factory (we will see the example later).

Note: Notice that we are using an attribute on each class. We will see in a little while why we are doing this.

Now we have broken our algorithm code out from the if....then....else and are only passing in the needed data, satisfying the requirements of good encapsulation. But we still need a way to decide how to render the right code at the right time. Since we know the variable i is always going to be a value we expect, let's convert the known values of i to an enum. This will provide us with a structured way to pass the variable value to the factory, and allows the factory to decide on the value of the enum which algorithm class to procure to the executing code. We can also use an attribute class to help the factory decide which class type to render:

Here we have the factory code. As you can see we register our known algorithm classes with the factory at compile time. This is done to procure the class types, so we can use reflection typing to render our classes from the factory. We pass in the enumAlgorithmType and check it against the attribute on each class:

This code looks very different from what we started with. First it is one line. Second if we wished we could move this code to another area in which we needed the same processing easily, and expect the same functionality (based on the values of x and y). Of course there was a lot of work to get to this point, and when you are refactoring code, you have to evaluate whether doing refactoring in some areas is worth the effort. Remember design patterns are only templates or ways of designing the code to make it more workable and maintainable, but you as the designer are going to have to decide what pattern if any works for you in different instances. Whenever you refactor, remember you should start with the smallest changes first, and make small refactorings, the sum of which lead to a better overall design of code.

Points of interest

This is the first installment in the series I am writing on real world design patterns. All examples and the bulk of this article are taken from my professional experience as an architect. The examples given are templates only, and the designer must keep in mind that they are the ones who must decide where different patterns, if any, may be best used in their code.

Deciding to perform a refactoring effort from the existing code to a pattern must be weighed on the necessity and need of the code itself. Patterns are only design templates, helpers to accommodate better overall design. I must stress that making an effort to use patterns will strengthen your overall design ability, but like your basic coding skills, it is something that is to be learnt and cultivated.

If this or any other in this series on design patterns is helpful or you have questions or comments please e-mail me at chris.lasater@gmail.com.

History

This is the first article submission in a series that I am writing to CodeProject on this subject and is the first revision. Look for other articles on design patterns coming soon.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

This is a very good question. So let me try and answer you in a way which merits the question. While your point is valid, I think a wider view of a particular problem is needed to give an answer. While there is a place for a boolean statement and you could use a boolean statement to accomplish this, try and think of this pattern in conjunction with other code, that is more dynamic. Lets say for instance that you want from your factory a particular type depending on a particular user flow. What I am talking about is how to make your code in such a way so that the most flexible part of a program, the user, will be able to interact with the code and have the code be interactive as well. Sure we could code a bunch of if..then..else statements, but we have a maintenance issue (In my new book I detail this), what if you wanted to add new strategies in configuration data? Also using a strategy is better class encapsulation than using if..then..else, hence easier scoping and maintenance. Clear as mud? Remember this is so you can write and maintain less code. Lets say a web control needs a particular algorithm to do a job (like displaying a format). And there are other controls that need the same algorithm. You obviously don't want to maintain this in multiple places. But lets say depending on the type of control or a property on the control that might be differnt in different places, you need a differnt algorythm. SO by setting the 'AlgorithmType' on the control, you get the right algorithm. Get it?

This is good. I've read about design patterns, but one really needs most of times a working implementation with a familiar language to see how the patterns actually form. This is good instead of reading about this stuff in some c++ or pseudo language. Thanks.

It would be great if you included image about the pattern as you did in your other articles.

I have some thoughts though, which I would like to get your feedback on. The enumeration just doesn’t seem right, neither does the register class (these are personal hunches). The enumeration has to be updated if you were to add a new arithmetic class e.g. mod, and the register class is doing typesafe checking.

Anyway, here are the thoughts:

Instead of doing the type check in the RegisterClass function create a type safe ArrayList instead (more work, but better practice)
Get rid of the enumeration and create an AlgorithmType as part of your AbstractArithmeticStrategy Class , then remove the attributes and your Create function then becomes very simple I.e. return _registeredImplementations(algorithmType)
This has the added benefit of bringing your enumeration constants and your subclasses into one class (increasing cohesion)

I’d love to get your thoughts on this.

Best Regards

Mark Grant

Technical Director

Cambridge Convergence Limited

Hi Mark,
Thanks for your interesting comments! That is always a possibility,
but remember, this is just an example to lead developers new to OO
into pragmatic design, not actual functional code.
I agree that doing a strongly typed arraylist would be a better way to
do the arraylist, but as you said, more work, and this example was
written just to get the basic idea of the pattern down. As well the
factory pattern I listed is not an exact example of a strict factory,
although it does perform the function. I based this one a generic way
that many others have done Factories using attributes in the past.
As far as your idea about changing the attribute, I didn't quite
follow why you think that was more effcient. You could check the type
of the class, of course, but what would you pass into the factory? I
would like to see some code examples of your ideas.