|
Prev: Temp control design
Next: Call for Papers: IAENG International Conference on Computer Science (ICCS 2008)
From: LuchoLaf on 4 Sep 2007 16:26 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 5 Sep 2007 13:23 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 5 Sep 2007 14:49 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 6 Sep 2007 13:23
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 |