Posts tagged with refactoring

Where developer is succinct

Radio 4 covered the The Six Word Memoir competition, inspired by Earnest Hemingway’s wager he could tell a complete story in just six words. He deliciously delivered “For sale: Baby shoes, never worn” earning him $10.

Expressing a life story in six words is just as tricky. Some of my favorite submissions include:

Found true love, married someone else. B. Stromberg

Work smart. Love what you do. Michael Scala

A limit on words means getting straight to the point – Twitter’s 140 character limit results in short useful extracts.

Short succinct messages require more thought, careful editing and of course time. Getting the balance right between losing important information and the laws of diminishing returns takes practice and is very dependent upon the mix and size of your audience.

As a developer I find these skills applicable to the following areas:

Blog posts

I’m not the world’s most prolific blogger but my posts tend to be short and to the point. If you didn’t find it interesting you should have realized quite quickly.

Being well-written and interesting gives a better chance of being added to StumbleUpon, Digg or other blogs.

Presentations

My latest presentation on LINQ consisted of around 20 logically-grouped slides with a few bullet points and tiny code samples.

I saved time by not writing a script and let the talk flow more naturally with interaction from the audience. This meant the audience chose the programming language and I broke into demos once they looked anxious to see it.

Code

My own projects change design dramatically during prototyping thanks to refactoring and the great tools available. It is for this reason I do not practice test-driven development.

I need my code and design to be as succinct as possible at this phase. Unused code, interfaces or stubs are wasted words. Verbosity. Declarations that are read and compiled but not used. Verbosity.

Once the overall design is settled the unit tests and fleshing out of functionality comes.

Where extensibility is needed I work with those who will consume it to ensure the interface does what is required and nothing more. Three consumers is quoted as the magic number.

This is also why I am so keen on extension methods and other simple expressions of intent.

Going forward

If anyone has any tips, informative articles or recommended books on succinct writing please leave them here.

Now if only I could get this post down to six words…

[)amien

Refactoring shared libraries and public APIs

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:

public string Reference {
  get { return id; }
}

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:

[DeprecatedRefactorRename("StockCode", "1.1.0.0")]
public string Reference {
  get { return StockCode; }
}

public string StockCode {
  get { return id; }
}

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.

Nice. Let’s try a few more:

Remove Parameters

public bool AddStock(int quantity, DateTime arrival, StorageBin location) {
   ...
}

We are switching to a managed warehouse and so we no longer need to know where items are stored so we refactor and remove the StorageBin.

[DeprecatedParameterRemoved("location", "1.1.0.0.")]
public bool AddStock(int quantity, DateTime arrival, StorageBin location) {
  return AddStock(quantity, arrival);
}

public bool AddStock(int quantity, DateTime arrival) {
  ...
}

Reorder Parameters

[DeprecatedParametersReordered("arrival, quantity", "1.1.0.0.")]
public bool AddStock(int quantity, DateTime arrival) {
  return AddStock(arrival, quantity);
}

public bool AddStock(DateTime arrival, int quantity) {
  ...
}

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.

[DeprecatedMethodMoved("StockController", "Add", "1.1.0.0")]
public bool AddStock(DateTime arrival, int quantity) {
  return stockController.Add(this, arrival, quantity);
}

Let’s say the current calling code looks something like:

stockController.DoSomething();
selectedProduct.AddStock(DateTime.Now, input.Value);

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:

stockController.DoSomething();
stockController.Add(selectedProduct, DateTime.Now, input.Value);

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.

[)amien