0
Participant
,
/t5/coldfusion-discussions/what-cfc-best-practices/td-p/169641
Jul 13, 2008
Jul 13, 2008
Copy link to clipboard
Copied
What do you think of this code? Am I using arguments right?
Should I be using argmuents collection instead? Does cfparam become
redundant when you use cfargument? Thanks for any advice I'm just
trying to understand these last points thanks again
TOPICS
Getting started
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
1 Correct answer
LEGEND
,
Jul 14, 2008
Jul 14, 2008
>
<cfparam name="session.getemp" default="">
> I (generally, if it can be avoided ~) would not access external scopes
> directly within a CFC method. It breaks encapsulation and makes code less
> reusable.
> hmm I don't understand- I was setting a default for the session.getemp session
> so it was set inside, apologies I don't understand that one
It's perhaps a good idea if you read up on encapsulation or data hiding.
Or the fundamentals of procedural programming (leaving aside OO principles
...
> I (generally, if it can be avoided ~) would not access external scopes
> directly within a CFC method. It breaks encapsulation and makes code less
> reusable.
> hmm I don't understand- I was setting a default for the session.getemp session
> so it was set inside, apologies I don't understand that one
It's perhaps a good idea if you read up on encapsulation or data hiding.
Or the fundamentals of procedural programming (leaving aside OO principles
...
LEGEND
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169642#M15407
Jul 13, 2008
Jul 13, 2008
Copy link to clipboard
Copied
> What do you think of this code?
> <cfcomponent>
> <cffunction name="getEmp" access="remote">
I would alsoways specify all attributes for <cfcomponent>, <cffunction> and
<cfargument> tags. It makes the code more self-documenting. Although I
think the DISPLAYNAME attribute is a complete waste of time, so I don't
bother with that.
> <cfparam name="session.getemp" default="">
I (generally, if it can be avoided ~) would not access external scopes
directly within a CFC method. It breaks encapsulation and makes code less
reusable.
> <cfif NOT IsStruct(session.getemp)>
> <cfset session.getemp = StructNew()></cfif>
WHy don't you just param it to a struct in the first place?
> <cfargument name="username" required="true">
> <cfargument name="email" required="true">
> <cfargument name="telephone" required="true">
> <cfparam name="arguments.username" default="">
> <cfparam name="arguments.email" default="">
> <cfparam name="arguments.telephone" default="">
These arguments are flagged as REQUIRED, so the <cfparam> lines are
redundant. The arguments intrinsically need to be passed in, or the
function call would have errored.
> <!--- Now do Error Checking --->
> <cfparam name="errors" type="string" default="">
You're not VARing this variable.
> <cfif arguments.username EQ "">
> no name</cfif>
It's generally considered poor form to output anything from a function.
--
Adam
> <cfcomponent>
> <cffunction name="getEmp" access="remote">
I would alsoways specify all attributes for <cfcomponent>, <cffunction> and
<cfargument> tags. It makes the code more self-documenting. Although I
think the DISPLAYNAME attribute is a complete waste of time, so I don't
bother with that.
> <cfparam name="session.getemp" default="">
I (generally, if it can be avoided ~) would not access external scopes
directly within a CFC method. It breaks encapsulation and makes code less
reusable.
> <cfif NOT IsStruct(session.getemp)>
> <cfset session.getemp = StructNew()></cfif>
WHy don't you just param it to a struct in the first place?
> <cfargument name="username" required="true">
> <cfargument name="email" required="true">
> <cfargument name="telephone" required="true">
> <cfparam name="arguments.username" default="">
> <cfparam name="arguments.email" default="">
> <cfparam name="arguments.telephone" default="">
These arguments are flagged as REQUIRED, so the <cfparam> lines are
redundant. The arguments intrinsically need to be passed in, or the
function call would have errored.
> <!--- Now do Error Checking --->
> <cfparam name="errors" type="string" default="">
You're not VARing this variable.
> <cfif arguments.username EQ "">
> no name</cfif>
It's generally considered poor form to output anything from a function.
--
Adam
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
LEGEND
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169643#M15408
Jul 13, 2008
Jul 13, 2008
Copy link to clipboard
Copied
> alsoways
Nice word, Cameron.
Err: it's probably obvious, but I meant "always".
--
Adam
Nice word, Cameron.
Err: it's probably obvious, but I meant "always".
--
Adam
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
LEGEND
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169644#M15409
Jul 13, 2008
Jul 13, 2008
Copy link to clipboard
Copied
quote:
Originally posted by: Hydrowizard
What do you think of this code? Am I using arguments right? Should I be using argmuents collection instead? Does cfparam become redundant when you use cfargument? Thanks for any advice I'm just trying to understand these last points thanks again
Since you asked:
I would never do this.
form action="corpQuery.cfc?method=getEmp
I would make that page a .cfm page.
Regarding your question,
Does cfparam become redundant when you use cfargument?
yes
The rest of it appears to be much more complicated than necessary.
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
Community Expert
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169645#M15410
Jul 13, 2008
Jul 13, 2008
Copy link to clipboard
Copied
Dan Bracuk wrote:
I would never do this.
form action="corpQuery.cfc?method=getEmp
Adam cameron wrote:
It's generally considered poor form to output anything from a function.
I agree. When you call a method via a URL invocation, as you do, you should set cffunction's returntype to "void" and output to "false". That would compel you to produce code that is more flexible and reusable. For example, whatever you wished the function to output or return could then be logged to a file or saved in a database.
I would never do this.
form action="corpQuery.cfc?method=getEmp
Adam cameron wrote:
It's generally considered poor form to output anything from a function.
I agree. When you call a method via a URL invocation, as you do, you should set cffunction's returntype to "void" and output to "false". That would compel you to produce code that is more flexible and reusable. For example, whatever you wished the function to output or return could then be logged to a file or saved in a database.
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
Hydrowizard
AUTHOR
Participant
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169646#M15411
Jul 14, 2008
Jul 14, 2008
Copy link to clipboard
Copied
Thank you for those replies Adam, BKBK and Dan really great
stuff appreciated.
Adam to clarify on your points:
I would always specify all attributes for <cfcomponent>, <cffunction> and <cfargument> tags
thanks I will use hint, returntype, name etc.
<cfparam name="session.getemp" default="">
I (generally, if it can be avoided ~) would not access external scopes
directly within a CFC method. It breaks encapsulation and makes code less
reusable.
hmm I don't understand- I was setting a default for the session.getemp session so it was set inside, apologies I don't understand that one
<cfif NOT IsStruct(session.getemp)>
<cfset session.getemp = StructNew()></cfif>
Why don't you just param it to a struct in the first place?
OK so like this then:
<cfparam name="session.getemp" default="">
then I can get rid of the isstruct checking-of course the cfparam check to see if it exists and if it doesn't then sets a default value (a session in this case)
<cfargument name="username" required="true">
<cfargument name="email" required="true">
<cfargument name="telephone" required="true">
<cfparam name="arguments.username" default="">
<cfparam name="arguments.email" default="">
<cfparam name="arguments.telephone" default="">
These arguments are flagged as REQUIRED, so the <cfparam> lines are
redundant. The arguments intrinsically need to be passed in, or the
function call would have errored.
True if the arguments values aren't passed in then there is an error thrown, that is why I was using the cfparam to stop any errors if they weren't passed(I suppose making the arguments not required would give the same result as well as setting a default value of ""). Right I get that thank you
<!--- Now do Error Checking --->
<cfparam name="errors" type="string" default="">
You're not VARing this variable.
so it should be <cfset var errors="">
<cfparam name="errors" type="string" default="">
or can I 'combine' the two?
<cfif arguments.username EQ "">
no name</cfif>
It's generally considered poor form to output anything from a function.
I'm sorry you completely lost me on this one!
Adam to clarify on your points:
I would always specify all attributes for <cfcomponent>, <cffunction> and <cfargument> tags
thanks I will use hint, returntype, name etc.
<cfparam name="session.getemp" default="">
I (generally, if it can be avoided ~) would not access external scopes
directly within a CFC method. It breaks encapsulation and makes code less
reusable.
hmm I don't understand- I was setting a default for the session.getemp session so it was set inside, apologies I don't understand that one
<cfif NOT IsStruct(session.getemp)>
<cfset session.getemp = StructNew()></cfif>
Why don't you just param it to a struct in the first place?
OK so like this then:
<cfparam name="session.getemp" default="">
then I can get rid of the isstruct checking-of course the cfparam check to see if it exists and if it doesn't then sets a default value (a session in this case)
<cfargument name="username" required="true">
<cfargument name="email" required="true">
<cfargument name="telephone" required="true">
<cfparam name="arguments.username" default="">
<cfparam name="arguments.email" default="">
<cfparam name="arguments.telephone" default="">
These arguments are flagged as REQUIRED, so the <cfparam> lines are
redundant. The arguments intrinsically need to be passed in, or the
function call would have errored.
True if the arguments values aren't passed in then there is an error thrown, that is why I was using the cfparam to stop any errors if they weren't passed(I suppose making the arguments not required would give the same result as well as setting a default value of ""). Right I get that thank you
<!--- Now do Error Checking --->
<cfparam name="errors" type="string" default="">
You're not VARing this variable.
so it should be <cfset var errors="">
<cfparam name="errors" type="string" default="">
or can I 'combine' the two?
<cfif arguments.username EQ "">
no name</cfif>
It's generally considered poor form to output anything from a function.
I'm sorry you completely lost me on this one!
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
LEGEND
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169647#M15412
Jul 14, 2008
Jul 14, 2008
Copy link to clipboard
Copied
>
<cfparam name="session.getemp" default="">
> I (generally, if it can be avoided ~) would not access external scopes
> directly within a CFC method. It breaks encapsulation and makes code less
> reusable.
> hmm I don't understand- I was setting a default for the session.getemp session
> so it was set inside, apologies I don't understand that one
It's perhaps a good idea if you read up on encapsulation or data hiding.
Or the fundamentals of procedural programming (leaving aside OO principles
to start with).
Your function could well be designed to set defaults for *a user object*,
but where that user object is stored and how should not really be its
business. Where possible a function should do one thing:
- validate a user object;
- put it into session.
That's two things.
What happens down the track when you want to valdiate a user object but
*don't* want to put it into session? It could be part of your process for
creating the user record in the first place, before putting it into the DB.
You don't want to have to write another function which is almost the same,
except for the session bit. Then you've got two bits of code to maintain
if anything changes. This is, obviously, just the tip of the iceberg.
My approach here would be to set a vanilla user object (a struct within the
CFC instance holding the bits and pieces of user data), and *return* that.
Then in your calling code you assign that to the session scope.
Google "getters and setters".
In general, a function should only manipulate data within its own scope
(passed-in arguments and variables local to the function (or the CFC
instance), and then pass back a result based on that manipulation. They
should not manipulate anything from "outside". The session scope is
intrinsically outside.
The exception I'd have to this would be to have a session manager, which is
specifically used to maintain values in the session scope. So that's its
job: managaing the session scope. It won't care about whether it's a user
object or authorisation permissions, or a the state of [something] which
persists for the session; it just manages putting things in, and getting
things out of session.
That said, for any good practice, there's a situation where it's not the
best approach. However I don't think this falls into this category.
Dan's probably rolling his eyes and going "overly complicated", but I think
we differ in opinion as to what's a good level of "complication" (I'd
prefer to say "abstraction"), what's too much, and what's too little ;-)
> <cfif NOT IsStruct(session.getemp)>
> <cfset session.getemp = StructNew()></cfif>
> Why don't you just param it to a struct in the first place?
> OK so like this then:
> <cfparam name="session.getemp" default="">
No. You don't want it to be a string, even an empty one. Param it to a
*struct*:
<cfparam name="session.getemp" default="#structNew()#">
> True if the arguments values aren't passed in then there is an error thrown,
> that is why I was using the cfparam to stop any errors if they weren't passed
The error would be thrown by the code making the function call, so the
params would not get a look-in.
> so it should be <cfset var errors="">
> <cfparam name="errors" type="string" default="">
> or can I 'combine' the two?
Just the VAR statement is fine.
> <cfif arguments.username EQ "">
> no name</cfif>
> It's generally considered poor form to output anything from a function.
>
> I'm sorry you completely lost me on this one!
I mean exactly what I said (ie: I wasn't being oblique). In general, the
code within a function should not output anything. A function should
*return* something, not output it.
I cannot recommend what specific books / web pages to read, but I recommend
you google about the place for coding practices when writing functions.
--
Adam
> I (generally, if it can be avoided ~) would not access external scopes
> directly within a CFC method. It breaks encapsulation and makes code less
> reusable.
> hmm I don't understand- I was setting a default for the session.getemp session
> so it was set inside, apologies I don't understand that one
It's perhaps a good idea if you read up on encapsulation or data hiding.
Or the fundamentals of procedural programming (leaving aside OO principles
to start with).
Your function could well be designed to set defaults for *a user object*,
but where that user object is stored and how should not really be its
business. Where possible a function should do one thing:
- validate a user object;
- put it into session.
That's two things.
What happens down the track when you want to valdiate a user object but
*don't* want to put it into session? It could be part of your process for
creating the user record in the first place, before putting it into the DB.
You don't want to have to write another function which is almost the same,
except for the session bit. Then you've got two bits of code to maintain
if anything changes. This is, obviously, just the tip of the iceberg.
My approach here would be to set a vanilla user object (a struct within the
CFC instance holding the bits and pieces of user data), and *return* that.
Then in your calling code you assign that to the session scope.
Google "getters and setters".
In general, a function should only manipulate data within its own scope
(passed-in arguments and variables local to the function (or the CFC
instance), and then pass back a result based on that manipulation. They
should not manipulate anything from "outside". The session scope is
intrinsically outside.
The exception I'd have to this would be to have a session manager, which is
specifically used to maintain values in the session scope. So that's its
job: managaing the session scope. It won't care about whether it's a user
object or authorisation permissions, or a the state of [something] which
persists for the session; it just manages putting things in, and getting
things out of session.
That said, for any good practice, there's a situation where it's not the
best approach. However I don't think this falls into this category.
Dan's probably rolling his eyes and going "overly complicated", but I think
we differ in opinion as to what's a good level of "complication" (I'd
prefer to say "abstraction"), what's too much, and what's too little ;-)
> <cfif NOT IsStruct(session.getemp)>
> <cfset session.getemp = StructNew()></cfif>
> Why don't you just param it to a struct in the first place?
> OK so like this then:
> <cfparam name="session.getemp" default="">
No. You don't want it to be a string, even an empty one. Param it to a
*struct*:
<cfparam name="session.getemp" default="#structNew()#">
> True if the arguments values aren't passed in then there is an error thrown,
> that is why I was using the cfparam to stop any errors if they weren't passed
The error would be thrown by the code making the function call, so the
params would not get a look-in.
> so it should be <cfset var errors="">
> <cfparam name="errors" type="string" default="">
> or can I 'combine' the two?
Just the VAR statement is fine.
> <cfif arguments.username EQ "">
> no name</cfif>
> It's generally considered poor form to output anything from a function.
>
> I'm sorry you completely lost me on this one!
I mean exactly what I said (ie: I wasn't being oblique). In general, the
code within a function should not output anything. A function should
*return* something, not output it.
I cannot recommend what specific books / web pages to read, but I recommend
you google about the place for coding practices when writing functions.
--
Adam
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
Hydrowizard
AUTHOR
Participant
,
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169648#M15413
Jul 14, 2008
Jul 14, 2008
Copy link to clipboard
Copied
Thanks for those answers Adam really great that has cleared
up a lot and made it a lot more difficult as well! Quite a few
hardcore concepts going on there. I'l get to work thanks
again
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more
LEGEND
,
LATEST
/t5/coldfusion-discussions/what-cfc-best-practices/m-p/169649#M15414
Jul 14, 2008
Jul 14, 2008
Copy link to clipboard
Copied
> Thanks for those answers Adam really great that has
cleared up a lot and made it a lot more difficult as well! Quite a
few hardcore concepts going on there. I'l get to work thanks again
You'll probably find there's a bit move overhead up front, but down the
track things become easier, and you can re-use more of your code.
I also recommend looking at some frameworks, because a lot of the work is
already done for you (and in an "industry standard" sort of way).
I would recommend looking at these:
- Model Glue (or Mach-II, but the last time I looked at it it seemed a bit
primitive)
- Reactor (or Transfer... they're slightly different but cover similar
ground)
- ColdSpring
It might seem daunting stuff, but after a wee play around you'll have a
"click!" moment, and it'll all seem very sensible.
Best of luck :-)
--
Adam
You'll probably find there's a bit move overhead up front, but down the
track things become easier, and you can re-use more of your code.
I also recommend looking at some frameworks, because a lot of the work is
already done for you (and in an "industry standard" sort of way).
I would recommend looking at these:
- Model Glue (or Mach-II, but the last time I looked at it it seemed a bit
primitive)
- Reactor (or Transfer... they're slightly different but cover similar
ground)
- ColdSpring
It might seem daunting stuff, but after a wee play around you'll have a
"click!" moment, and it'll all seem very sensible.
Best of luck :-)
--
Adam
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting.
Learn more

