Sunday, August 21, 2011

Business Analysts in the mist.

One thing I've noticed since moving to Australia is the lack of business analysts within organizations I've worked at, or worked for. Occasionally a client will have someone who's title is BA, but the normal responses I get when asking if they have a business analyst is either "No" or "Not now, but we plan to hire one." Now in Canada, this would be sending little red flags flying, but it seems to be par for the course at least here in Brisbane. What really sends the alarm bells clanging is when I ask "who defines the requirements then?" If the answer isn't a B.A. or a client then prepare for pain. Usually the answer is either "The Developers/Lead Developer" or "Sales."

Developers generally makes for very poor analysts. Developers are technical, they don't grok business process, only software process. A developer can analyse how something should be done, but not what should be done. Salespeople are often even worse. Salespeople only worry about signing on new customers or upgrading existing ones. They have an excellent perspective on the extreme high-level of what should be done, but they don't understand either from a business perspective or a technical perspective how it could be done.

The best person to define requirements is the client. Now if you're fortunate enough to be using a methodology like Extreme Programming and the client has someone valuable embedded in your team, then there's no real need for a BA. However, the next best thing is a dedicated BA. Now this gets back to businesses that have someone who's title is BA, but isn't a BA. An excellent example of this was a large government organization client. When I asked if they had a business analyst, their response was that they had a whole team of business analysts! What they said was true, it was actually a small department of about 8 BAs that were under the same director, but not actually part of the software development department. Their idea of a BA's role was to go and meet with the client, understand their business processes, write it up in a document, and hand it off to the software developers to build, washing their hands of it. This meant that the developers had a document, some months after a project has started, then if there are issues or clarifications needed, well too bad, lodge a request with the BA department to get the documentation adjusted. Often the BA that did the original work was tied up in a new project so you get a new BA that has no idea about the project. Of course, this model made perfect sense to them. They needed to have a billable block of time to charge back to the client. Once that was done, they needed to be charging other clients. This was not only frustrating from the software development side of things, it drove the clients nuts. (Having to explain the same thing to two or more BA's, and being expected to *pay* for the new BA to get up to speed with the project.)

Most often what businesses call a BA is essentially nothing more than a clerk. Write down requirements so that we effectively have a contract that we can associate a dollar figure to and get a sign-off on. But what a BA is should be so much more than that. In Canadian teams where I've worked with properly embedded BAs, the BA was effectively a conduit to the client. Even within an Extreme Programming project where the client was in another province, the BA proxied for the client when the client couldn't send someone to our office. If we weren't sure about something, we asked the BA. If they weren't sure, it was their job to get in touch with the client and sort it out. They had the business knowledge, and were abreast of the technical details of how the software was being implemented. They were instrumental in giving initial feedback for UAT phases. In short, they started the project, and they finished the project. In XP the BA was the tracker and the client.

So if anyone around Brisbane works for a client/company that has a BA similar to what I describe above, count yourself as lucky and let me know. I'd like to get my picture taken with them because I'm thinking they must be rarer here than dropbears. :)

Wednesday, August 17, 2011

Business software should advise

Business software should be an advisor to users, not a dictator above them. Business software boils down to one thing: Business Rules. How business rules are implemented in software is just as important as the rules are themselves. Some applications seek to "enforce" business rules by restricting behaviour until certain information is provided, or sequence of steps have been followed. There are definitely cases where this must certainly be expected to be the case, such as enforcing authentication and authorization to features. However, when applied to business logic this kind of enforcement leads to inflexible and, in some cases, very costly issues.

People generally like dictators at first. Life is pain, they need someone to stimulate the economy, get the trains running on time. When a software system is first designed, the idea of enforcing rules to save time and minimize mistakes is certainly attractive. Unfortunately, software has to evolve as business requirements evolve, and before you know it, your wonderful software application has divided Poland with Microsoft Office, and invaded Czechoslovakia. All you wanted was a system that would bring the efficiency back into your organization, but pretty soon you have a behemoth costing you hours of time, stacks of bug reports, and your business is failing to serve its customer base which is costing you customers.

Enforcing business rules restricts flexibility. Rather than designing software to be an enforcer, design it solely to be a time saver. Ensure that the only mandatory fields are things that ARE mandatory, and if the system can default a bunch of other optional fields, then fine. Someone can always change the values later. Also accept that a certain amount of business logic is best left in people's heads and hearts. Sure, you could define rules, even strive to make them configurable, but in the end keeping the most flexible business rules outside of software is sometimes the best option.

A perfect example of this was brought up today when one developer was querying another about a legacy system for manufacturing. The question was that when orders are received, different products take different amounts of time to manufacture. How does the factory worker know when they need to manufacture each product to get it done by the dispatch date? The answer was, "The floor supervisor decides what to manufacture to ensure everything is done on time." This is based on a report with the various orders and their respective dispatch due dates. It took a few rounds of questions to let this fact sink in. The software system didn't tell them when to manufacture the product, it simply told them what needed to be manufactured and by when, and a person would need to determine what should be done first.

There are an assortment of rules that govern when products get manufactured, and a *lot* of environmental variables involved. I'm sure the first thoughts of this developer would have been along the lines that the rules could be codified so that the software system could calculate and dispatch out work to the factory floor so that products are manufactured by their dispatch date. This would be more efficient and could probably mean they could accept more work or work with fewer staff. But the problem is that you cannot hope to codify *all* variables that are accounted for in the decisions to get work done. Staff being sick or on vacation, whups, need a rostering component. Machine break-downs or services, ah, incident tracking. Last minute order changes, cancellations, or changes in priorities. Stock shortages or quality issues. Issues that can crop up that haven't even happened before. Machines follow very clear an concise rules very effectively, but they cannot adapt to unknown variables like a human being can.

The result of leaving a good chunk of the business rules for producing the product in a person's head means that the actual mechanical work of getting product produced is completely dynamic. The machine simply advises what needs to be done, can make suggestions based on information it can compile, and records the results of the production. If the machine goes down, the data can still be queried, the product produced. The machine is not relied upon, it can be updated once it sorts itself out.

Friday, July 8, 2011

Pet Peeve: Misuse of KeyValuePair

This is one that irks me when I come across it.

public IList<KeyValuePair<bool, string>> ProcessRecords(IList<MyRecord> records)
{
    var results = new List<KeyValuePair<bool, string>>();
    foreach( var record in records)
    {
         // Do some processing...
         if (success)
             results.Add(new KeyValuePair<bool, string>(true, "Message indicating record was processed successfully.");
        else
            results.Add(new KeyValuePair<bool, string>(false, "Message indicating record was not processed successfully.");
    }
    return results;
}

The above is just a pseudo-example similar to some situations I've come across and even some examples on the web on how you can use KeyValuePair, and even one that gave an example of a KeyValuePair of KeyValuePairs to return a bastardization of triplets. *shudder* The alternative to KeyValuePair would be to create a new class which by all rights would be identical to KeyValuePair. So why not just use KeyValuePair?

Because it is misleading, and it's no different to writing a class to represent a tax invoice and naming it "Order", or "Thing" for that matter. KeyValuePair is meant to store a Key, as in a unique value, against a value. If your method is designed to return a unique list of keys with respective values then by all means use KeyValuePair. But if you're using it to return arbitrary pairs of values then for clairity just create a Pair class instead. 

The problem with returning KeyValuePairs is that looking at that return type you would expect that the data would be suited to being placed in a Dictionary. However if you're returning arbitrary pairs of values then you are misleading other developers all for the sake of being too lazy to define a simple generic class.

Friday, April 22, 2011

Getting .Net Property Names without Magic Strings

This was something that had been perking my interest every so often ever since I started truly adopting Agile development practices and re-factoring code with abandon. This meant that properties and methods could be added, removed, and renamed at any point within the life of a project. There are cases where in debug messages, log entries, reflection lookups, or Argument-related exceptions I want to extract a property name. This resulted in a magic string appearing in the code.

A classic example of needing property names is with WPF binding and PropertyChanged events. Your viewmodels may be listening for property changes on bound domain objects in order to perform actions or update calculated values. Take for example:


The problem here is that if properties within InterestRate (Delta, Rate, and EffectiveDate) are renamed, the above code will stop working as expected. Now effective unit tests should help guard against behaviour changes but it would be nice if we could avoid having a hard-coded string for the property name.

Enter the PropertyName method: I had come across a solution a while ago on Clinton's Blog around using a static method to extract property names. It worked well enough but it was still a bit clumsy. What I ended up with was:



This works well enough but I didn't really like having to explicitly declare the Type (In the above example: InterestRate x) in the parameter expression. Lately I got thinking why this functionality couldn't be adapted into an extension method...


Now the calling code looks like:


This is a compliment to the GeneralToolbox static method in that the extension method will only work against an instance of a class where the static method can work against the type. (In situations where an instance isn't present.)

- Edit: Code & unit tests are now available here.

Monday, April 11, 2011

Around 6+ hours I'd love to get back.

WPF is a beautiful thing most days, but every so often it rears up and slaps you in the face when all you think you have left is a fairly trivial bit of UI functionality left. Then you are burning HOURS making sure you haven't done something completely stupid in your bindings, and Dr. Googling for anyone else who's run into the same problem. The burn isn't that it's a particularly complex thing to do, it's that there end up being so many variations of things to try, most of which won't work for one reason or another, and many other suggestions simply never worked or were even tried. This burns hours upon hours. Even if I say to myself "This isn't that important, set it aside and come back to it later" it's still smouldering in my mind and within a couple minutes I'm back trying something else that comes to mind, and burning more time on it.

In this case all I had left were two little unrelated UI interactivity features that I wanted to polish off before continuing with the next set of requirements.

#1. I present details in a list that is sorted by date. In editing an item within the list I can edit the date. The logical behaviour is that the list should be re-sorted.

#2. Presented in the list rather than using separate views for viewing and editing the details I wanted to swap out a data template (or user control) inside the list item content. (Click a button to expand for edit/review, and another to save/restore to summary mode.)

WPF has Collection View Source objects that sounded like they should have fit my needs for item #1. (instead of binding directly to observable collections)  WPF also has DataTemplateSelectors which looked like they should service my needs for item #2. All set! Not quite....

CollectionViewSource allows you to sort sure enough, but editing the collection items doesn't cause the view source to refresh the sorting/grouping. I spent HOURS of digging and experimenting with different options to tackle this including extending ObservableCollection to provide the sorting, (see here) refreshing via Move operations, to trying to hook into the CollectionViewSource.View.Refresh() with limited success. Finally I hit paydirt with someone that got fed up with exactly the same problem. (see here)

After finally tackling #1 I had renewed energy to tackle #2. (which ironically I had shelved in order to tackle issue #1) I had arm-wrestled with the data template selectors earlier and quickly found while they were good at picking a template, they did not listen for changes to anything they were bound to in order to make that selection so they were only good for a one-off choice. This time the inspiration for the solution came from a little gem of an idea I glanced upon from Stack Overflow (see here), specifically "You could even make your data template a ContentControl, and use a trigger to change the ContentTemplate." I had used DataTriggers before and knew I could swap out individual controls between view and edit variations but I was looking to swap out an entire template in one go. Using a data template containing a content control, and the data trigger to swap out the content template was bloody BRILLIANT!


Finally these WPF UI thorns in my side have been removed and I can resume work without these damn things flaring up to burn up even MORE time. I find it very strange that implementing such functionality was such a chore within WPF, but in case Randall Doser ever comes across this blog... #2, definitely #2.
:)

Saturday, February 26, 2011

3 years, $1M

Most people that know me in the industry know my automatic response when asked to estimate on vague requirements for enhancements or a new small-to-medium-sized system.
"7 years, $1M."
This often was turned around to "1 year, $7M if you're in a hurry."

I've since revised this to a more reasonable "3 years, $1M"

This usually gets a laugh out of people but I'm actually quite sincere about it as a general estimate. If something has been well thought out and requirements have been neatly separated into units of work that can be estimated and built then I can give a detailed estimate for the exact amount of work needed. When all someone gives me is a rough idea of what they want, then my response is that I'm reasonably confident that I can deliver exactly what they want for $1M (preferably up-front) and in 3 years.

This covers the time to do proper requirements gathering, prototyping, iterative development & re-factoring, plus testing to ensure the end product is spit-shined. They will have something available in production before the three year mark, but what they had in their mind (and reasonable additional stuff they're surely to think of or require along the way) will be complete within 3 years. The simple truth is the endless cycles of negotiation, re-prioritization, and up-scaling to try and meet unreasonable time or scope expectations wastes far, far, more money.

Thursday, December 9, 2010

Ouch, 3-day bug!

Earlier I had posted on how to write tests for the Quantumbits ObservableList class by enabling a DispatcherCycler to essentially perform a "DoEvents" to hook up appropriate events.

This was all working just fine until one day after adding a more complete suite of tests for an implementation of an ObservableList I had a failing test. I had run the test successfully before so I took a quick look and re-run the test. It passed. I ran the suite again and it failed. I ran it several times as a suite and individually to see if it might be an intermittent problem but alone it always succeeded, as part of the suite it always failed. And it failed for a completely wrong reason.
        [Test]
        public void EnsureChangingRelativeDeltaUpdatesRemainingCorrectly()
        {
            var mortgageInterestList = new MortgageInterestList(new MortgageInterest.Initial(0.05m, DateTime.Today));
            var second = new MortgageInterest.Adjustment("+.5%", DateTime.Today.AddDays(2));
            var third = new MortgageInterest.Adjustment("+.2%", DateTime.Today.AddDays(3));
            mortgageInterestList.Add(second);
            mortgageInterestList.Add(third);
            new DispatcherCycler(mortgageInterestList.CurrentDispatcher).Cycle(); // * Failed here

            second.UpdateByAbsoluteOrRelativeValue("+.3%");
            new DispatcherCycler(mortgageInterestList.CurrentDispatcher).Cycle();
            Assert.AreEqual(0.05m, mortgageInterestList.SortedList.First().InterestRate, "First interest rate should not have changed.");
            Assert.AreEqual(0.053m, second.InterestRate, "Second interest rate was not updated.");
            Assert.AreEqual(0.055m, third.InterestRate, "Third interest rate was not updated.");
        }


The guts of the list in question contained a set of data that would be sorted in date-order. It contained an initial instance (which could have it's date adjusted) and had logic that basically asserted that "adjustment" instances could not be inserted before the initial item, or moved (date changed) prior to the initial item. The error behind the failing test indicated that the test was trying to move an item prior to the initial item, which it obviously wasn't. The test merely changes the value of one of the items which should update the later item. Debugging that failure it almost looked like the adjustments were being added to the collection before the initial item, which was completely impossible.

After staring this down for two evenings looking for bugs with my Dispatcher implementations within the Observable List and cycler, Dispatcher behaviour and multithreading, TDD.Net behaviour, etc. I decided to start looking for tests that were supposed to be replicating this behaviour.  Sure enough I did have tests for this behaviour:
        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void EnsureAdjustmentInterestRateCannotBeMovedBeforeInitialRate()
        {
            var mortgageInterestList = new MortgageInterestList(new MortgageInterest.Initial(1.25m, DateTime.Today.AddDays(1)));
            mortgageInterestList.Add(new MortgageInterest.Adjustment("+5%", DateTime.Today.AddDays(2)));
            new DispatcherCycler(mortgageInterestList.CurrentDispatcher).Cycle();
            mortgageInterestList.SortedList[1].EffectiveDate = DateTime.Today;
        }


I popped an [Ignore] attribute onto this test and re-ran the suite... All remaining tests pass! I re-enable the test and the other test fails once more. Now I'm seriously doing a WTF? but making progress.

Side Note: Notice now my Dispatcher cycler is accepting a dispatcher in it's constructer, rather than being a static helper using Dispatcher.CurrentDispatcher. I was chasing all kinds of ideas around whether Dispatcher actually was thread-safe, and whether I needed to ensure the Cycle call would use the same dispatcher as the list. I went through a LOT of trial and error to try and track this behaviour down...

Then I read up on Dispatcher and how it can capture unhandled exceptions. Since this test was waiting for an exception that would have been raised on the Dispatcher (UI) thread based on the nature of ObservableList I decided to see what happens if I handled the exception at the Dispatcher level. I added a text fixture setup implementation to handle unhandled exceptions:

            Dispatcher.CurrentDispatcher.UnhandledException += (sender, e) =>
                {
                    e.Handled = true;
                };

Re-running the tests I had different failures. Essentially the classes that were expecting the exception weren't receiving it... But the originally failing test was passing.

Finally I removed the fixture setup and tried the following:

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void EnsureAdjustmentInterestRateCannotBeMovedBeforeInitialRate()
        {
            var mortgageInterestList = new MortgageInterestList(new MortgageInterest.Initial(1.25m, DateTime.Today.AddDays(1)));
            mortgageInterestList.Add(new MortgageInterest.Adjustment("+5%", DateTime.Today.AddDays(2)));
            new DispatcherCycler(mortgageInterestList.CurrentDispatcher).Cycle();
            DispatcherUnhandledExceptionEventHandler handler = (sender, e) =>
            {
                e.Handled = true;
            };
            mortgageInterestList.CurrentDispatcher.UnhandledException += handler;
            mortgageInterestList.SortedList[1].EffectiveDate = DateTime.Today;
            mortgageInterestList.CurrentDispatcher.UnhandledException -= handler;
        }


Sure enough all tests PASS! I was actually expecting the above test to fail since the dispatcher would not raise the ArgumentException that would be raised when the effective date was changed, such as was the case when I had this essentially in the Fixture setup. However, the ArgumentEception does get raised and handled.

I explicitly add and remove the delegate handler since this would be attaching a handler to a CurrentDispatcher on the executing thread. I don't want it to interfere beyond the scope of this test.

Actually, as I write this I want to be certain that other tests that might trigger an exception (as a test failure) or test the exception behaviour don't trip up other tests.

The code can be substituted so that the handler is assigned on test start up, and removed on test cleanup. Fortunately I have a base class wrapper for my nUnit implementation so this is a snap!

        private DispatcherUnhandledExceptionEventHandler _handler = (sender, e) =>
        {
            e.Handled = true;
        };

        public override void TestSetup()
        {
            base.TestSetup();
            Dispatcher.CurrentDispatcher.UnhandledException += _handler;
        }

        public override void TestTearDown()
        {
            base.TestTearDown();
            Dispatcher.CurrentDispatcher.UnhandledException -= _handler;
        }


And now all tests are covered to behave nicely with one another if the Dispatcher encounters an error. No messy hooks in individual test cases needed.

Damn that felt good to squish!