在组件中的 'pseudo constructor' 与 'function init()' 中使用 CFML 代码时
When use CFML code in the 'pseudo constructor' vs 'function init()' in a component
给出例如CFML 中的伪构造函数:
component{
// Pseudo Constructor start
... here comes some cfml scripting code..
// Pseudo Constructor end
function init(){
return this;
}
}
我已经了解.cfc 组件中的伪构造函数:
- 是组件开头和函数init().
之间的cfml代码吗
- 伪构造函数的代码在组件创建时立即运行,甚至在调用实例化构造函数“函数 init()”之前。
- 在伪构造函数中创建的变量也可用于所有其他组件函数(词法作用域)
- 甚至一些组件函数之间的代码也被一些有经验的 cfml 开发人员称为伪构造函数。
请注意,我在这里指的不是 cfproperty
或 property
的使用,而是伪构造函数中的任何其他代码。
不过,我还没有在 CFML 中看到好的示例或用例来帮助我做出决定。任何有经验的 OOP CFML 开发人员能否详细说明一个示例以更好地理解它:
- 何时在伪构造函数中使用代码而不是“函数 init()”?
- 为什么不使用实例化构造函数“function init()”中的代码,这样变量就可以accessed/referenced在任何其他变量中使用“this”关键字组件功能?
请给出一个示例代码,这样可以帮助我和其他人决定将来何时使用一个而不是另一个?
在更深入地调查之后,我得出了自己的结论,我想与所有感兴趣的 CFML 开发人员分享。如果任何有经验的 OOP CFML 开发人员有更准确的信息,我会很高兴知道。
我创建了一个名为 Cube.cfc 的组件,它可以自己回答这个问题。我的结论基本上是“伪构造函数”允许创建某种“静态”函数,因为这些函数可以在不实例化对象的情况下使用这些变量。请注意,我不想使用术语“静态”,因为这些函数缺少命名属性“静态”(据我所知,目前只有 Lucee 支持真正的“静态”函数)。此外,我展示的示例似乎只适用于 createObject() 而不是隐式构造函数,例如new Component(),因为new Component()会立即实例化对象。但是:使用 createObject 和伪构造函数至少可以模仿静态函数。请注意,我的示例组件只是描述性的。
在下面的示例中,我将使用不需要任何对象实例化的可用函数。这些函数可用于检索一些未绑定到任何 created/instantiated 对象的有用信息。
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";
// pseudo constructor
variables.models =[
"model-a",
"model-b",
"model-c"
];
variables.modelNameMaterialMapping ={
"model-a": "wood",
"model-b": "steel",
"model-c": "silver"
};
variables.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( getMaterialByModelName( arguments.model ) );
setDimension( getDimensionByModelName( arguments.model ) );
return this;
}
//this function won't need any instantiating of an object because it uses variables of the pseudo constructor
public string function getMaterialByModelName( string modelName ){
return modelNameMaterialMapping[ arguments.modelName ];
}
//this function won't need any instantiating of an object because it uses variables of the pseudo constructor
public struct function getDimensionByModelName( string modelName ){
return modelNameDimensionsMapping[ arguments.modelName ];
}
//this function won't need any instantiating of an object
public string function isValidModel( string model ){
return variables.models.contains( arguments.model );
}
}
index.cfm:
<cfscript>
CubeService = CreateObject("component","Cube");
writeDump( CubeService );
writeDump( GetMetaData( CubeService ) );
modelsForChecking=[
"model-a",
"model-k",
"model-c",
"model-z"
];
// loop through model information without having any object instantiated
for( model in modelsForChecking){
if( CubeService.isValidModel( model )){
writeOutput("Cube ""#model#"" is valid.<br>");
writeOutput( "Cube models ""#model#"" are made of ""#CubeService.getMaterialByModelName( model )#"" and a dimension of ""#CubeService.getDimensionByModelName( model ).width#x#CubeService.getDimensionByModelName( model ).length#x#CubeService.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=CubeService.init("CubeOne", "white", "model-c" );
// dump properties of the specific cube "CubeOne"
writeDump( CubeOne );
// get width with the accessor getter for property "dimension" for the cube named "CubeOne"
writeOutput("""CubeOne"" has a width of #CubeOne.getDimension().width# <br>");
</cfscript>
如果你 运行 以上文件你会注意到函数:
- getMaterialByModelName( "model-a" ),
- getDimensionByModelName( "模型-b"),
- isValidModel(“模型-z”)
不需要任何实例化对象。他们只是在没有 运行 任何 init() 函数的情况下检索有关立方体模型的一些有用信息。
这让我假设以下经验法则:
在“init()”函数中使用绑定到 属性 实例化对象的变量。
在使用 init() 函数之前,只要您需要使用带有这些变量的函数,就使用 'Pseudo Constructor' 中的变量。
请注意,我的组件只是一个描述性示例。如果有人提供有关该主题的更详细信息,或者我的假设需要更正,我很乐意知道。
重要更新:正如 @SOS 所幸评论的那样,Adobe Coldfusion 自 Coldfusion 2021 起支持静态函数。这些“非实例化对象” -related”函数现在可以直接使用 Component::staticFunctionName( args )
调用,无需使用任何前置 CreateObject()
或隐式构造函数 new Component()
!正如@SOS 还评论的那样,在 CFML 中看起来“使用静态可能是 2021+ 的最佳方法”,因为现在 CFML 引擎 Lucee 和 Coldfusion 都完全支持它们。
为了完整起见,我放置了示例代码的 adapted/rewritten 版本作为 2021+ 的参考:
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 );
}
}
index.cfm
<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>
如需进一步参考,请参阅:
Static functions for CFC in Lucee
给出例如CFML 中的伪构造函数:
component{
// Pseudo Constructor start
... here comes some cfml scripting code..
// Pseudo Constructor end
function init(){
return this;
}
}
我已经了解.cfc 组件中的伪构造函数:
- 是组件开头和函数init(). 之间的cfml代码吗
- 伪构造函数的代码在组件创建时立即运行,甚至在调用实例化构造函数“函数 init()”之前。
- 在伪构造函数中创建的变量也可用于所有其他组件函数(词法作用域)
- 甚至一些组件函数之间的代码也被一些有经验的 cfml 开发人员称为伪构造函数。
请注意,我在这里指的不是 cfproperty
或 property
的使用,而是伪构造函数中的任何其他代码。
不过,我还没有在 CFML 中看到好的示例或用例来帮助我做出决定。任何有经验的 OOP CFML 开发人员能否详细说明一个示例以更好地理解它:
- 何时在伪构造函数中使用代码而不是“函数 init()”?
- 为什么不使用实例化构造函数“function init()”中的代码,这样变量就可以accessed/referenced在任何其他变量中使用“this”关键字组件功能?
请给出一个示例代码,这样可以帮助我和其他人决定将来何时使用一个而不是另一个?
在更深入地调查之后,我得出了自己的结论,我想与所有感兴趣的 CFML 开发人员分享。如果任何有经验的 OOP CFML 开发人员有更准确的信息,我会很高兴知道。
我创建了一个名为 Cube.cfc 的组件,它可以自己回答这个问题。我的结论基本上是“伪构造函数”允许创建某种“静态”函数,因为这些函数可以在不实例化对象的情况下使用这些变量。请注意,我不想使用术语“静态”,因为这些函数缺少命名属性“静态”(据我所知,目前只有 Lucee 支持真正的“静态”函数)。此外,我展示的示例似乎只适用于 createObject() 而不是隐式构造函数,例如new Component(),因为new Component()会立即实例化对象。但是:使用 createObject 和伪构造函数至少可以模仿静态函数。请注意,我的示例组件只是描述性的。
在下面的示例中,我将使用不需要任何对象实例化的可用函数。这些函数可用于检索一些未绑定到任何 created/instantiated 对象的有用信息。
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";
// pseudo constructor
variables.models =[
"model-a",
"model-b",
"model-c"
];
variables.modelNameMaterialMapping ={
"model-a": "wood",
"model-b": "steel",
"model-c": "silver"
};
variables.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( getMaterialByModelName( arguments.model ) );
setDimension( getDimensionByModelName( arguments.model ) );
return this;
}
//this function won't need any instantiating of an object because it uses variables of the pseudo constructor
public string function getMaterialByModelName( string modelName ){
return modelNameMaterialMapping[ arguments.modelName ];
}
//this function won't need any instantiating of an object because it uses variables of the pseudo constructor
public struct function getDimensionByModelName( string modelName ){
return modelNameDimensionsMapping[ arguments.modelName ];
}
//this function won't need any instantiating of an object
public string function isValidModel( string model ){
return variables.models.contains( arguments.model );
}
}
index.cfm:
<cfscript>
CubeService = CreateObject("component","Cube");
writeDump( CubeService );
writeDump( GetMetaData( CubeService ) );
modelsForChecking=[
"model-a",
"model-k",
"model-c",
"model-z"
];
// loop through model information without having any object instantiated
for( model in modelsForChecking){
if( CubeService.isValidModel( model )){
writeOutput("Cube ""#model#"" is valid.<br>");
writeOutput( "Cube models ""#model#"" are made of ""#CubeService.getMaterialByModelName( model )#"" and a dimension of ""#CubeService.getDimensionByModelName( model ).width#x#CubeService.getDimensionByModelName( model ).length#x#CubeService.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=CubeService.init("CubeOne", "white", "model-c" );
// dump properties of the specific cube "CubeOne"
writeDump( CubeOne );
// get width with the accessor getter for property "dimension" for the cube named "CubeOne"
writeOutput("""CubeOne"" has a width of #CubeOne.getDimension().width# <br>");
</cfscript>
如果你 运行 以上文件你会注意到函数:
- getMaterialByModelName( "model-a" ),
- getDimensionByModelName( "模型-b"),
- isValidModel(“模型-z”)
不需要任何实例化对象。他们只是在没有 运行 任何 init() 函数的情况下检索有关立方体模型的一些有用信息。
这让我假设以下经验法则:
在“init()”函数中使用绑定到 属性 实例化对象的变量。
在使用 init() 函数之前,只要您需要使用带有这些变量的函数,就使用 'Pseudo Constructor' 中的变量。
请注意,我的组件只是一个描述性示例。如果有人提供有关该主题的更详细信息,或者我的假设需要更正,我很乐意知道。
重要更新:正如 @SOS 所幸评论的那样,Adobe Coldfusion 自 Coldfusion 2021 起支持静态函数。这些“非实例化对象” -related”函数现在可以直接使用 Component::staticFunctionName( args )
调用,无需使用任何前置 CreateObject()
或隐式构造函数 new Component()
!正如@SOS 还评论的那样,在 CFML 中看起来“使用静态可能是 2021+ 的最佳方法”,因为现在 CFML 引擎 Lucee 和 Coldfusion 都完全支持它们。
为了完整起见,我放置了示例代码的 adapted/rewritten 版本作为 2021+ 的参考:
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 );
}
}
index.cfm
<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>
如需进一步参考,请参阅:
Static functions for CFC in Lucee