• Advertisement
  • entries
    146
  • comments
    436
  • views
    198319

Refactoring, Part 3

Sign in to follow this  

182 views

After my brief hiatus, I'm back...and eviler than ever.

Now, we have managed to refactor the code to a point where further refactorings will end up changing the public interface. In this case that isn't such a bad thing, as we have complete control over the whole source. In a larger project, however, we might find that modifying the public interface is a no no. Such is life. But, since in this case we can modify the whole source, we'll do such refactorings. If nothing else, it will demonstrate some interesting solutions to a few problems.

Looking over the AccessListEntry class, you should note that if we were to remove the sourceAddress member, or the destinationAddress member, then the associated mask would no longer be needed. The MatchAddress() method would also no longer be needed. This is a clear sign that we should refactor these out to their very own class. But first we need to define this class. The class should have two fields, a networkAddress and a networkMask. It should also have a Match() method, and a ToString() method. We shall call it NetworkMaskPair.

First we define the class to take two parameters in it's constructor, the network address and the network mask. We store these values in their associated fields. Then we apply the move method refactoring to the MatchAddress() method in the AccessListEntry class. Next we apply the rename method refactoring to change it from MatchAddress to Match, since the address portion is redundant. Be sure to run your tests often as you make these refactorings. We then add a ToString method which just returns a string composed of the two IP addresses. At this point we are now ready to remove the IP address fields from our AccessListEntry class, and replace them with NetworkMaskPair instances. Continue refactoring out the IP address fields as necessary to expedite their removal. At this point, our public interface hasn't changed any. However, we can now refactor the constructors to remove the extraneous IP address parameters, replacing them with NetworkMaskPair instances. Be sure to write tests for this new class to verify that it's behavior is correct.

And now our new class:
Quote:

public class NetworkMaskPair {
public static readonly NetworkMaskPair Any = new NetworkMaskPair(IPAddress.Any, IPAddress.Any);

public static NetworkMaskPair CreateHostPair(IPAddress hostAddress) {
return new NetworkMaskPair(hostAddress, IPAddress.None);
}

public NetworkMaskPair(IPAddress networkAddress, IPAddress networkMask) {
if (networkAddress == null)
throw new ArgumentNullException("networkAddress");
if (networkMask == null)
throw new ArgumentNullException("networkMask");

this.networkAddress = networkAddress;
this.networkMask = networkMask;
}

public bool Match(IPAddress ip) {
byte[] ipBytes = ip.GetAddressBytes();
byte[] addressBytes = networkAddress.GetAddressBytes();
byte[] maskBytes = networkMask.GetAddressBytes();
for (int i = 0; i < ipBytes.Length; ++i) {
if ((ipBytes & maskBytes) != (addressBytes & maskBytes))
return false;
}
return true;
}

public override string ToString() {
return networkAddress + " " + networkMask;
}

private IPAddress networkAddress;
private IPAddress networkMask;
}
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement