The past three posts of this little mini-series
have gone from a >Working definition of business logic
to a >Rigorous definition of business logic
and on to some >theorems about business logic.
To wrap things up, I'd like to ask the question,
is it possible to isolate business logic into
a single tier?
Related Reading
There are plenty of opinions out there.
For a pretty thorough explanation of how to put
everything into the DBMS, check out
>Toon Koppelaar's description. Mr.
Koppelaars has some good material, but you do
need to read through his earlier posts to get
the definitions of some of his terms. You can also
follow his links through to some high quality
discussions elsewhere.
Contrasting Mr. Koppelaar's opinion is a piece
which does not have nearly the same impact, IMHO,
because in
>Dude, Where's My Business Logic? we get some solid
history mixed with normative assertions based on
either anecdote or nothing at all. I'm a big believer
in anecdote, but when I read a sentence that
says, "The database should not have any knowledge of what a customer is, but only of the elements that are used to store a customer." then
I figure I'm dealing with somebody who needs to see
a bit more of the world.
Starting At the Top: The User Interface
First, let's review that our rigorous definition of business logic
includes schema (types and constraints),
derived values (timestamps, userstamps, calculations,
histories), non-algorithmic compound operations
(like batch billing) and algorithmic compound
operations, those that require looping in their
code. This encompasses everything we might do
from the simplest passive things like a constraint
that prevents discounts from being over 100% to
the most complex hours-long business process,
along with everything in between accounted for.
Now I want to start out by using that definition
to see a little bit about what is going on in
the User Interface. This is not the presentation
layer as it is often called but the interaction
layer and even the command layer.
Consider an admin interface to
a database, where the user is entering or modifying
prices for the price list. Now, if the user could
enter "Kim Stanley Robinson" as the price, that would be
kind of silly, so of course the numeric inputs
only allow numeric values. Same goes for dates.
So the foundation of usability for a UI
is at very least
knowlege of and enforcement of types in
the UI layer. Don't be scared off that I am
claiming the UI is enforcing anything, we'll
get to that a little lower down.
Now consider the case where the user is
typing in a discount rate for this or that,
and a discount is not allowed to be over 100%.
The UI really ought to enforce this,
otherwise the user's time is wasted when she
enters an invalid value, finishes the entire form,
and only then gets an error when she tries to
save. In the database world we call this
a constraint, so the UI needs to know about
constraints to better serve the user.
Now this same user is typing a form where there
is an entry for US State. The allowed values are
in a table in the database, and it would be nice
if the user had a drop-down list, and one that
was auto-suggesting as the user typed. Of course
the easiest way to do something like this is just
make sure the UI form "knows" that this field is
a foreign key to the STATES table, so it can generate
the list using some generic library function that
grabs a couple of columns out of the STATES
table. Of course, this kind of lookup thing will
be happening all over the place, so it would work
well if the UI knew about and enforced foreign
keys during entry.
And I suppose the user might at some point be
entering a purchase order. The purchase order is
automatically stamped with today's date. The
user might see it, but not be able to change it,
so now our UI knows about system-generated values.
Is this user allowed to delete a customer?
If not, the button should either be grayed out or not
be there at all. The UI needs to know about
and enforce some security.
More About Knowing and Enforcing
So in fact the UI layer not only knows the logic
but is enforcing it. It is enforcing it for
two reasons, to improve the user experience with
date pickers, lists, and so forth, and to prevent the user
from entering invalid data and wasting round trips.
And yet, because we cannot trust what comes in
to the web server over the wire, we have to
enforce every single rule a second time when
we commit the data.
You usually do not hear people say that the UI
enforces business logic. They usually say the
opposite. But the UI does enforce business logic.
The problem is, everything the UI enforces has
to be enforced again. That may be why we often
overlook the fact that it is doing so.
The Application and The Database
Now let's go through the stuff the UI is
enforcing, and see
what happens in the application and the database.
With respect to type, a strongly typed language
will throw an error if the type is wrong, and a weakly
typed language is wise to put in a type check anyway.
The the DBMS is going to only allow correctly typed
values, so, including the UI,
type is enforced three times.
With respect to lookups like US state, in
a SQL database we always let the server do that
with a foreign key, if we know what is good for
us. That makes double enforcement for lookups.
So we can see where this is going. As we look at
constraints and security and anything else that
must be right, we find it will be enforced at least
twice, and as much as three times.
You Cannot Isolate What Must be Duplicated
By defining First Order Business Logic, the simplest
foundation layer, as including things like types
and keys and constraints, we find that the enforcement
of this First Order stuff is done 2 or 3 times, but
never only once.
This more or less leaves in tatters the idea of a
"Business Logic Layer" that is in any way capable of
handling all business logic all by its lonesome.
The UI layer is completely useless unless it is
also enforcing as much logic as possible, and
even when we leave the Database Server as the
final enforcer of First Order Business Logic
(types, constraints, keys), it is still often good
engineering to do some checks to prevent
expensive wasted trips to the server.
So we are wasting time if we sit around trying to figure
out how to get the Business Logic
"where it belongs", because it "belongs" in at
least two places and sometimes three. Herding
the cats into a single pen is a fool's errand, it
is at once unnecessary, undesirable, and impossible.
Update: Regular reader Dean Thrasher of Infovark summarizes
most of what I'm saying here using an apt industry
standard term: Business Logic is a cross-cutting concern.
Some Real Questions
Only when we have smashed the concept that Business
Logic can exist in serene isolation in its own layer
can we start to ask the questions that would actually
speed up development and make for better engineering.
Freed of the illusion of a separate layer, when we
look at the higher Third and Fourth Order Business
Logic, which always require coding, we can decide where
they go based either on >engineering or the availability of qualified
programmers in particular technologies,
but we should not make
the mistake of believing they are going where they
go because the gods would have it so.
But the real pressing question if we are seeking
to create efficient manageable large systems is
this: how we distribute
the same business logic into 2 or 3 (or more)
different places so that it is enforced
consistently everywhere. Because a smaller code
base is always easier to manage than a large one,
and because configuration is always easier than
coding, this comes down to meta-data, or if you
prefer, a data dictionary. That's the trick that
always worked for me.
Is This Only A Matter of Definitions?
Anybody who disagrees with the thesis here has
only to say, "Ken, those things are not business
logic just because you wrote a blog that says they
are. In my world business logic is about code
baby!" Well sure, have it your way.
After all, the nice thing about definitions is that we
can all pick the ones we like.
But these definitions, the theorems I derived on
Tuesday, and the multiple-enforcement thesis presented
here today should make sense to anbyody struggling
with where to put the business logic. That struggle
and its frustrations come from the mistake of
imposing abstract
conceptual responsibilities on each tier instead
of using the tiers as each is able to get the
job done. Databases are wonderful for type,
entity integrity (uniqueness), referential integrity,
ACID compliance, and many other things. Use them!
Code is often better when the problem at hand cannot
be solved with a combination of keys and constraints
(Fourth Order Business Logic), but even that code can
be put into the DB or in the application.
So beware of paradigms that assign responsibility
without compromise to this or that tier. It cannot
be done. Don't be afraid to use code for doing things
that require structured imperative step-wise operations,
and don't be afraid to use the database for what it is
good for, and leave the arguments about "where everything
belongs" to those with too much time on their hands.
Update Contact :
No Wa/Telepon (puat) : 085267792168
No Wa/Telepon (fajar) : 085369237896
Email : Fajarudinsidik@gmail.com
No Wa/Telepon (puat) : 085267792168
No Wa/Telepon (fajar) : 085369237896
Email: Fajarudinsidik@gmail.com
atau Kirimkan Private messanger melalui email dengan klik tombol order dibawah ini :