Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

What cfc best practices

Participant ,
Jul 13, 2008 Jul 13, 2008
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
632
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 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
...
Translate
LEGEND ,
Jul 13, 2008 Jul 13, 2008
> 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
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 13, 2008 Jul 13, 2008
> alsoways

Nice word, Cameron.

Err: it's probably obvious, but I meant "always".

--
Adam
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 13, 2008 Jul 13, 2008
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.
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 13, 2008 Jul 13, 2008
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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 14, 2008 Jul 14, 2008
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!
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
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
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
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 14, 2008 Jul 14, 2008
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
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 14, 2008 Jul 14, 2008
LATEST
> 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
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources