The way I see it, the 'isLoggedIn' is a very ambigious property.  If you
need to know whether a user is currently logged into the system
(irrespective of the interface they are using), then yes, that's part of the
business logic, and should be stored in the user table in the DB, just like
any other field.  That's useful in an abstract, business-logic sense.  For
example, generating a list of users currently using the application, or
checking whether user X is online and can receive a chat request.

However, if you're using the property to track a session, then it's not
business logic, because you can't use that info in the business layer (nor
will you persist it).  In other words, it's meaningless except at the
presentation layer.  You're saying that not only is the user logged in (the
business logic part), but also that the specific session tied to this user
instance is logged in.  The "specific session" should throw all kinds of
warning bells, since "session" isn't understood by the business layer, only
the presentation layer.

I'm all for storing the first type of info in your user object; it can be
very useful information, particularly with applications where real-time
collaboration happens.  The second type of info should be stored in a
interface specific means (a session variable, in your case).  Not to say
that interfaces can't have shared storage, we use client variables for users
on the CFML/HTML interface and for CFC-based web services.  It might be a
third layer between business and presentation, but it's not a business logic
concern, and so shouldn't be mixed in with your business objects.

Cheers,
barneyb

> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On Behalf Of Steve Bryant
> Sent: Wednesday, April 28, 2004 10:35 AM
> To: [EMAIL PROTECTED]
> Subject: RE: [CFCDev] CFC interaction (user log in)
> 
> I thought that I understood the difference between business and 
> presentation logic, but now I am not so sure.
> 
> My thinking was that isLoggedIn was a property of the User 
> object. The user 
> is or is not logged in. In my presentation logic, I would check that 
> property of the User object in order to make decisions about 
> what to display.
> 
> In actual production, I probably wouldn't use an "isLoggedIn" 
> property, but 
> rather some sort of description about what type of User the 
> user is (what 
> role they are in maybe - except that I find Hal Helm's 
> arguments in favor 
> of permissions over roles very persuasive).
> 
> This seems, to me, to be part of business logic. I am not yet 
> making any 
> decisions about presentation. I am instead trying to use my 
> Security object 
> set properties of the User object.
> 
> I realize that it is a little odd for a Security object to 
> set properties 
> of a User object (and I am certainly open to changing my 
> ways), but I was 
> thinking in terms of the third umpire from the three umpires story.
> -----------------------------------------------
> Umpire #1: "I calls 'em as I sees 'em."
> Umpire #2: "I calls 'em as they is."
> Umpire #3: "They are as I calls 'em."
> -----------------------------------------------
> 
> Is it not appropriate to set properties of the User object 
> that will later 
> be used in presentation logic? Why is it better to set 
> Session.isAuthorized 
> than Session.User.isLoggedIn (which I was essentially 
> thinking of doing 
> through a method so that my Security object wouldn't have to 
> actually know 
> which properties my User object was using for that sort of thing)?
> 
> I guess that I am essentially not understanding why anything 
> in the Session 
> object in inextricably tied to presentation logic. What am I missing?
> 
> Thanks!
> 
> Steve
> 
> 
> At 10:07 AM 4/28/2004 -0700, you wrote:
> >There's a fundemental separation between different types of 
> logic that I
> >think your missing: business and presentation logic.  
> Business logic is
> >obviously the stuff that makes your application work.  
> Authenticating a
> >user, posting a document, and updating a product inventory, 
> are all business
> >logic.  Business logic is independent of the interface, it's 
> purely abstract
> >tasks.
> >
> >Presentation logic, on the other hand, is exclusively related to the
> >interface your client (be it a person, machine, whatever) is 
> using to talk
> >to the application.  This might be a CF/HTML, CFCs/Web 
> Services, Flash
> >Remoting, WAP, whatever.  This is the realm where session 
> variables, form
> >validation, and all that fun stuff lives.
> >
> >So with your validation and session tracking, you've got a 
> piece of both
> >halves.  The checkLogin function is pure business logic, but 
> how to handle
> >the result and persist it across requests is presentation 
> logic.  By adding
> >the isLoggedIn field to the User CFC, you're trying to make 
> it live on both
> >sides of the fence.  It's a business object, so part of the 
> business logic,
> >but integrating it with your session tracking (by making 
> it's behaviour
> >dependant on being cached in a session scope) is tying it to 
> presentation
> >logic as well.  That's why I suggested a separate variable 
> for tracking
> >authentication.  If you want to store an instance of the 
> User cfc in the
> >session scope, that's great, but don't try to make it help with your
> >authentication/authorization management system, which is 
> undoubtedly tied to
> >the presentation medium.
> >
> >Business logic is well suited for a high level of 
> abstraction, be it CFCs,
> >Java objects, EJBs, web services, whatever.  Presentation 
> logic, on the
> >other hand, isn't as well suited to a high level of 
> abstraction, because it
> >is inherently tied to a specific medium (html, flash, 
> whatever).  As soon as
> >you change the medium, the logic probably needs to be 
> changed as well.  The
> >trick is to make your presentation layer as lightweight as 
> possible, and to
> >encapsulate as much as you can in your business logic.
> >
> >Hopefully that all makes sense.
> >
> >Cheers,
> >barneyb
> >
> > > -----Original Message-----
> > > From: [EMAIL PROTECTED]
> > > [mailto:[EMAIL PROTECTED] On Behalf Of Steve Bryant
> > > Sent: Wednesday, April 28, 2004 9:50 AM
> > > To: [EMAIL PROTECTED]
> > > Subject: RE: [CFCDev] CFC interaction (user log in)
> > >
> > > I think that makes sense, although I have to confess that I
> > > am still a
> > > little confused.
> > >
> > > Here is what I have:
> > > Security.cfc:
> > > <cffunction name="checkLogin" returntype="boolean"
> > > access="public" output="No">
> > >          <cfargument name="UserID" type="numeric" default="0">
> > >          <cfset var isLoggedIn = false>
> > >          <cfif UserID eq 1>
> > >                  <cfset isLoggedIn = true>
> > >          </cfif>
> > >          <cfif isLoggedIn>
> > >                  <cfset Session.User.login()>
> > >          </cfif>
> > >          <cfreturn isLoggedIn>
> > > </cffunction>
> > > Obviously this won't be the production code.
> > >
> > > User.cfc:
> > > <cffunction name="login" returntype="boolean"
> > > access="package" output="No">
> > >          <cfscript>
> > >          this.isLoggedIn = true;
> > >          //return this;
> > >          </cfscript>
> > >          <cfreturn true>
> > > </cffunction>
> > >
> > > If I read this correctly, I should ditch:
> > > <cfset Session.User.login()>
> > > from Security.checkLogin() and take care of that in the code
> > > that calls
> > > Security.cfc?
> > >
> > > The advantage of that would be that each CFC would be more
> > > independent and
> > > therefore more reusable. The disadvantage is that I now have
> > > to have some
> > > logic outside of my CFCs. I guess that I could use a
> > > controller cfm file to
> > > handle that.
> > >
> > > The problem with this (in my mind at least) is that I was
> > > hoping to have
> > > all of my logic in CFCs. It seems that I either have to have CFCs
> > > interacting and less reusable or have some logic outside 
> of the CFCs.
> > >
> > > I am guessing that the answer lies in using a design pattern
> > > that includes
> > > as one aspect to have a CFC whose whole job is to handle 
> interaction
> > > between other CFCs and that I should read the gang of four
> > > book since I
> > > obviously don't know any of this stuff already.
> > >
> > > In fact, I am already convinced that I need to learn design
> > > patterns. The
> > > real question is, do I read the original gang of four 
> book or start
> > > elsewhere? So, I guess I have added another question onto an
> > > email full of
> > > them.
> > >
> > > I really do appreciate the feedback. Sorry it just inspires
> > > me to ask more
> > > questions. =)
> > >
> > > Thanks,
> > >
> > > Steve
> > >
> > >
> > > At 08:36 AM 4/28/2004 -0700, you wrote:
> > > >I think you're pretty close.  Your hunch about user.login()
> > > was correct.
> > > >I'd put your login method in your security CFC, since 
> it's not a user
> > > >function, it's a security function that's being performed.
> > > The method would
> > > >return true or false whether the login was successful.  If
> > > false, just go
> > > >back to the form.  If true, set some marker (I use
> > > session.authenticated) to
> > > >indicate that the session has been authenticated, and do
> > > whatever other
> > > >setup you need (such as instantiating the user cfc into the
> > > session scope).
> > > >
> > > >Always keep in mind that you don't want CFCs interacting
> > > with any scopes
> > > >except their own internal instance variables and 
> arguments passed to
> > > >methods.  As soon as you reference any external scope from
> > > within a CFC,
> > > >that CFC instantly becomes much less reusable.  However,
> > > it's generally a
> > > >desirable thing to instantiate CFCs INTO shared scopes.
> > > That way all their
> > > >instance variables are, in effect, members of that scope, so
> > > you get caching
> > > >and such.  Just be careful with locking and all the usual
> > > concerns with
> > > >shared scopes.
> > > >
> > > >Once you get to doing web services (if you have stateful,
> > > multi-request
> > > >services), then you can reuse everything.  You probably
> > > won't be storing a
> > > >user CFC in the session scope, and you might not use the
> > > session scope at
> > > >all, but your checkLogin method in security.cfc will be
> > > identical, you'll
> > > >just deal with the boolean result differently.
> > > >
> > > >Cheers,
> > > >barneyb
> > >
> > > ----------------------------------------------------------
> > > You are subscribed to cfcdev. To unsubscribe, send an email
> > > to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
> > > in the message of the email.
> > >
> > > CFCDev is run by CFCZone (www.cfczone.org) and supported
> > > by Mindtool, Corporation (www.mindtool.com).
> > >
> > > An archive of the CFCDev list is available at
> > > www.mail-archive.com/[EMAIL PROTECTED]
> > >
> >
> >----------------------------------------------------------
> >You are subscribed to cfcdev. To unsubscribe, send an email
> >to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev'
> >in the message of the email.
> >
> >CFCDev is run by CFCZone (www.cfczone.org) and supported
> >by Mindtool, Corporation (www.mindtool.com).
> >
> >An archive of the CFCDev list is available at 
> >www.mail-archive.com/[EMAIL PROTECTED]
> 
> ----------------------------------------------------------
> You are subscribed to cfcdev. To unsubscribe, send an email
> to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
> in the message of the email.
> 
> CFCDev is run by CFCZone (www.cfczone.org) and supported
> by Mindtool, Corporation (www.mindtool.com).
> 
> An archive of the CFCDev list is available at 
> www.mail-archive.com/[EMAIL PROTECTED]
> 

----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at www.mail-archive.com/[EMAIL PROTECTED]

Reply via email to