From: LuchoLaf on
Hi, I have the following problem in my program and would like to hear
for other ideas:

I need to do a complex operation in the Business layer, which is
called from the UI layer:

UI layer:

businessLayer.SyncFromServer(...);

My problem is that in the middle of this action, if some condition is
true, the user must choose what to do next. It would be easy if the
operation could be splitted in two indendent tasks as:

UI layer:

bool conflict = businessLayer.CheckForConflicts();
bool override = true;
if (conflict)
override = askUser();
businessLayer.SyncFromServer(override, ...);

In my situation, CheckForConflicts() produces some intermediate
results that are needed in SyncFromServer() but I don't want to
populate the UI with much logic and business stuff. Btw, businessLayer
is basically a static layer with no state at all.

My proposed solution is to forget about the static layer and create a
Facade-like object with its own state to handle all the Sync stuff.
Something like this:

UI layer:

sync = new SyncFacade(...)
report = sync.Init();

bool override = true;
if (report.conflict)
override = askUser(report);

sync.Commit(override);

I thought it was a common UI <> Business interaction problem and would
like to hear for other object solutions.

Thanks

From: H. S. Lahman on
Responding to LuchoLaf...

> Hi, I have the following problem in my program and would like to hear
> for other ideas:
>
> I need to do a complex operation in the Business layer, which is
> called from the UI layer:
>
> UI layer:
>
> businessLayer.SyncFromServer(...);
>
> My problem is that in the middle of this action, if some condition is
> true, the user must choose what to do next. It would be easy if the
> operation could be splitted in two indendent tasks as:
>
> UI layer:
>
> bool conflict = businessLayer.CheckForConflicts();
> bool override = true;
> if (conflict)
> override = askUser();
> businessLayer.SyncFromServer(override, ...);
>
> In my situation, CheckForConflicts() produces some intermediate
> results that are needed in SyncFromServer() but I don't want to
> populate the UI with much logic and business stuff. Btw, businessLayer
> is basically a static layer with no state at all.

I agree that this is bleeding cohesion between UI and Business layer.
Think of the UI as a low-level service for the Business layer that
provides communications with the user.

(1) User makes a request to synch up the server. That goes to the
Business layer. From the UI perspective, it has no idea what that means;
it just knows to generate a particular message when the user clicks a
particular button.

(2) To do that properly the Business layer needs to check conflicts,
which it does first thing. That is business policy problem that has
nothing to do with UI displays.

(2a) When checking conflicts it discovers a problem only the user can
solve, so it sends a message to the UI to get information from the user.

(3) The UI responds to the requests from (2a) by doing its dialog thing
and then sends back a message with the user data. The UI doesn't need to
know why the data is needed or that it is intrinsic to synching up the
server; it just needs to know what dialog to put up when it gets that
particular message.

(4) The business layer eagerly awaits the information and when the
message from (3) arrives, it continues processing where it left off.

IOW, we have a message exchange like:

UI Solution
| |
| need to synch |
|-------------------------->|
| |
| need data |
|<--------------------------|
| |
| here's data |
|-------------------------->|
| |
| OK, we're synched |
|<--------------------------|
| |

The point is that each layer responds to multiple messages, each with
unique processing. By breaking up the processing this way we ensure that
the subject matters are decoupled. The UI does only UI things without
knowing why it is doing them. The Business solution solves problems
without worrying about the details of the user communications.

[BTW, there is an implied required sequencing here in the order of
requests (e.g., the UI always sends the "need to synch" message before
the "here's data" message). The easiest way to capture such sequencing
rules in the transitions of a state machine. Then there is an object
state machine on either side, the messages become events, and the
exchange of messages becomes a handshaking protocol between the state
machines.]


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: LuchoLaf on
Hi H.S,

The problem I see when doing this message exchange between 2 objects,
is that both have to "see" each other. I mean, the business should not
have a dependency to UI, but it has in this message exchange solution
you propose. However, I'm considering adding an Interface, sthg like
'Questionable', that the Business layer depends upon, then make the UI
implement it and pass a reference to the Business Object constructor,
so it can call it in a future.
This way UI depends on Business, Business depends on Questionable
iface, and the whole exchange can be done.

Luis

On Sep 5, 2:23 pm, "H. S. Lahman" <h.lah...(a)verizon.net> wrote:
> Responding to LuchoLaf...
>
>
>
> > Hi, I have the following problem in my program and would like to hear
> > for other ideas:
>
> > I need to do a complex operation in the Business layer, which is
> > called from the UI layer:
>
> > UI layer:
>
> > businessLayer.SyncFromServer(...);
>
> > My problem is that in the middle of this action, if some condition is
> > true, the user must choose what to do next. It would be easy if the
> > operation could be splitted in two indendent tasks as:
>
> > UI layer:
>
> > bool conflict = businessLayer.CheckForConflicts();
> > bool override = true;
> > if (conflict)
> > override = askUser();
> > businessLayer.SyncFromServer(override, ...);
>
> > In my situation, CheckForConflicts() produces some intermediate
> > results that are needed in SyncFromServer() but I don't want to
> > populate the UI with much logic and business stuff. Btw, businessLayer
> > is basically a static layer with no state at all.
>
> I agree that this is bleeding cohesion between UI and Business layer.
> Think of the UI as a low-level service for the Business layer that
> provides communications with the user.
>
> (1) User makes a request to synch up the server. That goes to the
> Business layer. From the UI perspective, it has no idea what that means;
> it just knows to generate a particular message when the user clicks a
> particular button.
>
> (2) To do that properly the Business layer needs to check conflicts,
> which it does first thing. That is business policy problem that has
> nothing to do with UI displays.
>
> (2a) When checking conflicts it discovers a problem only the user can
> solve, so it sends a message to the UI to get information from the user.
>
> (3) The UI responds to the requests from (2a) by doing its dialog thing
> and then sends back a message with the user data. The UI doesn't need to
> know why the data is needed or that it is intrinsic to synching up the
> server; it just needs to know what dialog to put up when it gets that
> particular message.
>
> (4) The business layer eagerly awaits the information and when the
> message from (3) arrives, it continues processing where it left off.
>
> IOW, we have a message exchange like:
>
> UI Solution
> | |
> | need to synch |
> |-------------------------->|
> | |
> | need data |
> |<--------------------------|
> | |
> | here's data |
> |-------------------------->|
> | |
> | OK, we're synched |
> |<--------------------------|
> | |
>
> The point is that each layer responds to multiple messages, each with
> unique processing. By breaking up the processing this way we ensure that
> the subject matters are decoupled. The UI does only UI things without
> knowing why it is doing them. The Business solution solves problems
> without worrying about the details of the user communications.
>
> [BTW, there is an implied required sequencing here in the order of
> requests (e.g., the UI always sends the "need to synch" message before
> the "here's data" message). The easiest way to capture such sequencing
> rules in the transitions of a state machine. Then there is an object
> state machine on either side, the messages become events, and the
> exchange of messages becomes a handshaking protocol between the state
> machines.]
>
> *************
> There is nothing wrong with me that could
> not be cured by a capful of Drano.
>
> H. S. Lahman
> h...(a)pathfindermda.com
> Pathfinder Solutionshttp://www.pathfindermda.com
> blog:http://pathfinderpeople.blogs.com/hslahman
> "Model-Based Translation: The Next Step in Agile Development". Email
> i...(a)pathfindermda.com for your copy.
> Pathfinder is hiring:http://www.pathfindermda.com/about_us/careers_pos3.php.
> (888)OOA-PATH


From: H. S. Lahman on
Responding to LuchoLaf...

> The problem I see when doing this message exchange between 2 objects,
> is that both have to "see" each other. I mean, the business should not
> have a dependency to UI, but it has in this message exchange solution
> you propose. However, I'm considering adding an Interface, sthg like
> 'Questionable', that the Business layer depends upon, then make the UI
> implement it and pass a reference to the Business Object constructor,
> so it can call it in a future.
> This way UI depends on Business, Business depends on Questionable
> iface, and the whole exchange can be done.

I have to disagree. The whole point of encapsulating UI and Business in
subsystems or layers is so that their implementations are completely
decoupled. An object in the Business layer should not even know a
particular Window or Dialog object exists in the UI nor should the UI
know what objects exist in the Business layer.

The subsystem interface provides access to services that each layer
should logically provide according to the nature of their subject
matter. Thus the UI provides user communication services and the
Business layer solves some customer problem involving servers. In fact,
the most common way subsystems and layers are encapsulated is through
the Facade pattern, which completely hides the objects. So...

>>IOW, we have a message exchange like:
>>
>>UI Solution
>> | |
>> | need to synch |
>> |-------------------------->|
>> | |
>> | need data |
>> |<--------------------------|
>> | |
>> | here's data |
>> |-------------------------->|
>> | |
>> | OK, we're synched |
>> |<--------------------------|
>> | |

These are messages in the interface of each subsystem/layer and they
reflect the basic invariants of the services each subsystem/layer
provides. That is, they represent access to subject matter services
rather than individual objects. Thus the UI sends two messages:

need to synch. This will be a simple response to some button click or
whatever in the UI. The semantics of server synchronization is mapped in
the interface because that semantics is relevant to the Solution subject
matter. Only the Solution subject matter interface will know how to
re-dispatch that message to whoever will deal with synching up servers.
OTOH, in a GUI, that message is just {message ID, <data packet>} that
needs to be generated when the user does something to a particular
control. A GUI builder would provide that mapping through an external
configuration file (e.g., a Windows resource file).

here's data. This message is triggered when the UI has finished doing
its thing to get the requested information from the user. Getting such
information is a basic service of providing communications with the
user. The Solution knows nothing about how that it done and the UI knows
nothing about why that particular information is needed by the solution.

Similarly, the Solution sends two messages to the UI:

need data. The Solution needs data that only the user can provide. Since
the UI subject matter exists to communicate with the user, the Solution
sends the request to the UI. But the Solution knows nothing about how
the UI will get the information.

OK, we're synched. This message is only needed if providing UI
communications requires it (e.g., the cursor needs to be released from
an hourglass once the server has been synched up so that the user can do
other fun stuff). It is the nature of the UI service that requires it to
be notified when the solution has finished doing something. So the
Solution must send that announcement. But the Solution doesn't know why
the UI needs it and the UI doesn't know what the Solution was doing.

OTOH, the designer of the overall application does understand what sort
of collaborations will be needed between the two subsystems/layers,
which includes any sequencing constraints across messages. So the
application design specifies those services in the subsystem/layer
subject matter definition and specifies the sequencing constraints in
the interface definitions. Once that it done, both subsystems/layers can
be developed completely independently.

You might also find the "Application Partitioning" category of my blog
of interest.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH