Tag-Archive for ◊ Resharper ◊

Tuesday, June 28th, 2011

You may have come across code that creates a new instance of an object and setting it to a default state before working on it. Sometimes however the creation requirements of this object may grow and clouds the original code that was used to create the object. This is where a Factory class comes into play. For e.g. have a look into the below given test cases and classes.

[TestMethod]
public void ZoomLensesCanHaveMacroModeAlso()
{
const string lensDescription = “Canon EF-S 55-250mm f/4.0-5.6 IS Telephoto Zoom Lens”;
var zoomLens = new ZoomLens(lensDescription);
zoomLens.SetCloseupConversion(true);
Assert.IsTrue(zoomLens.HasMacroMode());
}
[TestMethod]
public void WideAngleLensesHaveUltraWideView()
{
const string lensDesription = “Canon EF 35mm f/2 Wide Angle Lens”;
var wideAngleLens = new WideAngleLens(lensDesription);
wideAngleLens.SetUltraWideView(true);
Assert.IsTrue(wideAngleLens.HasUltraWideView());
}
The classes used in the sample are as given below.
public class ZoomLens
{
private readonly string _lensDescription;
private bool _closeUpConversionEnabled;
public ZoomLens(string lensDescription)
{
_lensDescription = lensDescription;
_closeUpConversionEnabled = false;
}
public void SetCloseupConversion(bool closeUpConversion)
{
_closeUpConversionEnabled = closeUpConversion;
}
public bool HasMacroMode()
{
return _closeUpConversionEnabled;
}
}
public class WideAngleLens
{
private readonly string _lensDesription;
private bool _enableUltraWideView;
public WideAngleLens(string lensDesription)
{
_lensDesription = lensDesription;
_enableUltraWideView = false;
}
public void SetUltraWideView(bool enableUltraWideView)
{
_enableUltraWideView = enableUltraWideView;
}
public bool HasUltraWideView()
{
return _enableUltraWideView;
}
}
As you can see from the classes used in the sample, I can implement a class hierarchy by creating a superclass or an interface for the camera lenses and move the common methods to that type and make the subclasses implement/ inherit the superclass. This provides the situation for usage of a Factory method that makes it easy for programmers to extend the functionality of the framework by introducing polymorphic creations of objects.
First we need to extract all common methods and properties of these classes to a common base class. I have used the Extract Superclass refactoring to create a superclass for the classes in this sample.
After extracting the superclass, we need to create the constructor for the base class with the common properties.
public class CameraLens
{
protected string _lensDesription;
public CameraLens(string lensDescription)
{
_lensDesription = lensDescription;
}
}
Refactor the base class to use this constructor during object creation.
public WideAngleLens(string lensDesription) : base(lensDesription)
{
_enableUltraWideView = false;
}
Use the Pull members refactoring to move the methods as abstract to the parent class.
Repeat the steps for other inheriting classes also. Compile and run the test cases.
Next use the Extract Method refactoring to move the creation logic to creation methods in the test cases.
After applying the refactoring pattern the code looks like
public void ZoomLensesCanHaveMacroModeAlso()
{
const string lensDescription = “Canon EF-S 55-250mm f/4.0-5.6 IS Telephoto Zoom Lens”;
CameraLens zoomLens = CreateCameraLens(lensDescription);
zoomLens.SetCloseupConversion(true);
Assert.IsTrue(zoomLens.HasMacroMode());
}
private static CameraLens CreateCameraLens(string lensDescription)
{
return new ZoomLens(lensDescription);
}
Use the Move to another type refactoring pattern and specify the name of the new class in the type as given below
Make the Create method non- static and use the Extract Interface refactoring as given below.
Now you can use this interface as a dependency for your client classes that needs to create the Camera lenses or change the test cases as given below
private ICameraLensFactory _zoomCameraLensFactory;
[TestInitialize]
public void Initialize()
{
_zoomCameraLensFactory = new ZoomCameraLensFactory();
}
[TestMethod]
public void ZoomLensesCanHaveMacroModeAlso()
{
const string lensDescription = “Canon EF-S 55-250mm f/4.0-5.6 IS Telephoto Zoom Lens”;
var zoomLens = _zoomCameraLensFactory.CreateCameraLens(lensDescription);
zoomLens.SetCloseupConversion(true);
Assert.IsTrue(zoomLens.HasMacroMode());
}
Tuesday, June 21st, 2011
When you have a method with lots of conditional logic (i.e., if statements), you’re asking for trouble. Conditional logic is notoriously difficult to manage, and may cause you to create an entire state machine inside a single method. In such a situation, it is better to move each algorithm variation to new classes or to subclasses of the host class. The ideal solution would be to replace these conditional statements with a strategy implementation and delegate the execution to the concrete strategy implementations.
For e.g consider the test code and Calculator implementation given below. The execute methods runs a different algorithm based on the operator chosen.
[TestMethod()]
public void ExecuteMethodShouldCalculateTheSumIfOperationSelectedIsAddition()
{
var calculator = new Calculator();
calculator.SetOperation(Operator.Add);
var result = calculator.Execute(3, 5);
Assert.IsTrue(result == 8);
}
[TestMethod]
public void ExecuteMethodShouldCalculateTheDifferenceIfOperationSelectedIsSubtraction()
{
var calculator = new Calculator();
calculator.SetOperation(Operator.Subtract);
var result = calculator.Execute(3, 5);
Assert.IsTrue(result == -2);
}
[TestMethod]
public void ExecuteMethodShouldCalculateTheMultipledResultIfOperationSelectedIsMultiplication()
{
var calculator = new Calculator();
calculator.SetOperation(Operator.Multiply);
var result = calculator.Execute(3, 5);
Assert.IsTrue(result == 15);
}
[TestMethod]
public void ExecuteMethodShouldCalculateTheDivisionResultIfOperationSelectedIsDivision()
{
var calculator = new Calculator();
calculator.SetOperation(Operator.Divide);
var result = calculator.Execute(15, 5);
Assert.IsTrue(result == 3);
}
public class Calculator
{
private Operator _operator;
public void SetOperation(Operator operation)
{
this._operator = operation;
}
public int Execute(int firstArgument, int secondArgument)
{
if(_operator == Operator.Add)
return firstArgument + secondArgument;
if (_operator == Operator.Subtract)
return firstArgument – secondArgument;
if(_operator == Operator.Multiply)
return firstArgument * secondArgument;
if (_operator == Operator.Divide)
{
if (secondArgument != 0)
return firstArgument / secondArgument;
else
throw new ArgumentException(“Divider cannot be zero”);
}
return 0;
}
}
public enum Operator
{
Add,
Subtract,
Multiply,
Divide
}
  • As a first step to refactoring this code, we use the Extract Method to extract the logic to separate methods as given below.
  • Once you have completed all the extractions the code now looks like.
public int Execute(int firstArgument, int secondArgument)
{
if(_operator == Operator.Add)
return PerformAdd(firstArgument, secondArgument);
if (_operator == Operator.Subtract)
return PerformSubtraction(firstArgument, secondArgument);
if(_operator == Operator.Multiply)
return PerformMultiplication(firstArgument, secondArgument);
if (_operator == Operator.Divide)
return PerformDivision(firstArgument, secondArgument);
return 0;
}
private int PerformDivision(int firstArgument, int secondArgument)
{
if (secondArgument != 0)
return firstArgument / secondArgument;
else
throw new ArgumentException(“Divider cannot be zero”);
}
private int PerformMultiplication(int firstArgument, int secondArgument)
{
return firstArgument * secondArgument;
}
private int PerformSubtraction(int firstArgument, int secondArgument)
{
return firstArgument – secondArgument;
}
private int PerformAdd(int firstArgument, int secondArgument)
{
return firstArgument + secondArgument;
}
  • Next we use the ‘Move to another type’ refactoring to move these methods to separate classes, which we’ll make as concrete strategy implementations later.
  • After this refactoring your code looks like
public class Calculator
{
private Operator _operator;
public void SetOperation(Operator operation)
{
this._operator = operation;
}
public int Execute(int firstArgument, int secondArgument)
{
if(_operator == Operator.Add)
return AdditionStrategy.PerformAdd(firstArgument, secondArgument);
if (_operator == Operator.Subtract)
return SubtractionStrategy.PerformSubtraction(firstArgument, secondArgument);
if(_operator == Operator.Multiply)
return MultiplicationStrategy.PerformMultiplication(firstArgument, secondArgument);
if (_operator == Operator.Divide)
return DivisionStrategy.PerformDivision(firstArgument, secondArgument);
return 0;
}
}
  • Use the ‘Rename’ refactoring to change the name of PerformAdd, PerformSubtraction.. methods to Execute.
  • After renaming we’ll use the ‘Extract Superclass’ refactoring to create a superclass for these Strategies.
  • Now create an abstract method Execute with the same signature as in the base classes in the newly created superclass.
  • Use the resharper intellisense to make the superclass abstract.
  • Now move to the subclasses and make the execute method override, using the resharper menu.
  • Finally create a new Factory implementation to create concrete instances for these strategies based on the parameter passed and use this in the Calculator class as given below.
public int Execute(int firstArgument, int secondArgument)
{
var operationStrategyFactory = new OperationStrategyFactory(_operator);
var operationStrategy = operationStrategyFactory.Create();
return operationStrategy.Execute(firstArgument, secondArgument);
}
Monday, June 20th, 2011
Replacing your constructors with creational methods or static factories helps to reduce cumbersome code with multiple overloaded constructors in the class and clients having confusion which one to invoke and how. The overloaded constructors in your code creates confusion in the mind of a fellow programmer when he wants to create a new instance of the object, the main problem with these constructors are that they cannot be renamed to give a meaningful name. One of the easiest ways to address this problem is to use creation methods or static factories.
Creation methods have better readability and by having meaningful names so that the consumer gets a clear idea of each method and when to use them. Let’s see how we can use refactoring to remove overloaded constructors in the code and replace them with creation methods.
  • As a first step of refactoring find the client code that calls the constructor to create an instance of the type.
[TestMethod]
public void AllDucksCanSwimTest()
{
var pool = new Pool(_ducks);
Assert.IsTrue(pool.CanAllDucksSwim());
}
  • In the above test method I have a constructor for instantiating the Pool object, which we can refactor to create a new creation method.
  • Use the Extract method refactoring to create a new static method to get the Pool instance
  • Now use the Move to another Type refactoring to move the method to the Pool class.
public class Pool
{
private readonly IList<Duck> _ducks;
public Pool(IList<Duck> ducks)
{
_ducks = ducks;
}
public static Pool GetPool(List<Duck> ducks)
{
return new Pool(ducks);
}
public bool CanAllDucksSwim()
{
foreach (var duck in _ducks)
{
duck.Swim();
}
return true;
}
public bool CanAllDucksQuack()
{
foreach (var duck in _ducks)
{
duck.Quack();
}
return true;
}
}
public class Pool
{
private readonly IList<Duck> _ducks;
Pool(IList<Duck> ducks)
{
_ducks = ducks;
}
public static Pool GetPool(List<Duck> ducks)
{
return new Pool(ducks);
}
public bool CanAllDucksSwim()
{
foreach (var duck in _ducks)
{
duck.Swim();
}
return true;
}
public bool CanAllDucksQuack()
{
foreach (var duck in _ducks)
{
duck.Quack();
}
return true;
}
}
  • Compile the code and make sure that it builds successfully.