Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Think of Your Business Logic as Data

DZone's Guide to

How to Think of Your Business Logic as Data

Bottom line: Save time by making business logic your data. After all, if a Turing machine can do it, then so can your application.

· Big Data Zone
Free Resource

Access NoSQL and Big Data through SQL using standard drivers (ODBC, JDBC, ADO.NET). Free Download 

I’ll never forget this lesson that I learned from a friend around sixth or seventh grade.

We were building our own Windows clone... and we were doing it in Turbo Pascal, running in DOS, using a textual user interface because we didn’t know how to do graphics.

If you’re too young to know about textual user interfaces, they looked like this:

It’s got windows, buttons, a mouse cursor, and everything else you’d want in a modern user interface — except graphics. It’s all made with ASCII characters.

(I used to know the ASCII table by heart by back then!)

Now, when I say we were building a new Windows, I don’t mean working together on a single project. We didn’t know how to do that. There was no Git or CVS or SVN back then — at least not that we knew of. The best we could do back then was use diskettes to borrow each other’s code.

Oh, we also didn’t know about putting code into multiple files, so that was fun.

Anyway, the lesson he taught me about business logic being data came when we were both implementing our top row navigation — like a menu, but for your whole system.

Oh yes, we built drop-down menus and everything. It’s amazing what a 13-year-old with infinite free time can build in a few months.

Avoid Encoding Business Logic in the Shape of Your Program

Let’s say you have six items: File, Edit, Format, View, Window, and Help. That’s what iA Writer has.

Now let’s say you want to have a user action that goes through these items. My system used left and right arrow keys, and my friend liked j and k, while MacOS relies on mouse alone.

You could build navigation like this:

onLeftKeyPress() {
    if (currentMenu === "File") {
        goTo("Help")
    }else if (currentMenu === "Edit") {
        goTo("File")
    }else if (currentMenu === "Format") {
        goTo("Edit")
    }else if (currentMenu === "View") {
        goTo("Format")
    }else if (currentMenu === "Window") {
        goTo("View")
    }else if (currentMenu === "Help") {
        goTo("Window")
    }
}
 
onRightKeyPress() {
    if (currentMenu === "File") {
        goTo("Edit")
    }else if (currentMenu === "Edit") {
        goTo("Format")
    }else if (currentMenu === "Format") {
        goTo("View")
    }else if (currentMenu === "View") {
        goTo("Window")
    }else if (currentMenu === "Window") {
        goTo("Help")
    }else if (currentMenu === "Help") {
        goTo("File")
    }
}

Nothing wrong with that. It’s readable, it gets the job done; everything’s perfect. You congratulate yourself on an engineering problem well solved.

Then the PM comes in and says, “We’ve been running tests, and this sequence doesn’t really work. Let’s change the order.”

Uh-oh.

“Oh, and we want different apps to have different menus.”

Now, you have to rewrite that whole logic for every app every time the PM decides to change the order. That’s not fun at all!

So here’s what you can do instead:

items = ["File", "Edit", "Format", "View", "Window", "Help"]
currentItem = 0
 
onLeftKeyPress() {
    currentItem -= 1;
    if (currentItem < 0) currentItem = items.length-1;
    goTo(items[currentItem]);
}
onRightKeyPress() {
    currentItem += 1;
    if (currentItem >= items.length) currentItem = 0;
    goTo(items[currentItem]);
}

An array of options, and a pointer to the current selection that moves when the user does something. Now we’re talking!

With this approach, your system is flexible. You can change ordering, add elements, and remove elements, even have different lists for different apps or users. It’s great.

No difficult refactoring every time your PM changes their mind — just a data change.

But Swizec, Nobody Builds Keyboard Menus Anymore!

That’s true! People don’t use keyboards as much as they used to. My whole thing above is pointless when a user can directly tap or click whatever they want.

But we still live in a world of sequental flows. More than ever, things are designed as user flows that go backward or forward. Onboarding flows are a good example.

  • Screen 1: “Hai.”

  • Screen 2: “Our app does X.”

  • Screen 3: “Sign up.”

  • Screen 4: “Give us your phone number”

  • Screen 5: “Credit card maybe?”

  • Screen 6: “Do the thing.”

I simplify, but many apps have that flow.

You can build it as a hard-coded sequence of steps where each step must know who to call next. When your PM experiments, you’re in for a world of heavy refactoring.

I had fun like that just this week. Not my fault, even! Others on the team decided to build it the not-data way, and now we all suffer. I’m sure they will learn their lesson soon!

But Swiz, My Flow Has Branches and Sh*t

So?

You’re going to go into your super fancy logic and insert a bunch of if statements all the time?

if goNext and currentScreen is ‘phone’ and userSubscribed and…

F*ck. That.

Here’s how you do it:

[() => userSubscribed ? <CreditCard /> : <DoTheThing />, ...]

Put functions in your previous/next logic! Core logic stays simple, end result for user is a complex tree of options.

That can get tricky, too, I know. But you know what always works? Tree traversal. You can model your flow as a tree and build a simple walker that goes into different branches of the tree based on stuff — perhaps based on functions in the tree nodes themselves.

Save time. Make business logic your data. If a Turing machine can do it, so can your app.

Happy hacking!

The fastest databases need the fastest drivers - learn how you can leverage CData Drivers for high performance NoSQL & Big Data Access.

Topics:
big data ,business logic ,web app development

Published at DZone with permission of Swizec Teller, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}