Where do I validate business rules in a 3-tier application (quite long, sorry) ?

  • Thread starter Thread starter Ole
  • Start date Start date
O

Ole

Hi

Let me appologize for this since it is quite long but I've tried to explain
it as thouroughly as i could.

We're remaking an old application with three layers, presentation layer,
business logic (with a small facade layer) and datalayer. To use the
application you first define instructions that are later run by the
application on an instrument. The collection of instruction are called a
runscheme and follow certain rules that the business logic handles. In UML
it looks something like this (simplified)
____________ _____________
|RunScheme |-->|Instruction |
------------ *--------------

In the old application, the whole desing model made in UML is represented by
objects in the business layer and the object model can be manipulated by a
client via interfaces provided by the business layer.
So, for example if a user is making a RunScheme in the RunSchemeEditor it
first obtains a reference to a RunScheme object from a RunSchemeFactory in
the business layer. It then asks an InstructionFactory in the business layer
for a reference to a new Instruction object. The client edits the
instruction via an interface provided by the business layer. Then the client
adds it to a RunScheme object. When adding the instruction the business
layer validates this according to certain rules and generates an exception
if it is not ok. This is very stateful since the business layer provides
interfaces of exactly what can be done with the objects and the client holds
references to the interfaces. It is also quite simple IMHO.

However, now we're going .Net and now we have datasets which everyone says
should be just fetched and send directly to the client which can then bind
data to controls in the user interface. Well, this might be fine but I
really wonder who is validating the business rules. In my example above,
should the client add an extra row in the dataset table that represents an
instruction? In that case the client must know the representation of the
RunScheme object that is represented in the dataset? And how could the
client actually know if it is allowed, according to business rules, to
actually add an instruciton to the runscheme? This is in my opinion up to
the business layer to handle but how can it handle the rules if it just
forwards the data from the data layer to the client?

So my questions I think are:

1. Is it really a good thing to let a client have knowledge about the
dataset representing business objects and their relation. What happens if
the desing of the business layer changes? Then the client must also be
changed?
2. Who is actually validating the business rules? The client can not do this
since it should have no knowledge about these rules. On the other hand, the
client has the dataset and can play around with it with no validating done
until it sends it to the business layer.
3. Does the business layer has to span the object model as modelled in the
desing phase or is it enough for the business layer to work with the object
model represented by a dataset.
4. The desing patterns used in our previous application used factories for
object instantiation when read from persisten storage. Are they needed in
..Net application when using only with datasets?
5. In my example above with the runsheme and instruction, should it not be
the case that the client issues an addInstruction request to the business
layer to add a new instruciton, not that the client adds an instruction to a
dataset and then issues an update on teh dataset. In that case I see no
meaning with the business layer.

I would be really grateful for any comments about these issues.

Thanx,

Ollie
 
is this a Windows application or a Web application?

Or is it a Windows for now, and we want to port over to a web app later or
in pieces?
 
Thanks for your reply. I agree totally on what you say. The
application were writing is an enterprise application. We will deploy
the application as a set of services that handles the runscheme
editing, the instrument setup and the processing of the runscheme on
the instrument. Also we will have a facade layer to provide a generic
interface so that all clients have a standard way to talk to the
business layer. This is because some customers only edits runschemes
(they don't have an instrument) and some clients only processes
runschemes and some only has a process monitoring function that
basically only receives events from an ongoing process. We can
therefore install only the services (and UI components which most
likely will be Windows Forms) that the customer needs. Also, by using
the generic facade layer a customer can ideally write his own
application using the facades of the business layer.

I have read that working with services requires loose coupling and
that the information between a client and the services should be
stateless which works fine as I see it when working with datasets. But
datasets sort of removes the meaning of a business layer and, as you
said, brakes security rules and since we want thin clients we need a
business layer to handle business rules. So, in my previous example,
when working with runschemes and instructions, how does this
"stateless" thing comply with the using of services. I mean, the
business layer must keep the state of the appliciation while the UI
just presents the information. When the actor changed data in the UI,
the UI client uses interfaces to change the properties and attributes
of business object, i.e. the state in the business layer, so the
client must keep references to interfaces to business objects. When
running the instrument the instrument sends events and alarms to the
client so here they must have references to each other anyway since
the server (containing the business layer) have a list of observers
and the client must be able to issue actions to the instrument when
receiving alarms. But these references means tight coupling doesn't
it? What am I missing here? I'm a bit confused so if you have any good
words to sort of push me in the right thinking direction I would be
grateful.

Thanks again,

Ollie
 
So you have one instance on a server, or one per client of your business
logic DLL?

In either case, there is an "observer" pattern you can use. Tight coupling
is not required, and should be avoided when possible. To see the Observer
pattern, see the following link:

Observer pattern:
http://msdn.microsoft.com/practices/type/Patterns/Enterprise/DesObserver/
example implementation:
http://msdn.microsoft.com/practices/type/Patterns/Enterprise/ImpObserverInNET/

Other Microsoft pattern links:
"complete" list of patterns
http://www.microsoft.com/resources/practices/completelist.asp
layer patterns:
http://msdn.microsoft.com/practices...se/EspPatternsForBuildingEnterpriseSolutions/
 
Back
Top