Menu

Fluent API vs. named arguments for readability

Fluent APIs are great to make code readable - should I say, at the expense of verbosity? Because verbosity is, actually, one of the positive traits of being fluent. It is very useful in complex and hard to follow scenarios like data transformation (think LINQ), configuration, testing etc., leading the developer to the solution but also documenting what's going on.

One example: I have a LINQ-like method that processes an array. It takes as parameters a criterion for determining duplicates and separate operations for new and repeated entries. It could look like this:

list.DuplicateAwareSelect
(
    r => r.Name.Trim(),
    x => new Entry() { Name = x.Name.Trim(), Date = x.Date },
    (a, b) => { b.Date = a.Date > b.Date ? b.Date : a.Date; }
);

But it isn't obvious what's going on here... The code isn't descriptive at all - and only partially due to the fact that the variable naming scheme stinks. If we make it fluent, the purpose is much clearer:

list.DuplicateAwareSelect()
    .WithKey(r => r.Name.Trim())
    .SelectFirstAppearance(x => new Entry() { Name = x.Name.Trim(), Date = x.Date })
    .ProcessRepeatedAppearance((a, b) => { b.Date = a.Date > b.Date ? b.Date : a.Date; });

But what is the real difference here? In the second example we introduced methods just to describe the parameters from the first example. These parameters had names, though, didn't they, and in this respect the biggest flaw of the first example was that they were invisible. But, we can make them visible using named arguments. Like this:

list.DuplicateAwareSelect
(
    key: r => r.Name.Trim(),
    selectFirstAppearance: x => new Entry() { Name = x.Name.Trim(), Date = x.Date },
    processRepeatedAppearance: (a, b) => { b.Date = a.Date > b.Date ? b.Date : a.Date; }
);

Arguably, this makes the code as readable as the fluent example - aesthetic concerns aside. Of course, fluent can be much more powerful than this and allow more flexibility by providing different methods for different scenarios. But, when describing parameters is the primary concern, named arguments may work just as well.

Naturally, standard rules for code readability also apply, and the first one is naming. If we give descriptive names to arguments, we get something like this:

list.DuplicateAwareSelect
(
    key: sourceRow => sourceRow.Name.Trim(),
    selectFirstAppearance: sourceRow => new Entry() { Name = sourceRow.Name.Trim(), Date = sourceRow.Date },
    processRepeatedAppearance: (sourceRow, previousEntry) => { previousEntry.Date = sourceRow.Date > previousEntry.Date ? previousEntry.Date : sourceRow.Date; }
);

This could be enough for someone familiar with the API to understand the intention.

New site, new technology, old blog

Just a short notice: We have migrated our site to different technology (from WordPress to Joomla K2) and new design. I think I managed to reconstruct all blog posts and comments so it should work as before. Of feed URLs I'm not sure, I added a redirection for the main feed but category and comment feeds are probably unusable, so please update to new ones. If you find something wrong with the blog, please contact us at office (at) 8bit.rs.

Building customizable applications in .Net

Most modern applications today have at least some degree of modularity and customizability. By customizability I mean its simplest form - having one “vanilla” application with standard features and many derived versions adapted with minimal modifications to customer’s needs. It is common practice to use dependency injection (DI) and with it we can influence the behaviour of our application by being able to replace one component with another. But DI alone does not provide everything needed to make the application truly customizable. Each aspect of an application needs to support modularity and customizability in its own way. For example, how do you maintain a customized relational database?

This post is intended to be the first of a series regarding issues and solutions we found developing our own customizable application, a kind of an introduction to the subject so that I can write about concrete solutions to concrete problems, as/when they pop up. Here I’ll give an overview of the general architecture, problems and possible solutions.

Our product is a .Net WinForms line-of-business application. I think WinForms is still the best environment for LOB apps as the others are still not mature enough (like WPF) or simply not suitable (like the web). I would say it’s also good for customizability because it doesn’t impose an overly complex architecture: customizability will make it complex by itself.

As I said, DI fits naturally at the heart of such a system. DI can be used for large-grained configuration in the sense that it can transparently replace big components with other components implementing the same features. It’s generally suitable for assembling interfaces and possibly bigger parts of the business logic. It’s not very suitable for a data access layer: even if you used a superfast DI container that puts no noticeable overhead when used with thousands of records, that would be just part of the solution. A bigger question would be how you can customize queries or the database schema. So, for data access we need a different solution, and I believe that this part of the puzzle is the most slippery since it’s so heterogeneous. Firstly, there’s usually the relational database that’s not modular at all: how do you maintain different versions of the same database, each with part of its structure custom-built for a specific client? (It would be, I suppose, a huge relief if an object-oriented database was used, but this is rarely feasible in LOB). Then, there are SQL queries which you cannot reuse/override/customize unless you parse the SQL. Then the data access classes, etc.

Get content from WPF DataGridCell in one line of code (hack)

How do you get the text displayed in a WPF DataGridCell? It should be simple, but incredibly it doesn’t seem it is: all the solutions given on the ‘net contain at least a page of code (I suppose the grid designers didn’t think anyone would want to get the value from a grid cell). But when you quick-view a DataGridCell in the debugger, it routinely shows the required value in the “value” column. It does this by calling a GetPlainText() method, which, unfortunately, isn’t public. We can hack it by using reflection – and, absurdly, this solution seems more elegant than any other I’ve seen.

DataGridCell cell = something;

var value = typeof(DataGridCell).GetMethod("GetPlainText", 
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.Invoke(cell, null);
Subscribe to this RSS feed