开发者

What is the equivalent of static methods in ColdFusion?

In C#, I created static methods to help me perform simple operations. For example:

public static class StringHelper
{
    public static string Reverse(string input)
    {
        // reverse string
        return reversedInput;
    }
}

Then in a controller, I would call it by simply using:

StringHelper.Reverse(input);

Now I'm using ColdFusion with Model Glu开发者_Go百科e, and I'd like to do the same thing. However, it seems like there's no concept of static methods in ColdFusion. If I create a CFC like this:

component StringHelper
{
    public string function Reverse(string input)
    {
        // reverse string
        return reversedInput;
    }
}

Can I only call this method by creating an instance of StringHelper in the controller, like this:

component Controller
{
    public void function Reverse()
    {
        var input = event.getValue("input");
        var stringHelper = new StringHelper();
        var reversedString = stringHelper.Reverse(input);
        event.setValue("reversedstring", reversedString);
    }
}

Or is there some place where I can put 'static' CFCs that the framework will create an instance of behind the scenes so I can use it as if it was static, kind of like how the helpers folder works?


Nope, you are correct, there is no concept of static methods in ColdFusion. I think most would solve this problem through the use a singleton utilities in the application scope that are create when the application starts. So in your App.cfc in onApplication start you might have:

<cfset application.StringHelper = createObject("component", "path.to.StringHelper") />

Then when you needed to call it from anywhere you would use:

<cfset reversedString = application.StringHelper.reverse(string) />

Yeah, it's not as clean as static methods. Maybe someday we could have something like them. But right now I think this is as close as you will get.


One way to create statics in ColdFuison is to put the function or variable in the metadata of the object. Its not perfect but like a static you don't have to create an instance of the object to call them and they'll last until the server is restarted so they are quite fast after the first call.

Here's a quick snippet:

component name="Employee"
{
 public Employee function Init(){
  var metadata = getComponentMetaData("Employee"); 

  if(!structKeyExists(metadata,"myStaticVar")){

   lock name="metadata.myStaticVar" timeout="10"{
    metadata.myStaticVar = "Hello Static Variable."; 
   }
  }

  return this;
 }
}

More detail here: http://blog.bittersweetryan.com/2011/02/using-metadata-to-add-static-variables.html.


CFML in year 2021+ supports STATIC methods and STATIC variables because now Adobe has implemented it in ColdFusion 2021 (Lucee supported it since 5.0). Here is a code example of a component named Cube.cfc and a index.cfm file which uses static methods that I used in this other SO thread. I'm adding this information here for completeness.

A CFC component named Cube.cfc

component displayname="Cube" accessors ="true" {
    // class properties
    property name="name" type="string";
    property name="model" type="string";
    property name="borderColor" type="string";
    property name="material" type="string";
    property name="dimension" type="struct";
    
    // set static varibales
    static { 
        private models =[ "model-a",  "model-b", "model-c" ];
        private modelNameMaterialMapping ={
            "model-a": "wood",
            "model-b": "steel",
            "model-c": "silver"
        };
        private modelNameDimensionsMapping ={
            "model-a": {"height": 100, "length": 100, "width": 100 },
            "model-b": {"height": 133, "length": 133, "width": 133 },
            "model-c": {"height": 85, "length": 85, "width": 85 }
        };

    };

 
    public any function init( 
        string name,
        string borderColor,
        string model

    ){
        setName( arguments.name );
        setBorderColor( arguments.borderColor );
        setModel( arguments.model );
        setMaterial(  static.getMaterialByModelName( arguments.model ) );
        setDimension( static.getDimensionByModelName( arguments.model ) );
        return this;
    }

   
    public static string function getMaterialByModelName( string modelName  ){

        return static.modelNameMaterialMapping[ arguments.modelName ];

    }

    public static struct function getDimensionByModelName( string modelName  ){

        return static.modelNameDimensionsMapping[ arguments.modelName ];

    }

    public static string function isValidModel( string model ){

        return static.models.contains( arguments.model );

    }


 }

And a index.cfm file that calls the static methods:

<cfscript>
 
    modelsForChecking=[
        "model-a",
        "model-k",
        "model-c",
        "model-z"
    ];

    // loop through model information without having any object instantiated by calling static functions
    for( model in modelsForChecking){
        if( Cube::isValidModel( model )){
            writeOutput("Cube ""#model#"" is valid.<br>");
            writeOutput( "Cube models ""#model#"" are made of ""#Cube::getMaterialByModelName( model )#"" and a dimension of ""#Cube::getDimensionByModelName( model ).width#x#Cube::getDimensionByModelName( model ).length#x#Cube::getDimensionByModelName( model ).height#""<br>");
        }else{
            writeOutput("Cube ""#model#"" is NOT a valid model.<br>");
        }
    }

    //intantiate a specific cube object with the name "CubeOne";
    writeOutput( "Instantiate an object with the component:<br>");
    CubeOne=new Cube("CubeOne", "white", "model-c" );
    
    // dump properties of the specific cube "CubeOne"
    writeDump( CubeOne );

    // get width with the accesso getter for property dimension for the cube named "CubeOne"
    writeOutput("""CubeOne"" has a width of #CubeOne.getDimension().width# <br>");
  
</cfscript>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜