Geeks With Blogs

Tim Huffam Dotting the I and crossing the T of I.T.

For some time I've been wondering if there's a better way to program business logic.  Years ago I used to write COBOL, then moved onto a 4GL, bla bla bla... and today I find myself well entrenched in OO with Microsoft's .Net.  Development times don't seem to be much better these days - and the complexity of things seems to have mushroomed. 

We went from barely-a-3GL to 4GL back to 3GL plus an explosion of things you need to consider.  We started with procedural code then moved to OO and seem to have got stuck there.  But somehow I think we need to revise our use of OO.  Business logic is predominantly procedural code - even if written in OO; it starts, follows a process, performing stuff until finished eg Customer.UpdateCreditLimit()

OO is really good for modelling things - as per the classic OO examples of a bicycle or car.  And thus they model business things quite well too - like an Invoice or a Customer. 

However, I've found that the more object oriented the code gets - the less productive, maintainable and flexible it becomes.  Not saying leave OO - far from it - it's brilliant.  It's just that we need to learn when to say 'when'.   The use of patterns has helped a huge amount - but these can also caused similar problems - when being applied where they aren't really needed - resulting in overly complex software (read: inflexible and unmaintainable and unproductive).  It's a fine line - and it's not easy to get the balance.

A major break through in this area is LINQ.  This has meant we have less clutter in our apps catering for ORM (brilliant).  This has resulted in code very similar to the old 4GL days (essentially 4GLs were just SQL based code anyway) - where all you care/code about is the business logic - caring not a jot about how or where a Customer or Order got created - and in this age of SOA - that becomes more important (as a Customer could come from many different sources - local RDBMS, company ERP, external CRM etc).  I guess you could say LINQ allows you to focus your code to be more domain specific (not saying it's a DSL).

I have been playing with workflows for donkeys of years and found that although the individual workflow systems themselves can range from very simple to incredibly complex - the individual tasks they perform need not be.   This had lead me to start thinking about applying this principle to code design at a reasonably low level....  what if we developed tasks as objects.  Each task has just one job (I've heard some people say this is how objects 'should' be coded anyway).  It has properties that can be get/set.  Keeping things dead simple, eg:

public class AdderTask
public int Addend1 { get; set
; }
public int Addend2 { get; set
; }
public int Result { get; set
; }
public AdderTask(int addend1, int
Addend1 = addend1;
Addend2 = addend2;
public AdderTask
        Result = Addend1 + Addend2;
return this

To run this you'd simply do this:

int result = new AdderTask(1, 2).Execute().Result;

Exposing the task's properties means you can build up get and set statements - and because the Execute method returns the task object itself you can easily use it in a single line as if it was a method on it's own - or retrieve it's property values after the Execute (these tasks would easily be adapted to work within a workflow system).

This style lends itself to expanding; rather like building blocks, you can build large workflows out of these task oriented blocks.  The workflows themselves coded just like these tasks - whereby all the business logic resides within the Execute() method.

Adding LINQ to the mix takes this to the next level - allowing you to build software that is simple to develop and understand.

I've been building a sizable system using this technique and I'm finding that I'm converting code developed using standard OO practices over to this methodology as it makes code more easily reused - but most importantly: easier to read and maintain.

In summary:

  • All input and output parameters should be implemented as properties (getter and setter accessors).
  • Provide a constructor that accepts all required parameters. A default constructor (with no parameters) is optional (I've found I never need these - but if you were to use these tasks in a workflow system they may need this).
  • Provide an Execute() method that takes no parameters and returns the object instance eg return this;
  • The object should clean up after itself. 

Other notes:

  • Originally I created a similar type of class for workflows - but I found that these ended up being no different in concept to tasks.  Likewise I've found that some tasks needed to call other tasks - so I've ended up just implementing everything as tasks.  On reflection this is actually quite valid - because, as I found when building large orchestrations using Biztalk, workflows become atomic tasks themselves when used within the context of a large orchestration (which may run many workflows and external tasks) - and the orchestration, from a highlevel could also be considered an atomic task.
  • I've found using System.Transactions.TransactionScope great for scoping transactions around many tasks when creating a macro task that runs many sub tasks.

Suggestions/comments very welcome - I'd like others to expand or comment on this.


Posted on Tuesday, September 9, 2008 12:10 AM BizTalk , C# .NET , Off Topic , ASP.NET , Architecture, Design and Development | Back to top

Comments on this post: Task Oriented Programming

# Mr
Requesting Gravatar...
Thank you Tim!

I loved your idea!

A question, what is the difference between a Task in the Task oriented programming you described with the GoF's Command pattern?
Left by Hendy Irawan on Jun 24, 2009 10:35 AM

# re: Task Oriented Programming
Requesting Gravatar...
Hi Tim. I'm interested in learning more about task-oriented programming. Your post helped me, but I wanted to ask if you could suggest me some reading to deepen knowledge. Thank you very much for your time.
Left by Gabriela Bosetti on Oct 04, 2011 8:55 AM

Your comment:
 (will show your gravatar)

Copyright © Tim Huffam | Powered by: