Posts from  June 2013


6.20.2013

Part 3 - Integrating with ddfplus - Reactive benefits with commodity option barrier events

Barchart Market Data Solutions provides real-time market data feeds (ddfplus quote service) for equities, indices, futures and foreign exchange markets. I've worked with their platform in the past which makes this a great opportunity to share how these techniques work with a real system.

Creating the observable quote stream

In Part 1 I described how to wrap an event based interface to create an observable quote stream. The ddfplus API comes with a simple Client interface exposing several events, one of which we can use to be notified of new quotes (NewQuote). Here's how we create the quote stream:

    private static IObservable<Quote> CreateQuoteStream(Client client)
    {
        return Observable
            .FromEventPattern<Client.NewQuoteEventHandler, Client.NewQuoteEventArgs>(h => client.NewQuote += h, h => client.NewQuote -= h)
            .Select(e => e.EventArgs.Quote);
    }

Thanks to using a real system and running an integration test, I discovered that FromEventPattern is the overload to use, the reason: use FromEventPattern if the events follow the standard .net (sender, args) convention. Lastly, I added a Select to project just the quote into my new quote stream.

Testing

If you would like to add some confidence in this transformation, consider a smoke test. The client will always return the "last" quote per symbol upon connecting. This will give you the ability to expect some data in a smoke test.

An alternative or complementary strategy would be to setup notifications if you don't receive quotes when you expect them. This is a great way to proactively address risk in a real time system. I'll address techniques to add this monitoring in subsequent posts.

Beyond this there's not much to test as the Rx framework is doing the heavy lifting and is well tested.

ddfplus quote source

Obviously hooking up to the event isn't enough, we need to tell the client to start listening for data and what to listen for. Fortunately this is very simple:

public class ddfplusQuoteSource
{
    private readonly Client _Client;
    public readonly IObservable<Quote> QuoteStream;

    public ddfplusQuoteSource()
    {
        _Client = new Client();
        QuoteStream = CreateQuoteStream(_Client);
        SetupConnection();
    }

    private static IObservable<Quote> CreateQuoteStream(Client client)

    private void SetupConnection()
    {
        Connection.Username = Config.UserName;
        Connection.Password = Config.Password;
    }

    public void Start(IEnumerable<string> symbols)
    {
        _Client.Symbols = String.Join(",", symbols);
    }

    public void Stop()
    {
        _Client.Symbols = string.Empty;
        Connection.Close();
    }
}

Steps

  • Create a Client instance.
  • Create the observable using our CreateQuoteStream above.
  • Set user name and password.
  • To start, provide a list of comma delimited symbols.
  • To stop, clear the symbol list.

Testing this out

Now let's put this to use to print quotes to the console:

var source = new ddfplusQuoteSource();
source.QuoteStream.Subscribe(PrintQuote);
var symbols = new[] {"ZC^F"};
source.Start(symbols);

Steps

  • Create our observable adapter ddfplusQuoteSource
  • Subscribe and print quotes using PrintQuote
  • Start listening for CME Globex Corn futures, ZC indicates CME Globex Corn, ^F indicates all futures contracts

Here's what we're printing:

private static void PrintQuote(Quote quote)
{
    var currentSession = quote.Sessions["combined"];
    Console.WriteLine(new {quote.Symbol, currentSession.Day, currentSession.Timestamp, currentSession.High, currentSession.Low});
}

Quotes have two sessions: current (called "combined") and previous. For new lows and highs we are only interested in the current session.

Next

Creating a simple observable adapter is pretty straightforward with the ddfplus API. Next, we'll look at adding some separation and testing between the ddfplus API and our application, like we did in Part 2.

6.19.2013

Pattern: One Clearly Defined Project At A Time

Applicability

All the time.

Definition

Prefer working on one project at a time. Finish it before moving on to the next. The project should have a definitive start and end centered around clearly defined business objectives.

I don't mean to suggest you shouldn't have multiple projects in your work life. Just prefer to minimize the number within a context, say a team of people working together. That said, there is value in minimizing the number of teams you are involved with :)

Motivation

A common issue in software development is run on development. This introduces many risks:

  • Failure
  • Budget overrun
  • Infrequent delivery of results
  • Inability to measure success/failure of investment
  • Vestigial feature explosion
  • Incomplete feature explosion
  • Confusion about what the software does
  • Confusion about what the software should do
  • Buggy software
  • Lack of real world feedback
  • Lack of learning - reflection rarely occurs
  • Lack of trust - trust is built on results
  • General sadness for everyone as the work drags on with little or no results :(

Mechanics

Constrain each project based on a set of business objectives. Keep the list short and projects will start and end quickly.

If higher priority objectives arise, decide if they can wait. Ask what the value of doing it now versus a few weeks or months from now. If there's really no value (other than maybe excitement) then wait! If not, then decide what to do with the current project.

In my experience, working on clearly defined projects one at a time means we spend less time on each project, we know when we are done and we can quickly move on to the next highest priority objective. This often negates the need to interrupt a project.

Tips for interrupting a project

  • Replacing objectives - New objectives replace current objectives
    • Craft a project to address the new objectives and in the process discuss what has been done for the current objectives.
    • Determine what should remain
    • Determine what should be removed - if the objectives change there are going to be features that aren't necessary. Get rid of them or be prepared to pay to support them in the long run.
  • Different objectives
    • If at all possible discuss how to wrap up the current project with a subset of the objectives accomplished.
    • If that's not possible, put the work aside and switch gears.
      • Plan a time to come back to the current objectives. It's easy for months and years to pass. These easily become features that you may not get any value from but you pay to support.
      • If new and current objectives affect the same system, discuss removing or setting aside the current work so you can focus solely on the new objectives.
6.14.2013

The value of code reviews

Next week I'm going to pair with Sean Massa to talk about Code Reviews in Node. In lieu of this I thought maybe I should write down some of the things I look for in a code review. My perspective on this topic is definitely not unique, but after years of doing these I think I have some ideas about what works and especially what doesn't! My first inclination was to dive in and organize anything that comes to mind into tips or patterns. Before I do that though, first I wanted to ask myself: "Why do code reviews?"

Why do code reviews?

Certainly there are derivative reasons, but I find myself coming back to these two:

  • Improve quality
  • Shared learning

I'm sure there are other possible reasons, but this should be enough to get started. To avoid duplication, I found these fantastic posts that justify why these are important:

Improving Quality

Ask "What were the requirements?"

Misunderstandings and miscommunication are a leading cause of problems in software development. Especially with the prevalence of the mediating involvement anti-pattern. Writing code is a translation of the original idea and as with any translation, runs the risk of "lost in translation."

If you're a part of the team, revisit the topic to make sure you validate your assumptions. If you're not part of the team, invest some time in understanding the purpose before doing too much code review.

Once you know the requirements, watch for discrepancies.

Ask "How do we know this works?"

Once we know what it should do, we can investigate how the author verified it.

  • Manual Verification? - If the author used manual testing, it's possibly worth keeping track of that somewhere so the same manual tests can be repeated in the future. Study or inquire about these.
  • Automated Tests? - Review them to see if they match the requirements.
  • On faith? - Even if it's simple, it doesn't hurt to manually verify the happy paths. If it's complex, consider automation.

Ask "How can we improve testing?"

  • Are there missing scenarios?
  • Is there an elephant in the room after implementing a feature - things that haven't been discussed that could be a problem?
  • Is there a way easily automate testing?
  • What testing scenarios could be added?

Ask "Do the tests help us communicate that we are done?"

Does our testing give everyone on the team, non technical people included, confidence that we are done? If not, how could it? Where would this be most beneficial?

Ask "Are tests explicit?"

  • Can you easily identify the AAAs (Arrange, Act, Assert)?
  • Are the tests difficult to understand?
  • Are the tests concise?

The tests should be reviewed like any other code!

Ask "Does the code make sense? Is it easy to follow?"

If the code is difficult to understand now, imagine how difficult it will be in a few months when anyone, the author included, is re-visiting it.

Here are some simple refactorings that can be done:

  • Rename abbreviated terms
  • Reorder code
  • Replace comments with composition
  • Extract class from parameters

Ask "Is this code simple?"

Complexity happens naturally, simplicity takes work and creativity. A second opinion can easily identify simpler alternatives.

  • Prefer explicit over magic
  • Prefer less code
  • Prefer declarative code, separate what from how

Focus on what matters

There's only so much time in the day. What little time you have for code reviews, make sure it's well spent. This requires prioritizing what you review. As I've said before, ask "Does it really matter?". Focus on complexity, the business domain, challenging problems etc. Don't worry about administrative CRUD interfaces. Focus on areas you routinely have problems. Focus on what keeps you up at night!

Identify repeat issues and do a root cause analysis

Keep track of common problems, instead of relying on the review to fix them, focus instead on using reviews to identify them. Then, work as a team to address the problems. Some examples:

  • Code formatting, style, and layout inconsistencies - perhaps invest in a tool to do this for you
  • Missing error handling - perhaps identify patterns or languages to get around these issues
  • Unused code - perhaps invest in a static analysis tool

Using code reviews to catch repetitive issues is going to be a problem when the code review misses it or fails to happen.

Ask "Does the commit log help organize the changes?"

One overlooked area of feedback is the commit log. Look for problems like

  • Files committed separately
  • Infrequent commits
  • Commits based on components of technology and not business value. IE: a commit for the controller, a commit for the model, a commit for the database changes and a commit for the view. Instead it's often much more useful to have these organized into one commit per use case/story/feature, especially when doing code reviews!

Shared Learning

This normally happens as a consequence of doing code reviews. However, if we are cognizant of it we can maximize the benefits and actually avoid doing things that can inhibit learning.

Review together

Do the code review with the author involved, there's no faster way to learn than having both people sit down together. Obviously this can't always happen, but for significant functionality it's probably a wise idea.

Don't rely on reviews to catch your mistakes

There's a trade off between wasted time reviewing and not enough, there's no guarantee every piece of code will be reviewed. Instead of relying on a review to catch mistakes, try to minimize the mistakes that you think are likely so the review instead focuses on highly valuable topics like simplicity, readability, verification and other areas where you can learn from others. Do the very best work you are capable of so you can learn new ideas from the reviews.

Avoid doing the work for the other person

Code reviews should be a process of feedback and discussion. Obviously there are times when you're refactoring and you just have to do it yourself. If you are intentionally doing a code review, try to involve the author in the changes.

In my experience, when I make the changes myself and ask the person to review them, I see more repeat behavior of the same problems, not a reduction. As a reviewer, be very cognizant of this risk.

Review sooner rather than later

The longer you wait, the more likely things that are important to discuss will be forgotten and the more likely the code will be in production causing problems anyways. Quick feedback is always beneficial. The longer you wait, the less beneficial a code review will be.

Pair programming

Pair programming is like the best form of code review, it happens instantaneously. Of course, make sure you use this judiciously. For example, there's probably no reason to use it on an administrative CRUD interface.

Don't use reviews to fix problems from people who don't give a ...

When people repeatedly make negligent changes and just don't care about the quality of the code, the code review won't help. I've made the mistake of trying to cleanup after this behavior and it never helps.

There's no way code reviews will solve this problem, they can only identify when it may be happening. Don't try to be the hero that always reviews this person's code, you will be very unhappy. Perhaps do some pair programming with the person to see if it's negligent or accidental, and then deal with it outside the code review process.

Assume good intentions

Unless you are dealing with someone who doesn't give a ..., assume the person does until proven otherwise. This will lead to a much more productive learning experience.

Ask why if something doesn't make sense

Sometimes you see something you don't understand, instead of inferring it's not necessary or was a "bad decision." Ask why it's there.

Avoid taking offense and try not to be offensive

We all take pride in what we do, keep it constructive. Likewise, if someone is coming across offensively, point it out politely. It's tempting when you get repeat behavior or rudimentary problems to become frustrated, but remember these can be a sign of a problem in the process, it's often a sign that people are rushed. Sometimes code reviews cannot fix the underlying problem.

TLDR

At the end of the day, a code review is an opportunity for feedback. We do them to improve quality and to learn. The specific techniques will be subjective but keep the end goal in mind. Leverage techniques of testing, refactoring, automation, design and every other aspect of software development in the process.

6.14.2013

Pattern: Establish Trust First

Applicability

The first few discussions with a new consultant.

Definition

Ease into starting a project with new consultants. First invest in building some trust.

Mechanics

The first discussion is a great opportunity to talk about your business with the consultant. This understanding is invaluable and should be easy to talk about without advanced preparation. In subsequent discussions gradually introduce goals and problems.

Shared understanding is a great way to establish trust. Look for ways a consultant offers value through past experience, advice, and other feedback. This initial value can go a long way towards establishing trust.

Not to mention what it means for a consultant to invest the time to learn about your business and showing interest in what you do. Holding several discussions gives everyone a chance to reflect and bring even more to the table in subsequent discussions. This can be a quick way to weed out consultants that don't have the time to deliver quality solutions.

This is also an opportunity to show the consultant that you are willing to invest the time to build a quality solution.

Wouldn't your rather learn a bit about each other to see if the relationship will be a good fit?

Tips

  • Make the first meeting only about your business.
  • Subsequent meetings can lead into objectives (goals and problems).
  • Assess the trust you have established, keep notes!
  • Avoid talking about solutions in these meetings. Solutions in software development often take significant time to develop. Work on establishing the trust necessary to justify investing time in devising solutions.
  • Avoid talking about costs in these meetings. Costs are unknown before a thorough analysis of solutions. Instead talk about pricing methodology to determine if it will fit into an investment model you are comfortable with.
6.13.2013

Pattern: Reduced Risk Initial Project

Applicability

The first few projects with a new consultant.

Definition

While taking on the risk of working with a new consultant, minimize other risks including time, complexity and low value. Nothing builds trust like a completed project that meets your objectives!

Mechanics

  • Minimize Time - Work with the consultant to identify a project that can be completed within a time-line that is quick for your organization. I would recommended something around a month or less.
  • Avoid asking "Can X be done within a month?" Instead let the consultant identify the time-frames and compare relative time-frames to find the quickest projects.
  • Ensure that quick does not mean rushed. Quick means there isn't a large time investment. Rushed means efforts will be doubled up which actually increases risk.
  • Stick to a simple objective with clearly defined value and simple measures to gauge progress. This will lead to a much more definitive end of the project.
  • Maximize Value - Make sure the project is of high value. It's exponentially more difficult to build trust if there's not much value to be gained from the relationship. High value leads to better commitment on both sides. Honestly, I never recommend low value projects, I've never found a company short on high value projects but I've seen plenty of low value projects get in the way.
  • Avoid Complexity - If you have a set of projects that seem equal in value and time, pick the least complicated project. Complexity almost always leads to unknown risks.
  • Be prepared to discuss several sets of objectives to see which project minimizes these risks the most.

Consequences

  • Complex, higher value projects will have to wait.
6.13.2013

Antipattern: Mediating Involvement

Definition

Mediating involvement happens when information flows from person A to B to C, where A and C rarely talk directly. A & C could be individuals or a group. In some cases there are multiple Bs!

Think about the telephone game where everyone sits in a circle passing a message around until it comes back to the source. It's often crazy what gets back, even with the best of intentions. Imagine having a conversation back and forth between the first and last person in the circle!

Consequences

Full disclosure: I've been guilty of being a mediator, it's not about blame, it's about what we can do to avoid these issues:

  • Miscommunication / misunderstanding
    • Even in direct conversation this happens.
    • It's even more likely in complex matters like software development.
  • Lost in translation
    • The mediator is very likely to summarize perspectives. Important aspects can easily be lost.
    • What if there was a miscommunication / misunderstanding in conveying the original information to the mediator?
  • Lack of creativity
    • Less minds = less creativity
    • Can't draw on the experiences of those that aren't involved.
  • Assumptions waste time and resources
    • Sometimes I'll ask a follow up question and a mediator will give me an answer they think is accurate when it's not.
    • Only after the software is built do we find out otherwise... ouch!
  • Unrefined information
    • No ability to carry on a quick back and forth conversation to refine ideas.
  • Huge delays in feedback
    • When it does happen, it often takes days for SIMPLE questions!
  • Follow up fails to happen
    • Follow up always runs this risk, even the most organized of people make mistakes.
    • I've never met a mediator who hasn't failed to follow up multiple times, even on critical issues!
    • Sometimes the mediator doesn't understand the value of following up, so there's no impetus to follow through.

In my experience:

  • Nearly every time someone speaks for someone else, I have a follow up question they can't answer.
  • Nearly every time I think I understood what someone said for someone else, eventually something comes up that was miscommunicated or misunderstood.
  • I've been blown away by the ideas that come from those that are often excluded.
  • The majority of times people say they will follow up I have to ask multiple times or just go to the source directly.
  • Countless times I've had to give up on mediators following up and make assumptions.
  • Most miscommunication / misunderstanding traces back to mediation, it's rarely from direct communication.
  • Software development is complex and time consuming. If it's not worth the time to involve everyone in simple conversations it's not worth the time to be developing the software.

Mitigation

This is very simple to mitigate. When a situation arises where involvement is needed, directly involve the responsible people in a conversation. This can't always happen immediately so keep track of these situations in an area visible to everyone so they can be addressed as soon as possible.

  • Clearly define roles and responsibilities
    • Users, Buyer, Consultant, Stakeholders, Subcontractors etc
    • Introduce everyone as soon as possible
    • Exchange contact information (email, phone etc)
  • Foster a team approach.
  • Everyone should avoid speaking for anyone else.
  • Consultant's shouldn't mediate the involvement of employees and sub contractors.
  • Analysts / managers shouldn't mediate the buyer nor the users.
6.12.2013

Why analyzing value gets you results.

It's very common to hear from customers, "What will it cost to build X?" Naturally, I want to understand what X will accomplish. I consider this process understanding the value Y, the desired outcomes. Sometimes customers just demand a cost, but for those that are patient in analyzing the value these are the benefits they will reap:

Optimal solutions

My expertise is custom software development. If I don't know about Y I can't leverage my expertise to propose and build optimal solutions to achieve Y. I also don't have the opportunity to point out deficiencies in X. Imagine someone telling their doctor what medication to prescribe.

Results

If you ask for results, you will likely get them. If you ask for features, there's no guarantee of results.

Significantly less wasted time

If I don't understand Y, when X doesn't accomplish it we'll have to try something else. You would be surprised, but when this happens I usually get requests for changes and new features, again with no guarantee of achieving Y. This has happened on every project I've worked on when Y wasn't discussed. Not only does this waste my time, it wastes yours. We are both stuck with the conundrum of who should pay for this wasted time.

Software development is an involved process, it's not just my time. Success requires your involvement in planning, implementation, user feedback, stakeholder feedback, testing, training and many other aspects. It's easy to overlook/underestimate this time commitment. Either way we both lose if we build failed solutions.

Timely results

If we reduce wasted time, you will get results faster.

Reduced cost

Less wasted time means less cost. Identifying and steering clear of low value projects means more of your money can go to high value projects.

Simplicity

Complexity in software happens naturally, simplicity takes expertise. Simplicity brings a whole host of benefits. If the focus is on features, features (complexity) will be maximized.

Maximum value

If the focus is on value, then value will be maximized! Low value features will take a back seat to higher value features.

Minimized maintenance

In my experience, maintenance cost is exponentially proportional to features. Minimal features means minimal maintenance.

If your business needs to make deliveries you could buy a Lamborghini. However, the cost to maintain it will be much higher than many other equally viable choices.

Flexibility to change

The more features the more difficult it will be to introduce and/or change features in the future. For every feature we must be careful not to "break" it with any updates. Naturally, if we don't minimize features, over time it will become very difficult to introduce change. Ironically, I find the features most likely to get in the way are the ones that aren't even used!

Reduced unused features

Do you want to pay to maintain features you don't use?

If I know Y, when your business changes I can make recommendations about which Xs can be removed. If not, in my experience, they never get removed.

Here's a great post on why less code is better.

Reduced training cost

The more features, the harder it is for users to learn to use your software. Keeping things simple for users means less training. Training cost is proportional, probably exponentially so, to features.

Pivoting on effectiveness

If we both know the desired outcomes we can devise simple methods to monitor the effectiveness of the resulting features at achieving the outcomes. When features prove ineffective we can alter/remove them and try other strategies.

Disciplined investment analysis

If we discuss value we can compare it to cost and make sure we're both making a wise investment decision. Without this analysis it's very easy to propose features that can lead to a marginal or negative ROI. In business it takes extreme discipline to make an investment decision. All too often I see everyone wrapped up in features and value takes a back seat. If we make this our focus, it's less likely to happen and you are more likely to see a significant ROI.

Increased investment capacity

This analysis will naturally take longer the first few times it's done. Over time everyone will become more effective and efficient and the time will be significantly reduced. The capacity to make wise investment decisions in software will be magnified!

Free investment analysis

There's ample opportunity for any company to invest in high value projects. Low value work competes for limited resources to develop high value projects. Low value work is unlikely to make you happy, at least not compared to high value work. If you demonstrate an interest in maximizing value, it means we're much more likely to have a successful business relationship and we're both much more likely to prosper. Because of this I provide this analysis process for free. When we're done you will still make the decision if we move forward. That means before I charge a penny you will already be guaranteed to get something of value!

Identify missing perspectives

When discussing value we're likely to stumble upon roles that usually aren't involved until much later, if at all. These roles often provide perspectives that can avoid sub optimal solutions before we even start. One of these roles is the buyer, the person who sets the final expectations of outcomes. Imagine how difficult it is to achieve an expectation for someone you've never met! Also, users of the resulting software are often left out. For example, if we're trying to save time or expand capacity, doesn't it seem like a good idea to involve the person that does the work now?

It's very easy to identify missing roles when we discuss value and run into questions that can't be answered.

Reduced risk

All of these benefits can be had by simply investing in an analysis of value. Once you get good at this it's often only a few hours investment per project. Is it worth the risk to skip this step?

6.10.2013

Reaction to: Why your users hate Agile development (and what you can do about it)

I stumbled upon this article this morning: Why your users hate Agile development (and what you can do about it).

The article is a great starting point for at least a dozen conversations. Here are some of my ideas to mitigate the risks the article introduced:

  • Have clearly defined projects based on outcomes.
    • A lack of planning leads to run on development.
    • With waterfall, there is an attempt to nail down features up front. With agile, it's about nailing down objectives and outcomes up front.
    • In my opinion, waterfall fails because it usually focuses on features and not outcomes. When the features don't result in the desired outcome, more work must be done. The same thing will happen with agile unless the focus is first on outcomes.
    • What are objectives? Deliverables should not be the objective.
  • Communicate directly
    • Traditional project management encourages indirect communication through layers of bureaucracy. This is very difficult to change. Many people have faith that this saves time.
    • Nearly every time someone speaks for someone else, I have a follow up question they can't answer.
    • Nearly every time I think I understood what someone said for someone else, eventually something comes up that was miscommunicated or misunderstood.
    • I would never be so arrogant to assume that I can speak for someone else as good as they can speak for themselves. Especially on complex matters like software development.
    • Often when speaking for someone else, the speaker fails to consistently identify who let alone why. There is an attempt to sanitize the content to what they think is important, this is often disastrous.
    • Talk directly to avoid wasting time playing a game of telephone.
  • Involve the buyer
    • The article mentioned that users are often uninvolved, I agree, but I also think the buyer is often uninvolved.
    • With the indirect communication in bureaucratic management, the buyer rarely will represent their expectations to everyone involved. Instead someone else speaks for them.
    • The real expectations (outcomes and objectives) will be lost if the person setting them isn't directly communicating with everyone involved.
    • Compound excluding the buyer with a focus on features. We have one translation from the buyer's expectations (outcomes) to a set of features that may achieve the outcome. Then, another translation of the features to the rest of the team (assuming no more layers of indirection).
      • That's two opportunities for a failure of communication to occur.
      • The person translating objectives to features isn't the expert that builds the feature. They rarely have the experience to draw from to maximize achieving the objective, this is yet another risk.
      • Compound that with any miscommunicated features, which will happen between technical and non technical people, and your risk is through the roof.
      • Add in the reverse process for any follow up questions and you have a disaster.
      • The crazy thing is, all you have to do is involve the buyer directly and all of this risk goes away. And you will save everyone time!
  • Learn to plan just enough
    • Teams new to agile often fail to plan enough. Instead of wasteful upfront planning with waterfall, the opposite occurs. Have patience to learn to balance not enough versus too much.
  • Avoid outcome creep
    • Do not take on a large set of outcomes, and do not let outcomes be added to a project.
    • If a higher priority outcome arises mid project, put the current project (outcome) on hold and switch to addressing the new outcome. However, I would strongly advise against this if timeliness is not of value in the new outcome.
  • Make sure regular reflection occurs
    • At least at the end of a project and each iteration within.
    • Everyone should be involved.
    • If you don't study what worked and what didn't how will you improve?
  • Discuss timeliness
    • Time is a feature, it's not always of value.
    • If time is of value, talk about that up front.
    • Talk about WHY it's of value. Is there risk of losing customers to a new competitor?
    • Otherwise, only talk about ideals, that's the best anyone can do.
    • Communicate regularly about status.
    • Realize that all of the above recommendations will reduce risk and thus reduce wasted time.
  • Budget thoughts
    • This is too big a can of worms
    • However, mitigating the risks above should go a long way towards mitigating budget risk.
    • I personally advocate for an up front investment before taking on a project.
      • Take the objectives/outcomes, analyze value and compare it to the estimated cost.
      • If the ROI is negative there is no reason to take on the project.
      • If the ROI is marginal there is no reason to take on the project.
      • Estimated costs in software development are always subject to risk of what will be learned in the process. Even experts learn, there is no way to mitigate this upfront, embrace it.
      • With the risk in the estimated cost, if the value is not several multiples of the cost, why take on the risk?
    • IMO way too much software is developed without justifying the investment.
      • This inhibits everyone's ability to develop high value software.
6.7.2013

Part 2 - Testing: Reactive benefits with commodity option barrier events

In my last post I introduced some benefits of using reactive programming techniques. This post will start us down the journey of testing so that subsequent topics can easily be expressed and verified.

Extracting the Anti Corruption Layer

As previously mentioned, when working with APIs it's helpful to introduce an anti-corruption layer. This layer allows you to build strong separation between an external system and your own. Think of this layer as a condom, practice safe development! This layer is a great place to transform and filter interactions to constrain how you use the external system and to inject a layer that can be very helpful for testing.

FuturesQuoteClient publishes FuturesQuotes via an event. First, we'll build a small anti-corruption layer with transformed events. Then we can do the same with observables. The anti-corruption layer will transform a FuturesQuote to QuoteWithContract and exclude quotes with invalid contracts.

Anti-corruption event layer

Stubbing the real client

The FuturesQuoteClient for reference:

public class FuturesQuoteClient
{
    public delegate void QuoteHandler(object sender, FuturesQuote quote);

    public event QuoteHandler Quotes;

    ...
}

Most APIs that use events won't have the ability to stub them for testing. Also, in c#, only the defining class of an event can raise it. Therefore, to separate the real client we'll need a wrapper around it. This is like a wrapper before our anti-corruption wrapper :)

/// <summary>
///     An interface to abstract the quote source.
/// </summary>
public interface IFuturesQuoteClient
{
    event FuturesQuoteClient.QuoteHandler Quotes;
}

This allows us to abstract an interface which we can stub during testing. Here's an implementation of the wrapper for the real client:

/// <summary>
///     Implementation of real wrapper around quote source.
/// </summary>
public class FuturesQuoteClientWrapper : IFuturesQuoteClient
{
    public FuturesQuoteClientWrapper(FuturesQuoteClient client)
    {
        client.Quotes += (sender, quote) =>
            {
                var handler = Quotes;
                if (handler != null) handler(this, quote);
            };
    }

    public event FuturesQuoteClient.QuoteHandler Quotes;
}

The wrapper takes a FuturesQuoteClient and forwards quotes to the IFuturesQuoteClient.Quotes event interface. I'm not going to test this wrapper, I only included it to show the extra dimension of complexity required. This wrapper would require an integration test with the real quote service.

Testing the anti-corruption event layer

Now that we can isolate the anti-corruption layer from the real client, we can begin to build the functionality through tests.

First, we want to transform FuturesQuote to QuoteWithContract:

[Test]
public void OnFuturesQuote_AValidContractOnAFuturesQuote_TriggersQuoteWithContract()
{
    var validFuturesQuote = new FuturesQuote
        {
            Symbol = "CZ2013"
        };
    var futuresQuoteClient = MockRepository.GenerateStub<IFuturesQuoteClient>();
    var quotesWithContractClient = new AntiCorruptionLayerEventClient(futuresQuoteClient);
    var quotes = new List<NotifyOnBarrierEventsReactive.QuoteWithContract>();
    quotesWithContractClient.Quotes += (sender, quote) => quotes.Add(quote);

    futuresQuoteClient.Raise(c => c.Quotes += null, null, validFuturesQuote);

    quotes.Should().HaveCount(1);
    var quoteWithContract = quotes.Single();
    quoteWithContract.Quote.ShouldBeEquivalentTo(validFuturesQuote);
}

  • Setup
    • We start with a valid FuturesQuote.
    • I'm using Rhino.Mocks to generate a stub of IFuturesQuoteClient instead of creating this class manually.
    • AntiCorruptionLayerEventClient is the class that will implement the anti-corruption layer, it doesn't exist yet. It requires a client of type IFuturesQuoteClient.
    • To detect what events are raised, we subscribe to the transformed event AntiCorruptionLayerEventClient.Quotes and put the quotes into a list.
  • Act
    • Next, we raise the event on our IFuturesQuoteClient stub with the validFuturesQuote event argument.
  • Assert
    • Finally, we want to make sure only one QuoteWithContract arrives for the original validFuturesQuote.

Implementing AntiCorruptionLayerEventClient

First we need our transformed event:

public class AntiCorruptionLayerEventClient
{
    public delegate void QuoteWithContractHandler(object sender, NotifyOnBarrierEventsReactive.QuoteWithContract args);

    public event QuoteWithContractHandler Quotes;

    protected virtual void OnQuotes(NotifyOnBarrierEventsReactive.QuoteWithContract quote)
    {
        var handler = Quotes;
        if (handler != null) handler(this, quote);
    }

    ...
}

That's a lot of typing, events aren't fun!

To get the test to pass we have to transform and forward the quotes:

public class AntiCorruptionLayerEventClient
{
    ...

    public AntiCorruptionLayerEventClient(IFuturesQuoteClient client)
    {
        client.Quotes += TransformToQuoteWithContract;
        // neglects handling unsubscribing from the event and cascading that up the chain :)
    }

    private void TransformToQuoteWithContract(object sender, FuturesQuote quote)
    {
        OnQuotes(new NotifyOnBarrierEventsReactive.QuoteWithContract(quote));
    }
}

The constructor takes IFuturesQuoteClient, subscribes to FuturesQuote events and transforms them to QuoteWithContract. Finally, it raises the transformed event.

Pain points

  • Awkward to assert what events are raised.
  • Extra layer of indirection in IFuturesQuoteClient abstraction.
  • Excessive code to setup new events in the anti-corruption layer.
  • These code samples would also need unsubscribe and disposal taken into consideration.
  • Obsession with how (imperative) versus what (declarative).

Side Note: Unit testing transforms

The above example demonstrates testing the composition of the anti-corruption layer. Testing the actual transform is better left to a unit test where the infrastructure of the anti-corruption layer doesn't get in the way of more detailed testing. Here's one possible test:

[Test]
public void MapFromFuturesQuote()
{
    var quote = new FuturesQuote
        {
            Symbol = "CZ2013"
        };

    var commodityContract = NotifyOnBarrierEventsReactive.QuoteWithContract.ContractFromQuote(quote);

    commodityContract.ContractMonth.Should().Be(12);
    commodityContract.ContractYear.Should().Be(2013);
    commodityContract.ProductCode.Should().Be("C");
}

Notice how simple this test is! Regardless if we use events or observables these tests will look the same.

Anti-corruption observable alternative

Stubbing the real client

Now let's look at the same scenario with an anti-corruption layer built on observables. To isolate the client we still have to apply a wrapper, fortunately the reactive extensions provides this for us (as shown in the last post):

private static IObservable<FuturesQuote> FuturesQuotesSource(FuturesQuoteClient client)
{
    return Observable
        .FromEvent<FuturesQuoteClient.QuoteHandler, FuturesQuote>(h => client.Quotes += h, h => client.Quotes -= h);
}

Again, I'm not testing the wrapper to isolate our anti-corruption layer, that would be done in an integration test. However, since we're leveraging a built in wrapper, we don't have to worry about as many test cases as we would with our implementation of FuturesQuoteClientWrapper.

Testing the anti-corruption observable layer

Here's the equivalent test to verify quotes are transformed:

[Test]
public void OnFuturesQuote_WithAValidContract_StreamsQuoteWithContract()
{
    var validFuturesQuote = new FuturesQuote
        {
            Symbol = "CZ2013"
        };
    var scheduler = new TestScheduler();
    var futuresQuotes = scheduler.CreateColdObservable(ReactiveTest.OnNext(0, validFuturesQuote));
    var quotesWithContractClient = new AntiCorruptionLayerObservableClient(futuresQuotes);

    var quotesWithContracts = scheduler.Start(() => quotesWithContractClient.Quotes);

    quotesWithContracts.Messages.Should().HaveCount(1);
    var quoteWithContract = quotesWithContracts.Messages.Single().Value.Value;
    quoteWithContract.Quote.ShouldBeEquivalentTo(validFuturesQuote);
}

  • Setup
    • Again we start with a valid FuturesQuote.
    • The reactive extensions comes with testing abstractions in Rx-Testing. One of these is a TestScheduler
      • Schedulers dispatch work in the reactive framework
      • TestScheduler is optimized to control and monitor the testing process.
    • Our new client AntiCorruptionLayerObservableClient requires an IObservable<FuturesQuote>
      • TestScheduler.CreateColdObservable creates this observable for testing, there's more to learn about this API but for now those details aren't relevant.
      • We setup the validFuturesQuote message in the test observable.
  • Act
    • To run the test we tell the scheduler to Start which causes it to dispatch our validFuturesQuote message
    • The Start method takes an IObservable<T> and returns an ITestableObserver<T> where T is our transformed QuoteWithContract
      • The testable observer, note observer not observable, records message type, timing and values.
      • Time is irrelevant for Select transforms but will be invaluable later on.
  • Assert
    • Finally we assert the same condition as before, that only one quote was transformed for the provided validFuturesQuote

Pain points

  • The TestScheduler is designed to help with testing situations where time is involved. There's a bit of overhead to test Select operations where timing is irrelevant
    • Have to specify time (0 above) when setting up the observable scenario (scheduler.CreateColdObservable(ReactiveTest.OnNext(0, validFuturesQuote)))
    • Have to dig into messages skipping timing and message type to get to the value you want to verify (Messages.Single().Value.Value)

Benefits

  • Testing abstractions are built in
  • No awkward hacks to capture messages, it's part of the framework.
  • Focus on what (declarative), not how (imperative)

Implementing AntiCorruptionLayerObservableClient

There's one constructor to create the AntiCorruptionLayerObservableClient from the FuturesQuoteClient, and one to create this from IObservable<FuturesQuote>. These are equivalent to FuturesQuoteClientWrapper and AntiCorruptionLayerEventClient.ctor(IFuturesQuoteClient) respectively:

public class AntiCorruptionLayerObservableClient
{
    ...

    public AntiCorruptionLayerObservableClient(FuturesQuoteClient client)
        : this(FuturesQuotesSource(client))
    {
    }


    public AntiCorruptionLayerObservableClient(IObservable<FuturesQuote> quotes)
    {
        Quotes = quotes
            .Select(q => new NotifyOnBarrierEventsReactive.QuoteWithContract(q));
    }

    public IObservable<NotifyOnBarrierEventsReactive.QuoteWithContract> Quotes { get; private set; }
}

The only real code involved is in transforming the source observable, one call to Select!

Anti-corruption layer filtering

In the anti-corruption layer event sample I didn't go into excluding quotes with invalid contracts. It's trivial and I think the reactive sample is much more expressive:

[Test]
public void OnFuturesQuote_WithAnInvalidContract_StreamsNothing()
{
    var invalidFuturesQuote = new FuturesQuote
        {
            Symbol = "invalidcontract"
        };
    var scheduler = new TestScheduler();
    var futuresQuotes = scheduler.CreateColdObservable(ReactiveTest.OnNext(0, invalidFuturesQuote));
    var quotesWithContractClient = new AntiCorruptionLayerObservableClient(futuresQuotes);

    var quotesWithContracts = scheduler.Start(() => quotesWithContractClient.Quotes);

    quotesWithContracts.Messages.Should().BeEmpty();
}

To get this test to pass we simply add a filter:

public AntiCorruptionLayerObservableClient(IObservable<FuturesQuote> quotes)
{
    Quotes = quotes
        .Select(q => new NotifyOnBarrierEventsReactive.QuoteWithContract(q))
        .Where(NotifyOnBarrierEventsReactive.IsValidContract);
}

Conclusion

Implementing an anti-corruption layer around information streams with reactive programming offers several benefits over imperative approaches. I'll admit the benefits aren't as exciting without the time dependent aspects. However, when working with time it will become patently obvious that there's no real comparison.

6.7.2013

Reactive benefits with commodity option barrier events

Reactive programming offers many advantages over traditional imperative techniques when handling information streams like commodity market data. In this and several follow up posts I want to demonstrate some of the advantages I've found using these techniques. I'll be demonstrating this with c# and the Reactive Extensions framework.

Reactive Programming

What is reactive programming? From Wikipedia:

"reactive programming is a programming paradigm oriented around data flows and the propagation of change." en.wikipedia.org/wiki/Reactive_programming

Spreadsheet calculations are a great example of reactive techniques. If you are unfamiliar and want to know more look at the Wikipedia article or follow along in this series as I demonstrate some of the advantages.

Barrier options on commodity futures

I'm going to use barrier options to demonstrate the value of reactive programming. From Wikipedia:

a barrier option is an exotic derivative typically an option on the underlying asset whose price breaching the pre-set barrier level either springs the option into existence or extinguishes an already existing option. en.wikipedia.org/wiki/Barrier_option

If you aren't familiar with finance, an option is easy to think of as an insurance policy. One purpose is to protect a future purchase from major price changes. Imagine if you could buy insurance to cover the cost of gas if it rose above an extreme level, say $8/gallon.

To protect against major price swings you may need to pay a hefty premium. One way to reduce the premium is to purchase a barrier option. One way a barrier can work is to cancel the insurance policy. Say you are worried about gas rising above $8 a gallon but you doubt it will rise about $12. You might be willing to pay a reduced premium in exchange for the small chance that gas will breach $12 a gallon causing the policy to be canceled. Barriers in this case reduce the seller's risk and hence reduce premium.

If a breach occurs you might want to find out ASAP to mitigate the risk. This is the scenario I will use to demonstrate reactive techniques.

Traditional imperative approach

First I'll start with an imperative approach that is pretty common to come across.

Note: Most of the following code can be found in a more complete fashion here https://github.com/g0t4/blog-samples/tree/master/reactive/src.

Quote client

Many APIs that provide quotes in c# have been around a while and therefore use an event based interface:

var client = new FuturesQuoteClient();
client.Quotes += OnQuote;

Simply attach an OnQuote handler to process quotes.

Active barrier options by contract

In this example I'm going to assume there is a "cache" of options that gets updated periodically. The details of this are irrelevant.

_ActiveBarrierOptionsByContract = GetActiveBarrierOptionsByContract();

OnQuote handler

Here is an example of the OnQuote handler. I tried to leverage extracted methods and LINQ to show even in an imperative fashion, the code can be concise and clean (at least in my opinion):

private void OnQuote(object sender, FuturesQuote quote)
{
    var contract = ContractFromQuote(quote);
    if (IsValidContract(contract))
    {
        return;
    }
    IEnumerable<CommodityBarrierOption> activeBarrierOptionsForContract;
    if (!_ActiveBarrierOptionsByContract.TryGetValue(contract, out activeBarrierOptionsForContract))
    {
        return;
    }
    activeBarrierOptionsForContract
        .Where(option => BarrierIsBreached(option, quote))
        .Where(NoticeNotAlreadySent)
        .ToList()
        .ForEach(option => NotifyTheHumans(option, quote));
}

When the quote arrives, we parse the contract with ContractFromQuote. If the contract isn't valid we ignore the quote. When you interface with an external API there are going to be things you want to transform. This is part of your "Anti-Corruption layer" if you are familiar with domain driven design.

Without going into the details of options on futures, suffice to say the contract describes what type of gas (say regular versus premium) and when you will be buying it (a month). I'm really simplifying this as the location would matter too.

If _ActiveBarrierOptionsByContract doesn't contain the contract, we ignore the quote. We only care about quotes for contracts that we insured.

Next, we check each option to see if the BarrierIsBreached and if NoticeNotAlreadySent. If these conditions are met we'll NotifyTheHumans.

This example ignores any performance considerations. I'll address those in subsequent posts.

Refactoring towards reactive

Now let's refactor to incorporate reactive patterns. Starting imperative means the reactive solution will be somewhat "tainted" but will suffice to move us in the reactive direction.

Reactive benefit: decouple handler from source transforms

The imperative solution makes it difficult to decouple transforms and filters from handlers. Instead of receiving all FuturesQuotes, we only want to know about quotes with valid contracts. We could create new events and wire up conditions to trigger them. However, leveraging the reactive framework makes this possible with much less typing and in a much more expressive fashion.

Observables

First we have to wrap the FuturesQuote event to produce an observable. Think of this as a stream of FuturesQuotes:

private static IObservable<FuturesQuote> FuturesQuotesSource(FuturesQuoteClient client)
{
    return Observable
        .FromEvent<FuturesQuoteClient.QuoteHanlder, FuturesQuote>(h => client.Quotes += h, h => client.Quotes -= h);
}

This creates the observable:

var client = new FuturesQuoteClient();
FuturesQuotesSource(client)

We now have a stream of FuturesQuotes.

Transform

The Reactive Extensions provides LINQ operators that work on observables. In the example above we parse the contract into a local variable, instead we could create a new type QuoteWithContract and store both the quote and the parsed contract:

public class QuoteWithContract
{
    public FuturesQuote Quote { get; set; }
    public CommodityContract Contract { get; set; }

    public QuoteWithContract(FuturesQuote quote)
    {
        Quote = quote;
        Contract = ContractFromQuote(quote);
    }

    ...
}

Now we can apply the Select LINQ operator to transform our stream from FuturesQuote to QuoteWithContract:

var client = new FuturesQuoteClient();
FuturesQuotesSource(client)
    .Select(q => new QuoteWithContract(q))

Filter

The other thing we want to ensure is that the contract was valid, we can do this with the Where LINQ operator:

FuturesQuotesSource(client)
    .Select(q => new QuoteWithContract(q))
    .Where(IsValidContract)

private static bool IsValidContract(QuoteWithContract quote)
{
    return quote.Contract != null;
}

I like extracting method conditions to increase readability of the stream composition. We now have a stream of only quotes with a valid contract.

Reactive benefit: Thinking in streams

At this point we could Subscribe to the quotes stream and execute our imperative code:

private void OnQuote(QuoteWithContract quote)
{
    IEnumerable<CommodityBarrierOption> activeBarrierOptionsForContract;
    if (!_ActiveBarrierOptionsByContract.TryGetValue(quote.Contract, out activeBarrierOptionsForContract))
    {
        return;
    }
    activeBarrierOptionsForContract
        .Where(option => BarrierIsBreached(option, quote.Quote))
        .Where(NoticeNotAlreadySent)
        .ToList()
        .ForEach(option => NotifyTheHumans(option, quote.Quote));
}

But why not keep with the concept of a stream and re-frame our solution as producing a stream of barrier breach notices! To do this I've taken the above code and extracted this method that can take a quote and create the resulting breach notices:

private IEnumerable<BarrierBreachNotice> BarrierBreachNotices(QuoteWithContract quote)
{
    IEnumerable<CommodityBarrierOption> options;
    if (!_ActiveBarrierOptionsByContract.TryGetValue(quote.Contract, out options))
    {
        return Enumerable.Empty<BarrierBreachNotice>();
    }
    return options
        .Where(option => BarrierIsBreached(option, quote.Quote))
        .Select(option => new BarrierBreachNotice(option, quote));
}

public class BarrierBreachNotice
{
    public BarrierBreachNotice(CommodityBarrierOption option, QuoteWithContract quote)
    {
        Option = option;
        Quote = quote;
    }

    public CommodityBarrierOption Option { get; set; }
    public QuoteWithContract Quote { get; set; }
}

Now we can transform a stream of quotes, along with our active barrier options "cache", into a stream of BarrierBreachNotice. We'll use the SelectMany operator as each quote could generate more than one notice:

FuturesQuotesSource(client)
    .Select(q => new QuoteWithContract(q))
    .Where(IsValidContract)
    .SelectMany(BarrierBreachNotices)

And we want to avoid duplicate notices:

FuturesQuotesSource(client)
    .Select(q => new QuoteWithContract(q))
    .Where(IsValidContract)
    .SelectMany(BarrierBreachNotices)
    .Where(NoticeNotAlreadySent)

Reactive benefit: Descriptive subscriptions

Our original goal was to notify the humans:

FuturesQuotesSource(client)
    .Select(q => new QuoteWithContract(q))
    .Where(IsValidContract)
    .SelectMany(BarrierBreachNotices)
    .Where(NoticeNotAlreadySent)
    .Subscribe(NotifyTheHumans);

private void NotifyTheHumans(BarrierBreachNotice notice)
{
    ...
}

This subscription is much less work, no awkward += on an event and object sender overhead, a simple call to Subscribe!

Notice how easy it is to continue the idea of a stream. Transforms and filters are very easy to use to partition event handling into an ordered, composable pipeline. This is one of the extremely powerful aspects of reactive programming abstractions.

Next up

Next I want to discuss testing, further thinking in streams, performance and other considerations and how reactive programming techniques apply.

6.3.2013

Deliverables should not be the objective.

Technologies

This is pretty common in a software development project:

We want BizTalk, .net, ruby, Nodejs, SQL Server, Sharepoint, Oracle... 

Features

This is pretty common too:

We want a table of customers.
We want an export of invoices. 
We want a list of orders. 
We want the ability to apply discounts. 
We want a report of inventory.

Value

This is very rare:

We want to provide more value to our customers.
We want more customers and to do that we may need to increase the frequency of doing X.
We want to increase customer satisfaction.
We want happier employees.
We want to expand Y and to do that we may need to automate Z.

When I hear this, I know I can make a difference.

Be careful what you maximize

This is my opinion:

Deliverables (ie: features, technologies, software) should be a means to an end.

Why?

If you want to maximize business value, the end should be a business objective. If you want to maximize features, technologies and software then let those be your ends.

I'd prefer to minimize features, technologies and software. They aren't cheap to maintain!