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

CFC best practices

Community Beginner ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

Hello. Please help me out with a little issue I have. I've recently started working with CFC's and there is something that I want to get clear. I have seen two different ways to write CFC's (although I'm sure that there are many others). Let me get to the point. The first method uses an init() function that acts as a constructor.
The second way does not use the init() function. It just has the set and get methods and uses "This" to refer to them. I will attach both code snippets at the end. My question is. What is the best way (if there is any)? Are there advantages to one of the methods? if there is anything I left out that would make my question more clear please let me know. Thank you for your time.

TOPICS
Advanced techniques

Views

1.2K

Translate

Translate

Report

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

Valorous Hero , Feb 28, 2009 Feb 28, 2009
> You've got this <cfscript> block, but you stick the return
> statement outside it. Why not do this:

> variables.attributes.cityId = 0;
> return this;
> </cfscript>
> </cffunction>

My preference is to put return statements outside of cfscript blocks. To me it emphasizes the exit point of a function and I am less likely to overlook it. But technically either option is valid. So I think it is more of a stylistic preference. I am sure some might find the reverse more readable.

> Are there advan...

Votes

Translate

Translate
LEGEND ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

I don't normally do that type of work so I don't write those types of cfc's. Looking at your example, I'd do neither.

I'd use the property scope for the name, id, etc instead of the this scope. The property scope is available to all the functions, but not to the calling template. I would also have a single init function that sets all the values. It would return true, not this.

But then again, it depends on what you intend to do with your object after you have created it.

Votes

Translate

Translate

Report

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 ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

> Hello. Please help me out with a little issue I have. I've recently started
> working with CFC's and there is something that I want to get clear. I have seen
> two different ways to write CFC's (although I'm sure that there are many
> others). Let me get to the point. The first method uses an init() function that
> acts as a constructor.

Good question!


> <cffunction name="init">
> <cfscript>
> variables.attributes = structNew();

One thing you could do with your init() method is to have optional
arguments for each of your object properties here too. This allows the
calling code to init() the object and set some properties in one hit,
rather than having to init() then set().


> variables.attributes.cityId = 0;
> </cfscript>
> <cfreturn this>
> </cffunction>

Here's a question for you. I see a lot of people doing this, and I just
don't get it. You've got this <cfscript> block, but you stick the return
statement outside it. Why not do this:

variables.attributes.cityId = 0;
return this;
</cfscript>
</cffunction>

It's a very trivial thing, but it piques my interest.


> <cffunction access="public" name="getId" returntype="numeric">
> <cfreturn This.id>
> </cffunction>
> </cfcomponent>

I would say with properties exposed in the THIS scope, one would not
necessarily bother with getters. The whole point of THIS-scoped variables
is that they're accessible directly. Using your example code, one would
just do personDTO.id in the calling code.

That said, I would almost never store my object's properties in the THIS
scope, I'd keep them safely locked away in the VARIABLES scope.

--
Adam

Votes

Translate

Translate

Report

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
Valorous Hero ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

> You've got this <cfscript> block, but you stick the return
> statement outside it. Why not do this:

> variables.attributes.cityId = 0;
> return this;
> </cfscript>
> </cffunction>

My preference is to put return statements outside of cfscript blocks. To me it emphasizes the exit point of a function and I am less likely to overlook it. But technically either option is valid. So I think it is more of a stylistic preference. I am sure some might find the reverse more readable.

> Are there advantages to one of the methods?

One difference I see is that option #1 sets default values for each of the components properties (id, name, etcetera). Whereas option #2 does not. So an error might occur if you were to call one of the getX() functions too soon, because the properties are not defined yet inside the component.

<cfscript>
personDTO = createObject("component", "PersonDTO");
id = personDTO.getID();
</cfscript>

That said, I completely agree with Adam's comments about using the THIS scope. I rarely use it either.

Votes

Translate

Translate

Report

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 Beginner ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

Thank you for all your to the point answers. I come from php so "This.id" came more natural to me as it resembled very much "$this->id". I understand now that the variables scope is the way to go for what I'm trying to achieve here. As for the <cfreturn>, I didn't pay much attention to it. I guess, as -==cfSearching==- said, it's a matter of preference. Me, that's the way I found the code in the book that I'm using to learn and it suited me just fine.

Votes

Translate

Translate

Report

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 ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

quote:

Originally posted by: Mihai Baboi
Thank you for all your to the point answers. I come from php so "This.id" came more natural to me as it resembled very much "$this->id". I understand now that the variables scope is the way to go for what I'm trying to achieve here.

Maybe, maybe not. I'll have to try this myself on Monday when I get back to work.

<cfcomponent name="abc">
<cfset x = 2>
<cffunction name="xyx">
<cfreturn true>
</cffunction>
</cfcomponent>

calling template.
<cfset x = 1>
<cfinvoke component="abc" method = "xyz" returnvariable = "def">
<cfdump var="#x#>

If you see 2, you had better reconsider that variables scope.

I don't actually know. I've never tried it.

Votes

Translate

Translate

Report

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
Valorous Hero ,
Feb 28, 2009 Feb 28, 2009

Copy link to clipboard

Copied

> If you see 2, you had better reconsider that variables scope.

No, using the variables scope is fine:

The Variables scope in a CFC is private to the CFC. It includes variables defined in the CFC body (initialization or constructor code) and in the CFC methods. When you set Variables scope variables in the CFC, they cannot be seen by pages that invoke the CFC

Votes

Translate

Translate

Report

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 Beginner ,
Mar 01, 2009 Mar 01, 2009

Copy link to clipboard

Copied

quote:


If you see 2, you had better reconsider that variables scope.

I don't actually know. I've never tried it.



I don't think I'm gonna have this problem. That CFC is going to be used to map the columns of the tables in the database so I'm going to load it from a query. Most of the times I'm going to call the "get" methods from the CFC so I can manipulate and display the data.

The only time I'm going to use the set methods is when I want to update a table. Maybe this kind of approach may seem odd to some of you, but as I said I come from PHP and I like some of the methods there. The objective is to have these DTO's (Data Transfer Objects) that I can use as an interface between the business logic and the database. Here is an example of what I mean by using the set methods for an update:

1. Load the DTO with data from the query ( return a single row by ID )
2. Change only the fields that I'm interested in updating ( personDTO.name = "corrected name" )
3. Call the method that updates the database using the data in the DTO object

Votes

Translate

Translate

Report

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 ,
Mar 01, 2009 Mar 01, 2009

Copy link to clipboard

Copied

> 1. Load the DTO with data from the query ( return a single row by ID )
> 2. Change only the fields that I'm interested in updating ( personDTO.name =
> "corrected name" )
> 3. Call the method that updates the database using the data in the DTO object

Before you reinvent too many wheels, have a look at Reactor
( http://reactorframework.com/) or Transfer( http://www.transfer-orm.com/).

Whilst you're about it, also have a gander at Model-Glue
( http://www.model-glue.com/) and ColdSpring
( http://www.coldspringframework.org/).

A lot of the work you might be setting out to do could already have been
done for you.

--
Adam

Votes

Translate

Translate

Report

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 Beginner ,
Mar 01, 2009 Mar 01, 2009

Copy link to clipboard

Copied

quote:

Originally posted by: Newsgroup User
Before you reinvent too many wheels, have a look at Reactor
( http://reactorframework.com/) or Transfer( http://www.transfer-orm.com/).

Whilst you're about it, also have a gander at Model-Glue
( http://www.model-glue.com/) and ColdSpring
( http://www.coldspringframework.org/).
Adam



I've read about all of these. I was most interested in Transfer and Reactor because I prefer ORM to MVC. I will admit that at the time I only read about them as a curiosity and I didn't dig to much into the documentation. That being said, I will admit that I like working with my own objects, because I can build them to work for my style of coding in stead if writing code to work with the built in objects of a framework. I must also add the fact that right now, I'm not working with ColdFusion, so there's no deadline looming over me. I just started to learn ColdFusion because I like very much. I think it's one of the fastest ways to get from database to browser. So I thought that by making my own objects an a sort of framework I get to dig into it more and learn more stuff. If I start working on a real project I will probably use Transfer or Reactor because the goal is to use a reliable framework that speeds up the development process, not play around with experimental objects.

Votes

Translate

Translate

Report

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 ,
Mar 01, 2009 Mar 01, 2009

Copy link to clipboard

Copied

> I've read about all of these. I was most interested in Transfer and Reactor
> because I prefer ORM to MVC. I will admit that at the time I only read about
> them as a curiosity and I didn't dig to much into the documentation. That being
> said, I will admit that I like working with my own objects, because I can build
> them to work for my style of coding in stead if writing code to work with the
> built in objects of a framework. I must also add the fact that right now, I'm
> not working with ColdFusion, so there's no deadline looming over me. I just
> started to learn ColdFusion because I like very much. I think it's one of the
> fastest ways to get from database to browser. So I thought that by making my
> own objects an a sort of framework I get to dig into it more and learn more
> stuff. If I start working on a real project I will probably use Transfer or
> Reactor because the goal is to use a reliable framework that speeds up the
> development process, not play around with experimental objects.

I think what you say here is almost the model answer to getting up to speed
with CF, and then transitioning into a production environment. I wish
other people (ha: including myself!) had this take on things.

Best of luck with your experimentation, and obviously post up any questions
that crop up.

--
Adam

Votes

Translate

Translate

Report

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 Beginner ,
Mar 01, 2009 Mar 01, 2009

Copy link to clipboard

Copied

LATEST
quote:

Originally posted by: Newsgroup User
Best of luck with your experimentation, and obviously post up any questions
that crop up.

--
Adam



I'm sure I'll be back pretty soon, as there are still a lot of things that I haven't gotten to grips with. Thanks for all your support.

Mihai

Votes

Translate

Translate

Report

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
Documentation