Posts tagged ‘patterns’

LINQ 201 – Changing the way I work with lists

LINQ brings the set-based power of SQL-like syntax to VB.NET  and C#.  I thought I’d highlight some of the ways this has changed and simplified my code.

Find an element in a list

Pre-LINQ:
function FindItem(key as string)
  For each item in myList
    if item.Key = key then return item
  Next
end function
 
dim foundItem = FindItem(key)
if foundItem isnot nothing then
  ...process item
else
  ...not found
end if
Post-LINQ:
dim foundItems = from item in MyList where item.Key = key
if foundItems.Any then
  ...process item (foundItems.First)
else
  ...not found
end if

Find matching elements in a list

Pre-LINQ:
dim newList = new List(Of SomeClass)
for each item in oldList
  if item.SomeField = "Foo" then newList.Add(item)
next
Post-LINQ:
dim newList = from item in oldList where item.SomeField = "Foo"

Convert a list of items of one type into another

Pre-LINQ:
dim newList = new List(Of NewType)
for each item in oldList
  dim newItem = new NewType
  newItem.Field1 = item.FieldA
  newItem.Field2 = item.FieldB
 
  newList.Add(newItem)
next
Post-LINQ:
dim newList = from item in oldList _
  select new NewType with _
  {.Field1 = item.FieldA, _
   .Field2 = item.FieldB}

Sorting a list

Pre-LINQ:
Way too hard. Suffice to say it involved creating a new IComparer class or
implementing IComparable in the existing class
Post-LINQ:
dim sortedList = from item in myList _
  order by item.Field1

(or you could use lambda expression, but I find the above more readable)

Exception Handling 101

  1. In some older languages, the runtime was not able to expose a call stack when exceptions occurred. This led to programmers spattering the code with exception handling-code, so that they would have a better idea of where exceptions occurred.
  2. Historically, programmers have sometimes used exceptions to communicate status.

The above 2 ways of doing things are no longer appropriate.

First, in a language which exposes an exception call stack (like C# or VB.NET), the only place you need an exception handler is at the top-most point of a thread. So, you need a try…catch around your application entry point (Main sub), and around every new thread you manually spawn.

Second, using exceptions to communicate status is a terrible practice. I cannot articulate why really. Perhaps because it forces you to code everything very defensively, which obscures the intention of the code. In any case, experience shows that things are much simpler if you follow the rule that exceptions are only for exceptional scenarios. In other words, do everything you can to avoid having to trap exceptions.

This is harder than it sounds. It pairs well with the “fail fast” rule though. You can implement this rule by validating parameters to your methods. If they do not meet your expectations (e.g. something is NULL when it should not be), then throw an exception. The intention of the exception is always to indicate an invalid system state. (An invalid system state is unpredictable and dangerous, and should never occur – it is an exception).

API Design vs. OO Design

Traditional OO lore teaches us that objects are things that have both data and behavior. Blindly following this rule can lead us to make poor design choices, especially around what many refer to as “business objects”.

The pattern is that these objects already have data, so we seek to add behavior as well. In this way we can feel happy and content that we have a true “object”, and we are successful OO programmers.

The problem is that adding behavior as a sort of “suffix” to an object is ignoring a more important aspect of objects, which is that they should do one thing, and do it well. Add too many “suffix” behaviors, and pretty soon you can have a tightly coupled bowl of spaghetti.

This is not just theoretical – I have seen it happen, more than once. I’ve even been guilty of it.

So what is the solution? When we have classes that are primarily data, should we resist adding behavior?

My answer is “it depends”. To understand why, we need to take a small detour into API design…

Sometimes, programmers expect things to be a certain, simple way. They do not want to ask a FactoryLocator for an IObjectPersistorFactory, use that to get an IObjectPersistor, and finally tell the IObjectPersistor to Save their object to the database. They just want to write:

myObject.Save()
or
myObject.Load(id)

This ActiveRecord implementation is easy to write and easy to read. In short, it is good because it is a nice API for the client of the object. It has drawbacks (no transaction support, high risk of coupling to database). But in many systems, this API will be sufficient.

So the ActiveRecord “suffix” is mostly ok. What other behaviors can we add? How about validation? The save method should probably validate before it saves, so as to ensure we have good data in the database. How about some initial field values for new objects? And some event driven behavior – let field A be defaulted when field B changes? And we need properties for other objects. MyCustomer.Address.ZipCode works real nice. We can even lazy-load the Address property. Not too hard.

Hmm. Question. If we save the Customer object, should the Address save too? Probably. So we need to add some more code to the Save method for that.

etc. etc.

You get the picture (I hope). You can create a perfectly functional system in this way, but the coupling of all functionality to a single class will make it difficult to change in any substantial way. It will also have poor quality, because we are ignoring several key principles, such as DRY and Open-Closed.

There is only one way in which you can mitigate the problem. Use code-generation to generate your “business object” implementations. This mitigates quality problems substantially (DRY does not apply to generated code). It also forces you to either state some things declaratively (such as required fields), or else move them into their own dedicated area.

The Testable UI

I just read Jeremy Miller’s ideas on creating a testable UI, so I thought I’d respond with my own. Mine has the distinction of being used successfully in a working product. That said, we are still aggressively developing the product, so it has not been proven to everyone’s satisfaction at this point.

Let me restate the problem first. It is very hard to test the logic behind a Windows application. Some techniques exist, but they all suck in their own special way. My technique also sucks in some ways, but it addresses the following design goals with varying degrees of success:

  • must be able to test the interactions between controls on a form (one value changes, then another must update or become enabled etc.)
  • must be able to test the processes that involve multiple forms
  • there should be zero user-code behind forms. Thus, the forms can be worked on independently of the business logic, and all business logic can be tested without instantiating forms. Business logic can also be reused by imports into the system
  • it should be easy for designers to build a form.
  • component responsibilities should be well-defined so that it is easy for programmers to know where business logic should be coded (and thus to find it later when they need to change it)
  • it should be easy to code, test and understand a previously coded sequence of actions (no confusing event-driven processes).
  • it should handle the OO conflict of business logic that fits badly within traditional entity objects, mostly because they need to behave differently in different business processes.

Here are some of the main components:

The UI Interface is an interface definitions containing a method for each dialog that the user may see. It is defined at the business layer, but implemented in the GUI. This allows the business logic to be tested with a mock GUI.

The Context is a holder of state data containing everything in the user’s view. Everything you could want is in the context. Having a context keeps APIs simpler, and prevents the Wormhole Anti-pattern. It is also one of the main weaknesses of testing the system, because it is not obvious what the context needs to contain in a particular scenario.

The RichScreen is a model of a real screen . It is a class defined at the business layer, but with a rich event-driven interface to be able to handle changes to fields. It is bound directly to one or more forms (the view), and can be directly persisted. Like Windows Forms, RichScreens have a lot of generated or inherited plumbing code. An instance of a rich screen may be thought of as a Business Entity.

The Commands are executable actions. They are sequential controllers (my own term) – this means that they strongly resist using events, thus ensuring readability. They have a single “Execute” method, and are often constructed with a reference to the context. Commands often make use of the UI interface. They are usually constructed by ExecutableMenus, which are rendered as menus or buttons in the user interface.

To bring it all together, a simple scenario:

  1. User chooses an “Add Order” menu item
  2. The ExecutableMenu attached to the real menu creates an Add Order command with a simple context. The Add Order command is executed.
  3. The Add Order command creates an empty order, initializes the order date to today, creates a RichScreen instance, and instructs the UI implementation to display the order.
  4. The UI implementation displays the order form. Data binding to the RichScreen is automatic.
  5. User enters some data and presses “Confirm Order” button.
  6. The context validate method is called, and uses metadata defined in the RichScreen to validate the data. Problems are discovered, and automatically highlighted on the form. The UI implementation is told to display the validation message, which it does with a message-box.
  7. The user corrects the data and re-presses “Confirm Order”.
  8. This time the validate completes and the context Save method is called. The order is persisted to the database
  9. The Add Order command continues, and sends a message to the order-system queue.