Workflows
Important note: this article focuses specifically on SharePoint workflows. What is written here doesn't apply to Windows Workflow Foundation (WF) and similar workflow tools, which have a perfectly valid usage and empower developers with the ability to make some business rules easier to change by non-technical users. While WF and source code are complementary, workflows for SharePoint substitute to the code. This means that their nature is very different from general workflow tools.
I spent a week on a Nintex training session. For those who don't know, Nintex is a company which created an alternative for workflows in a context of SharePoint. The goal:
Being simple to use, so that anyone can create and change workflows.
Being much more powerful compared to SharePoint workflows.
While I agree with the fact that the tool is more powerful than its free little brother, I'll try to show in the following article how wrong the apparent simplicity is. Trying to create a tool which is simple and easy by being visual, Nintex only achieved something which wastes your time and kills your productivity while encouraging you to bang your head and ultimately killing yourself trying to solve any problem which can be solved writing five lines of code in any programming language.
Editing
The most important drawback seems to be the poor user experience which leads to slower work. Programming is about text, and this is what makes it particularly powerful, as well as fast. In any 3GL coupled with a comprehensive framework, a few keystrokes are enough to create a lot of business logic. With workflows, the simplest logic becomes a pain, translated into dozens of clicks, drag & drops and lots and lots of forms to fill.
Let's take a simple example. We want to load the list of products to preorder and email them to a specific person. We start by loading the data from a list and excluding the duplicates. If the resulting sequence contains something, we concatenate the names (a comma and a space are inserted in between) and prefix them with “Products to preorder.” If the resulting sequence is empty, just put a log message saying that, well, there is nothing to preorder.
This is the result using Nintex Workflows:
For each step, there were plenty of clicks and plenty of information to fill in forms. A complete nightmare, given the extreme simplicity of the task. Indeed, if we compare that to source code, the results are funny to look at:
var uniqueNames = this.Data.ProductsQueue.Select(p => p.Name).Distinct();
if (uniqueNames.Any())
{
var message = "Products to preorder: " + string.Join(", ", uniqueNames);
this.Messaging.Send(this.Messaging.ToDefault, message);
}
else
{
this.LogInfo("There are no products to preorder.");
}
In six lines of code, you can see the whole logic at once. No clicks required.
The fact that we deal with text makes it possible to empower developers with many nice tools, such as auto-completion, syntax highlighting and refactoring. On Linux, grep
and other powerful tools can be used as well. Finally, text editors such as vim or Visual Studio make it extremely easy to cut and paste, undo, move blocs of code, search through code and auto-format it to make the life of a programmer as easy as possible. When dealing with workflows, even a task as easy as copy-pasting the logic of a condition (for example when switching from an if/else
block to an execute-if
block) is impossible: if you have five conditions matching variables to field values, this means twenty form fields to change by hand.
Those are not the only benefits of plain text approaches. We, developers, rely on daily basis on many other tools: background compilation which discovers the errors nearly instantly as we write them, static analysis which prevents us from introducing subtle and difficult to find bugs, formalized reviews which help us to become better at what we are doing, while finding even more bugs before they reach production.
Plain text also implies the benefits of a version control: versioning with diff, blame, branching, optimistic/pessimistic concurrency control. With Nintex workflows, don't even think about working on a workflow at the same time as your colleague. It's like storing source code in a shared folder and trying to change it in parallel: you'll see funny things happening all the time.
Notice that the things I'm talking about here are very basic. It's not like I was blaming a workflow tool for not supporting aspect oriented programming (AOP) or not having design patterns. Could you list five other things you have in your favorite language and which is impossible to do with Nintex workflows?
Debugging
When it comes to debugging, it looks like the designers of the workflow tools made everything they could to avoid this part of the development process. The only tool which is actually implemented in Nintex Workflows is the ability to put a message in a log. In other words, if I want to be able to trace the execution of a workflow in details, I need to double the quantity of workflow entries. Except that I wouldn't, because it appears that in most cases, such logging is disabled in production. Nice.
Even worse, Nintex Workflows will be very polite with you and will never blame you for making mistakes, unlike compilers do. In fact, if you do make a mistake, Nintex Workflows will usually skip over, producing a completely inconsistent result, and let you figure out what happened. You want to load a sequence into a number and then do a forEach
on this number? With Nintex Workflows, you can! (“For God's sake, why isn't it looping, while there are elements in my collection?!”)
The funniest part is that it's one thing where workflows could excel. Every step could log its inputs and outputs, and eventually its internal workings specific to the type of action. For instance, a loop could log the time it took to execute each iteration.
Now compare this to code. In programming, we have step-by-step debugging, we have breakpoints, we have exceptions with a stack trace. Would you ever work with a programming language which lacks those debugging fundamentals?
Prior to debugging per se, you often have the benefit of static checkers (which, let's be honest, find a lot of errors which would become bugs which might be difficult to spot during debugging) and sometimes (IDEs for C# or Java, for instance), you also benefit of background compilation which makes it possible to correct bugs in near real-time.
Testing
Should I mention that there is no automated testing for workflows? Right, you test it by hand, and you discover regressions through phone calls of your angry users.
Profiling
When code is slow, one has to run a profiler and to find the bottleneck. This doesn't resolve the problem, but at least makes it possible to determine precisely where is the problem.
Once the problem is located, one may run benchmarks and try different optimizations. Ultimately, a developer removes the bottleneck through a bunch of trial and error steps.
Nintex Workflows shows how long every step takes within a given run of a workflow. This might help (although it's not granular enough), but, seriously, I have to hover over every step and compare them by hand? Any profiling tool I've seen shows me the hot path, as well as the remaining data in a format I can actually use.
Also, what about the CPU load or memory used? Nintex Workflows considers that I don't need this information.
Convoluted approach of a problem which doesn't exist in the first place
For me, those workflow tools represent a convoluted approach of a problem which doesn't exist in the first place. Compared to code, we are expecting three benefits from workflows:
Ability for non-developers to deal with business logic. Good in theory, it doesn't work this way in practice. I've explained how complicated and error prone workflow tools are. This means that non-technical persons who will try to use workflows will quickly be overwhelmed by the user-hostile aspect of the thing. Those persons will end up either asking a programmer to create a workflow, and then never change it, or hire a programmer to maintain and modify the workflow.
Visualization. Workflows are nice. You immediately see what is going on. Wait, are you? Actually, when I look at a workflow other than the most elementary one, I can't see shit. I need to scroll horizontally and vertically all the time. I need to click everywhere, open dozens of popups. If there is hell for programmers and in hell, they have nightmares, I imagine that in those nightmares, they have to debug a workflow.
The funny thing is that we do have enough excellent visualization tools for mainstream languages. For .NET, there is NDepend, and Visual Studio Ultimate contains visualization tools as well. One can note that those visualization tools work at a level of methods, not control statements. There is a good reason for that: there is no reason to have a visual tool for control statements for any sane (and so, short) method, because such method will fit on screen, and text will be the most appropriate visualization.
So for short methods, text visualization doesn't need to be substituted by anything else. Large systems with sane methods have visualization tools already. So what's the point of the workflows? They only pervert the visualization of simple logic, and more complicated logic cannot be visualized anyway with them.
Execution standby. Workflows are good at interacting with users. They may request a person to do a task, and then wait for human action as long as it will take. They are designed for that. The problem is that we don't need workflows to wait for user actions. Asynchronous programming existed long before workflows were invented, and every mainstream language (OK, except PHP) supports asynchronous tasks. Workflows are in no way better than programming languages at staying inactive for long periods of time, and waking up when a person finally responded. API-oriented design makes it hugely easy to implement the thing.
So what is the alternative?
The alternative
It's extremely simple. Take a message queue service (MQS), an API and a Python script. Yes, that's all you need. The Python script interacts with both the API and the MQS. Let's see:
Ability for non-developers to deal with business logic. Totally. Give me a week, and I can train any non-technical person to deal with Python better than I can deal with workflows now, after a week of training. As I explained previously, workflows cannot be used by a non-technical person anyway. Python, on the other hand, can easily be learned and the person can use those skills later for writing short scripts and other stuff.
Visualization. Totally. Python being an elegant language, its code is easy to read and understand. Functions make it possible to very easily break the code into parts and reorganize and refactor it later. Agreed, this comes with experience, but so does the use of the workflows. Well, is it so? I'm still waiting to see a workflow which is easy to read and understand, when I don't need to do hundreds of clicks to open lots of popups.
Execution standby. Totally. With web infrastructure and a MQS, the code is executed when needed and can react to person's actions. It don't even need to NOP around. It just executes a given flow, and then stops, to be called once again when there is something else to proceed.
Some other benefits:
It's free. Those thousands of dollars you throw away every year for a workflow solution, well, you can keep it or spend for something actually useful.
It's extensible by developers. They can extend the API to provide additional functionality which is too complex to implement for non-technical users. In turn, those users will use the API to call the specific functions in a very simple way.
You have all the benefits of a programming language. Syntax highlighting, version control, debugging, profiling,... you name it.
The skills the non-technical persons acquire learning Python can be used elsewhere to accomplish basic scripting tasks.
In my humble opinion, such workflow tools are based purely on marketing, while providing absolutely no value whatsoever (if only could they be less harmful!) I wish things were different, and I hope this overview of the subject will help my fellow developers to defend their project against the introduction of workflows.