Building a Modern Line-Of-Business Application — Part 1
Warning: I intend to re-invent the wheel. Not because I have too much time on my hands, but because we need to take a fresh look at the entire process of developing LOB (Line-of-Business) applications. Simply adding new features to the monolithic systems we currently have is a losing battle. Things are changing too rapidly.
Most of you who are reading this are software developers, working with a well-developed and mature LOB application, so I'm sure you know that this article series has the potential to become a full-blown business book. There's enough material
As developers and administrators, it is our job to keep the business current, but what we have today is not always flexible in the ways we need it to be. Developers of twenty and thirty years ago had no way of anticipating the radical evolution in software, interfaces, and expectations. And yes, some of us are simultaneously "the previous developers" and "the current developers."
Time to Start from Scratch
Easy to say, but hard to do. Start where? UI? Core logic? Database layout? Interfaces? Standards? Eventually, yes to everything. We're not going to focus on the details — which all of those are — we're going to start with a concept: What type of LOB application are we going to build?
For this series, we'll create an "Accounting and Bookkeeping" application. The reason for this is because it's the basis of almost all LOB applications, and it will also demonstrate three of the key features of any modern application: Flexibly, Adaptability, and Extensibility.
Before any modern software can be written, a developer needs to decide on a framework or design pattern to follow. Why? These frameworks and design patterns help a developer code consistently and with flexibility. Let's keep this moving by defining what our LOB framework will look like.
The framework is where most of the monolith code resides. Let that sink in. We won't be writing all of the code. That's the old way. Developing software becomes the process of connecting your application's procedures to the framework. Modular thinking, not monolithic thinking. Now keep in mind, while there are UI frameworks, we're talking about the deeper kind here. This is something which will handle the processing of the overall application.
Our framework should contain of the following:
- Workflow Engine
- Background Processor/Scheduler
- Asynchronous Processor
Work-flows are what drive all business processes. For example, creating a new customer would trigger all of the following: a processes in accounting to verify credit, a process in sales to send welcome emails, and an administrative process to request additional contact information. Most work-flows are pretty simple, like the one above, but others can become rather complex.
An order work-flow, for example, might trigger multiple different work-flows depending on what needs to be done. It might trigger a processes to notify manufacturing, reserve product in inventory, request pickers to retrieve inventory AND also one in accounting to submit liens or send invoices. In turn, reserving product in inventory may trigger work-flows for purchasing and/or EDI transactions.
Modern work-flows must be able to process tasks synchronously and asynchronously. The vast majority of older systems can only handle the synchronous approach. The background processor comes into play as a tool for making the tasks less bound to linear execution. Keep in mind that the background process is not dedicated to any one work-flow, but is used by multiple work-flows to help handle all asynchronous processing. This is how we define the order in which something is done: 1st, 2nd, and 3rd, as well as what happens when the work-flow process fails.
Entity requests — we'd like to place an order, for example — and business rules are the main entry points for any work-flow. Think of the entity request and the business rules as the finger, and the work-flow as the dominoes. Like dominoes, each task should be a small quick routine that does one thing.
Workflow: Write Customer
- Update Contacts
- Update Terms
- Write Customer
- Link To Other Customers
This allows the developer to add their own extensions to the work-flow. As an example, say a developer wants to add a social networking task. They can add "Post to Facebook Customer Status" before or after any step.
Any large software system has a background/scheduler process of some kind. Whether it is something at the O/S level, like cron on Linux/Unix, or at that database level, like a phantom processor; there's a way to trigger hourly, nightly, or on-the-fly tasks.
For the most part, this is just a large loop that checks to see if something needs to be run now, or if it can wait. This process is a must for any LOB system because it is the basis for report processing, back-ups, and database maintenance. It is also the basis for building the asynchronous processor.
An asynchronous processor is often overlooked in application design. Asynchronous programming can be a pain to debug and not all environments or databases have good, or any, tools built-in to do this type of programming. .NET, JAVA UI, and other software make use of async design a lot. However, even in those systems, it is not widely used. But some of the newest technologies being created are starting to force UI and UX developers to address it.
Asynchronous programming in an LOB application is generally not as complex as you would find in a UI/UX Client. This is mainly because developers already do it without realizing it.
The core of any asynchronous process is to push it into another thread, or phantom port, so it can do its work at the same time as the process that called it is doing something else. This allows a task to complete faster, as long as there is not conflict in changing data.
Doing two things at once using the same data and processes seem really complex, but it isn't — assuming you don't make it complex. Let's look at an order creation work-flow.
During order creation, the system needs to notify the warehouse that inventory needs to be retrieved. The order creation work-flow does not need to wait for these notifications to complete in order to be written to disk. This is, therefore, asynchronous.
Workflow: Order Creation
- async Validate Product in Inventory
- Validate Customer
- Validate Customer Account Aging
- If Customer Account Closed then Terminate
- Calculate Gross Dollars
- Calc Tax
- Update GL
- WaitForComplete Validate Product in Inventory
- If Inventory Has Error then Terminate
- Print Picking
- async Notify Customer of Order Status
In the pseudo-flow above, you will see that there is an async flag on "Validate Product in Inventory". This would push the long drawn out process of checking inventory and availability to the background while the immediate checks ("Customer Account Aging", "Calculate Gross Dollars") are being done.
Once the immediate items are completed, the process will then "WaitForComplete" on the "Validate Product in Inventory" before going any further. If "Validate Product in Inventory" has not completed, then the "Order Creation" work-flow will continue to wait.
If you look further into the example you will see the " async Notify Customer of Order Status", but it does not have a "WaitForComplete" associated with it. This is done because there is no reason to wait for the completion of "Notify the customer of order status" in order to finish completing the "Order Creation" work-flow task. It just needs to be done.
I've only scratched the surface here. There is a lot more to get into and talk about, and I haven't even started talking about the business rules and database layouts for an "Accounting and Bookkeeping" application.
Stay tuned for more details on this on-going project.