Re: Design Question
From: Nunaya (nunaya2004_at_yahoo.com)
Date: 04/29/04
- Next message: Vijay Singh: "High Level & Low Level Design"
- Previous message: Matthias Hofmann: "Re: Aggregation vs composition"
- In reply to: H. S. Lahman: "Re: Design Question"
- Next in thread: Robert C. Martin: "Re: Design Question"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 29 Apr 2004 08:50:17 -0700
"H. S. Lahman" <h.lahman@verizon.net> wrote in message news:<QHWjc.38686$2v.23747@nwrdny02.gnilink.net>...
> Responding to Nunaya...
>
> >>>So the salesrep object does not do the validation? The customer class
> >>>would communicate directly with the data access layer that would query
> >>>the DB to ensure the salesrep was valid?
> >>
> >>This is a matter of context and responsibility. Who cares if the
> >>salesrep is in the DB? If one is validating user input, it might be the
> >>UI that does the validation. If one is batching "add" DB transactions
> >>into a dataset, whoever is doing that batching probably should do the
> >>validation.
> >
> >
> > But let's be clear, the UI does the validation through the use of the
> > business layer, does it not? I guess in that case, the GUI *could*
> > validate that a valid salesrep has been selected from the list, prior
> > to attempting to add the salesrep to a customer. The problem I see
> > with this approach is that I am reluctant to not have the business
> > layer do the validation itself. This removes the potential that the
> > GUI programmer will forget to implement the validation check.
>
> There are several disconnects here (e.g., I partition applications in 2D
> via subsystems rather than 1D layers). I should have foreseen that and
> used a different example than a UI. Pretend I never mentioned it. B-)
Forgotten! :)
>
> As far as the general issue of where to validate is concerned, there are
> two conflicting principles: (1) validate at the earliest possible point
> and (2) validate only things understood by the subject matter. UIs are
> obviously the earliest place to validate user input. OTOH, they are
> very dumb; the only semantics they understand is data entry and display.
>
> You can have some long and controversial discussions about which rule
> applies in a given situation. Because I partition by subsystem, in my
> world there is no problem with the UI directly querying the DB access
> subsystem but in the layer models one has to use the Business layer as a
> middleman to do that because it sits between UI and DB.
This is our intention, to validate at the business layer.
>
> [FWIW, I would probably not let the UI query the DB access directly. My
> rule of thumb is that UIs shouldn't check anything that can't be
> expressed as a data comparison (e.g., > 0, a part number pattern, etc.).
> IOW, don't check anything that isn't data supplied with the request or
> available through external configuration data. To ask the DB for
> validation the UI would have to know too much about the semantics of the
> data (e.g., it's a salesman's ID and valid = persisted). So I would
> likely opt for option (2). So that would put me in the equivalent of
> your Business layer anyway. B-)]
I agree. I don't intend to have the UI ever query the DB directly.
Instead, any validation that the UI wants to do would be handled as a
call to some object in the business layer.
>
> >
> > The approach I am leaning towards is having a customersalesrep object
> > that knows how to talk to the customer object, and how to talk to
> > salesrep object. Between the two, it is able to validate that a valid
> > customer has been passed to it, and a valid salesrep has been passed
> > to it before passing the relationship to the data tier for
> > persistence.
>
> Given that you are going through the Business layer, I still think it
> depends upon the reason for the validation. Is the user supposedly
> adding a new sales person? If so, whoever instantiates the salesrep
> object should check before doing so.
I think that is the crux of the issue. A customer is selected on the
screen from a listbox. We now know the PK for the customer we are
dealing with. A list of all salesreps is displayed in a combo box and
the user can select a salesrep from the list to be associated with the
selected customer (in reality, it will be more complicated if we allow
multiple salesreps for a customer). When the salesrep is selected, we
now know the PK for the salesrep. When the user goes to save the
customer information, it is then a matter of making a call to
customersalesrep to pass the two PK's, have the customersalesrep
object attempt to create a customer object and a salesrep object for
an existing customer and salesrep based on the two PK values passed,
and if that succeeds (meaning both were found from the call to the
data layer), the two values are then passed to the data layerfor
persistence in the customersalesrep table. While not trying
complicate things, the process could also work the other way where we
select a salesrep, and then want to maintain all customers associated
with that salesrep. I think the customersalesrep object would still
be used for that as well.
>
> If the user is merely trying to identify a sales rep and one is checking
> for typos, then there is some other context that is broader than the
> sales rep that is being processed. That is, the sales rep is supporting
> data for some other request. In that case, whoever would process that
> request should probably do the checking.
>
> [Unfortunately the last example opens a broader issue of UI design. Why
> should the user have to define the sales rep in the context of some
> other request? That information is already in the DB so the user
> shouldn't need to input it. (Or, at most, the user should select from a
> pick list whose entries were acquired from the DB to initialize the
> dialog the user is accessing.) But let's no go there.]
>
> Perhaps more relevant, when do the application's memory instances for
> customer, sales rep, etc. get instantiated?
I'm thinking this is done as needed. The customer maintenance screen
is opened, the customer object is instantiated, and a list of
customers is retrieved via a customer object method (through the data
tier) and the values are used to populate the listbox. The customer
object is then destroyed as it goes out of scope. The user selects
"Fred's Sheds" from the customer list and the customer object is
instantiated and a method is called that populates customer properties
on the customer object for "Fred's Sheds". These properties are then
read by the GUI and the various controls on the screen are set to
those values. The user makes changes and goes to persist the data
through the save button. The customer object is instantiated, the
customer object properties are set to the values in the GUI, and the
customer object's save method is called to persist the values
(obviously with the save function first validating the data passed to
the object). The user has also changed the salesrep for this
customer, so in that case, the customersalesrep object is
instantiated, the customerid and salesrepid properties are set, and
the save method is called which validates both IDs and persists the
relationship using the data layer. The IDs would be validated by the
customersalesrep object when it attempt to create an existing salesrep
object and an existing customer object based on the IDs passed to it,
all of which is done internally within the customersalesrep object.
> I would expect that to be
> done from the DB as soon as one had some clue from the user about the
> context. For example, if the user identifies a particular customer and
> the application routinely deals with sales reps, why wouldn't the sales
> reps for that customer be read form the DB immediately? Then when the
> user gets around to identifying a particular sales rep you only have to
> see if it is instantiated as a business object.
The list of salesreps could very well be a business object that
persists for the life of the screen. Generally, we try to instantiate
objects and destroy them as quickly as possible once the operation is
completed. This is obviously a general rule as we have to balance the
need for efficient use of memory resources and the performance penalty
for recreating objects each time they are needed.
>
> Obviously I don't have enough information about your problem to
> speculate on this. I am just pointing out that there is a 3-way trade
> off between UI needs, business problem needs, and DB access efficiency
> when triggering when business objects are instantiated. One of magical
> design activities is organizing interface protocols so that things like
> validating whether a sales rep is in the DB can be done elegantly (i.e.,
> talking to the DB once for many possible user contexts).
>
> >
> >
> >>Assuming 'valid' means a tuple with that identity exists in the DB AND
> >>Customer is the one who cares, then Customer would query the data access
> >>layer and that data access layer would relay that in the appropriate
> >>format (SQL?) to the DB.
> >>
> >>Note, though, that the application solution has its own set of data
> >>needs and it may think of 'valid' in a more generic context. It may
> >>also think of identity differently. The job of the data access layer is
> >>to interpret, "Is John Doe a valid sales guy" as meaning, "In the
> >>SalesRep table, is there a row with key 'John Doe'". In this case that
> >>mapping is very likely to be 1:1 but it may not be.
> >>
> >>For example, suppose your application adds a customer to a particular
> >>sales person's list of clients. That message to the data access layer
> >>may be, "I've assigned John Doe to customer Amalgamated Mutton." The
> >>data access layer may have to add John Doe to the SalesRep file (if this
> >>is a new sales person) in addition to putting the obvious entry in the
> >>CustomerSalesRep table. Being able to encapsulate these sorts of rules
> >>that are unique to the DB view is a big reason why one wants to
> >>encapsulate DB access.
> >
> >
> > Adding a new salesrep would be a function of the salesrep object.
> > There would likely be a button on the GUI that would invoke a screen
> > to handle collecting the data needed for a new salesrep. Once the
> > salesrep was entered, the GUI would call the customersalesrep object
> > to actually add the salesrep to the selected customer.
>
> The question I would push back with is: does the user click that button
> before or after a check is made to see if the sales rep is already
> there? If I were a user I would be a bit miffed if I entered in all the
> data just to discover someone else had already entered the sales rep.
> Not to mention the developer side aggravation of resolving
> inconsistencies between what I entered and what the DB had already.
>
> I mention this just to reinforce my points above that ideally one wants
> a very friendly UI and it needs to play properly with business object
> instantiation and DB access. IME, a user friendly GUI will usually go
> hand-in-hand with instantiating business objects early in the
> processing, which will involve going to the DB early. IOW, what's
> already in the DB should be driving the UI displays until the user is
> sure something needs to be added. So one may be able to provide
> validation in the business layer directly rather than going to the DB.
>
The design of the GUI is of critial importance because it is the only
thing the user has to interface with. You could have the greatest
object model in the world, and the project will fail if the GUI is
garbage. My examples at the GUI level are not cast in stone, and in
fact, many of the examples are just that, examples, and simple ones at
that to not confuse the main issue we are discussing related to the
object model. Maybe there is more of a blurred line between the two
than I want to realize! Everything I read tells me no, but the
theoretical world and the real world are sometimes at odds with one
another.
> *************
> There is nothing wrong with me that could
> not be cured by a capful of Drano.
>
> H. S. Lahman
> hsl@pathfindermda.com
> Pathfinder Solutions -- Put MDA to Work
> http://www.pathfindermda.com
> (888)-OOA-PATH
You have made some really good points in your post. Thank you again
for your insight.
- Next message: Vijay Singh: "High Level & Low Level Design"
- Previous message: Matthias Hofmann: "Re: Aggregation vs composition"
- In reply to: H. S. Lahman: "Re: Design Question"
- Next in thread: Robert C. Martin: "Re: Design Question"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|