views:

33

answers:

1

I'm looking for a pattern (or good practice) for the following scenario:

My function List<BatchItemResponse> Process(List<BatchItem> Data) {..} will process a list of data, and return info on where each item in the batch could be processed.

struct BatchItemResponse { int BatchItemID; bool Processed; string Description; }

Any thoughts? Is what I've proposed as good as it gets?

A: 

You could do exactly as you proposed - it'll work just fine. But since you're talking patterns, there are a couple of potentially elegant possibilities, depending on what your goal is.

You could use the Iterator pattern (the details of which are neatly hidden away by .NET's lovely enumerators):

IEnumerable<BatchItemResponse> Process(List<BatchItem> Data)
{
    foreach (BatchItem item in Data)
    {
        BatchItemResponse result = new BatchItemResponse();
        result.Processed = ProcessItem(item);
        yield return result;
    }
}

Or you could use the Observer pattern by firing an event for interested observers to subscribe to:

public class EventArgs<T> : EventArgs
{
    public EventArgs(T value)
    {
        m_value = value;
    }

    private T m_value;

    public T Value
    {
        get { return m_value; }
    }
}

public event EventArgs<BatchItemResponse> ItemProcessed;

public void Process(List<BatchItem> Data)
{
    foreach (BatchItem item in Data)
    {
        BatchItemResponse result = new BatchItemResponse();
        result.Processed = ProcessItem(item);
        if (ItemProcessed != null)
        {
            ItemProcessed(this, new EventArgs<BatchItemResponse>(result));
        }
    }
}

What's good about either of these patterns is that, properly used, they will let you update status in real-time rather than waiting for the whole list of BatchItems to be processed.

allonym