Posts tagged with c - page 9

Refactoring is an essential process to keep code clean and elegant while it evolves. IDE’s offer common refactorings (although somewhat short of those prescribed in Fowler’s excellent Refactoring book and way short of the overall goals explained in Kerievsky’s Refactoring Patterns).

One limitation of existing tools is that they can only update references within your solution. When you are refactoring a shared library this is a problem, especially if it is your public API to the outside world.

We need to introduce metadata to document how the API has evolved and extend the tools to generate and understand this metadata.

Let’s take a look at a few of the refactoring in Visual Studio and see how they could be documented using the .NET metadata mechanism of choice, attributes.

Rename

Starting simple lets we had a property named Reference:

publicstringReference{get{returnid;}}

We are going to rename Reference to StockCode for the 1.1.0.0 release. The tool could introduce a stub for backward compatibility whilst also marking it with metadata giving us:

The library is both binary and source compatible but with a little IDE work they could get a warning that Reference is now StockCode and given the choice of updating all the references in their project.

Reorder Parameters

Move Method

Existing tools offer little support for MoveMethod because they haven’t considered how to refactor the references. It is difficult to retain binary compatibility unless the class has a reference to class that now has the method we are interested in.

However with a little ingenuity the IDE could examine the new method and map existing parameters based on name and type. If it still doesn’t have enough information consider local variables and properties of the objects it does have to present choices. This works especially well if your parameters are not primitives. Our code becomes:

Keeping it clean

We don’t want our classes being cluttered with deprecated code indefinitely so the solution should contain two extra revision numbers, one detailing the oldest revision of attributes to keep in the source, the other for the oldest revision to compile into the binary. All the [Deprecated] marked methods and properties can slip into another file, perhaps Product.deprecated.cs so they stay out of sight until needed.

For .NET it would need somebody at Microsoft to take this on board and move us forward from ObsoleteAttribute as the facility should be cross-tool and so adding it solely to SharpDevelop would be of limited gain.

By integrating query into the language instead strings parsed by an external provider at runtime we gain IntelliSense prompting for fields, members and table names and full compile-time syntax checking and a unified syntax.

They will be included in the .NET Framework 3.5 and delivered as part of the Visual Studio 2008 ‘Orcas’ release which is currently available in beta and comprises of:

LINQ syntax

LINQ to Objects

A core part of the .NET Framework 3.5 and allows you to query against any IEnumerable collection and test or sort against any of T’s properties.

In the above example imagine Country is a business class and Countries is a List. Continent is a string property and population a numeric one.

LINQ to SQL (formerly known as DLinq)

LINQ to SQL works by mapping classes and properties to tables and fields as any normal Object-Relational Mapping (ORM) tool would.

It achieves this by marking the classes and properties with attributes to indicate how they map to the underlying database. A visual modeling tool is provided that can generate and manipulate such classes for you from an existing SQL database.

The ORM functionality includes tracking of changed objects and change persistence. It also ensures that you will not obtain multiple objects for the same underlying row in the database (Fowler’s Identity Map).

If the accepted mantra is that your object should expose interfaces and delegate the implementation of those interfaces elsewhere then it could really do with some better support than .NET currently offers especially where the interface comprises more than a member or two.

Consider the following fragment of a class for customer price-lists (properties and methods omitted). We decide to support IList so that consumers of our class can add, remove and iterate over the prices in a familiar manner (principle of least surprise).

Implement interface

Visual Studio offers some assistance where you can choose Implement interface _IList_ which gives you all the method definitions with the very unhelpful body of throwing an exception of “This method or operation is not implemented”. It requires some work to fill in all these definitions to something that works:

This works but means CustomerPriceList can not control any of the IList implementation such as validation.

Methods may also start accepting IList instead of CustomerPriceList because developers imagine the parts to be more decoupled than they actually are and are encouraged to code to interfaces not concrete classes.

Refactoring away from this at a later date would require a IList wrapper than delegated calls back to the containing class to prevent an interface-breaking change.

Introduce interface to declare IList available

Add an interface that signifies a IList can be obtained by calling the named method, e.g.

publicinterfaceIListable<T>{IList<T>GetList();}

This is a similar pattern to that of IEnumerable and IEnumerator whereby one interface signifies the availability of the other. In this example our class would look like:

Which is less code, a closer adherence to single responsibility principle (SRP) and the ability to change without breaking the interface although it still does nothing to prevent passing IList or IListable interfaces where CustomerPriceList would be more suitable. An IPriceList class could be introduced although it starts to feel like abstract infinity.

Improved support from .NET

I’d really like to see .NET improve on the support for interfaces and composition, like perhaps the following:

The solution which I have been using since my .NET 1.1 days is much simpler still and involves nothing more than creating a plain class with properties for every session variable and a static get accessor that obtains or creates it on the HttpContext similar to a singleton.

Here’s an example with the important Current property (slightly cleaned up and improved for this post ;-)