In the last blog post, we learned many reasons why we wanted DRYer more reusable code in ColdFusion. This blog post will talk about some of the different tools ColdFusion / CFML gives you to achieve that.
- Custom Tags
- User Defined Functions
- CFCs with Functions
- JVM Functionality accessible from CFML
Pros: The CFInclude tag (script function) is a well-known, popular way most of us already use in our code. It is easy to use and can reference relative or full paths, making reusing code very easy.
Cons: Since you include the entire file's contents, it is treated like you copied and pasted the code there. Therefore that code absorbs everything around it, it has access to all the variables (which can be good), but the code cannot explicitly be given inputs. If your include defines a variable, it puts it in the same context, so if you include that file again, it will read the same inputs and create the same outputs.
Pros: CFModule improves on some of the cons of CFInclude by wrapping your code in a little black box so it can only access what you give to it. It can make your code more flexible because you control the inputs. CFModules allow you to break encapsulation and access the caller (parent), and they can reference local or absolute locations for easy sharing.
Cons: CFModule was not well-known, or more accurately, people didn’t like it. It is similar to a custom tag, which has a bad reputation. Since you can access the caller (parent) for access to that parent, it breaks encapsulation. It can also create unintended side effects, which are not favorable in object-oriented programming.
Pros: Custom Tags give you tag syntax to wrap content as you would with regular HTML, which is great for HTML and UI presentation. They can make your code more flexible since you can control the inputs to your code, and the location you call the custom tag doesn’t forcibly leak into the custom tag like it would with a CFInclude. You can access the content you have wrapped inside of your custom tags to treat that content as one of the inputs. Custom Tags do allow you to break encapsulation and access the caller (parent). Engines have central Custom Tag locations (Lucee has multiple locations), including local locations relative to the current page and application.
Cons: Since your custom tag has a beginning and an ending tag to wrap the code, the custom tag file executes twice, which often confuses programmers when first using custom tags. Of course, HTML / XML tags can be self-closing, but that does not stop the CFML engine from calling the custom tag “start” and “end.” Although CustomTags are very powerful and naturally align to HTML / XML perfectly, especially in the UI design, people seem to strongly dislike custom tags, and that hasn’t changed over the years. Also, like CFModules, you access the caller for access to the parent, it breaks encapsulation, and can create unintended or unexpected side effects.
User Defined Functions (UDFs)
Pros: UDFs can make your code much more flexible since you can control the inputs. They are simple to create and include, and you can use them one or many times or have multiple UDFs as needed. If the code is not procedural, you can include your functions inline, at the top or bottom of your code, and the code only runs when you call the function from somewhere else in your code. You can access the calling environment if you need to. Scopes like Application, Request, URL, FORM, etc. are available, although they have their own internal scopes as well. You can write them in the file you are calling them from or an included file in the file you are calling the UDF from, so you can be flexible sharing and reusing with cfinclude, for example.
Cons: You can access the calling environment, it breaks encapsulation, and can create unintended or unexpected side effects. If you include lots of UDFs everywhere, you can bloat your generated byte code, and if every page consists of hundreds of UDFs, it can add up very quickly.
CFCs with Functions
Pros: CFCs with functions make your code much more flexible since you can control the inputs. They are simple to create and include, and you can even have multiple UDFs in a single CFC. The code is not procedural. You can include your CFC inline, at the top or bottom of your code, and the code only runs when you call the function from somewhere else in your code. You can mix one or more CFM files into your CFCs using mixins. You can also extend one CFC from another CFC, allowing you to use Object Oriented Programming techniques. One of the big pros for CFCs is the ability to store data inside the CFC as OOP encapsulation of data, with the functions to perform actions on that internal data. Data does not leak from the page into your function, although the main shared scopes like Application, Request, URL, FORM, etc. are still available. They have their own internal scope as well.
Cons: Creating CFCs inside of other CFCs, or in every site page, can bloat your bytecode or increase your memory use. If you mixin your core CFM UDFs into your CFCs, it will also increase the size of those CFCs. Dependency injection can help centralize your CFCs, reducing this dependency duplication, which helps reduce duplicated code in memory by using references instead of copies.
Pros: ColdFusion gives you the ability to use CFObject tags to create instances of Java Objects, already available in the JVM that ColdFusion runs on top of. Method arguments and return values can be any valid Java type, simple values, arrays, and objects. ColdFusion handles transformation when you pass values into Java Functions and has a series of java interoperability methods for casting values to and from Java. Common java functionality accessed might include environment variables, java arguments, networking, host, date objects, maps, and much more. In the next section, we’ll look at how you could load additional java libraries in addition to the ones included in the JVM’s JDK or JRE.
Cons: Java is a very verbose language, and sometimes it requires jumping through a lot of extra hoops to do something simple. ColdFusion still lacks power features when working with java, like extending a java class or implementing some Interface types. Ask Brad Wood; he’s always trying to get those features added to all the ColdFusion Engines.
Tools to help use the Features more effectively and efficiently
- Dependency Injection
- Externally Sourced Frameworks / Libraries
- CommandBox Endpoint Installation
- Install from Zip
- Install from Git
- Install from ForgeBox
- Install from Maven (Java)
- Full ColdFusion Package Management
Pros: Dependency Injection Libraries, like WireBox, alleviates the need for custom object factories or manual object creation in your ColdFusion (CFML) applications. They provide a standardized approach to object construction and assembling that will make your code easier to adapt to changes, and easier to test, mock and extend. This will eliminate a lot of bytecode bloat, and boilerplate homegrown object creation convention, i.e., manual Dependency Injection.
Externally Sourced Frameworks / Libraries
Pros: Most importantly, when discussing DRY code, using 3rd party extension frameworks and libraries stops you from reinventing the wheel. Learn from others' mistakes and gain from their security and coding practices. Contributions from many people can give you options you haven’t thought about yet. More pros and cons for using External Libraries vs. rolling your own in an upcoming article
CommandBox - Endpoint Installation
For CommandBox to install packages for you, it needs to connect to where packages are stored so it can download them for installation. CommandBox integrates seamlessly with ForgeBox, our community of ColdFusion (CFML) projects, which is the recommended Endpoint. CommandBox also integrates with many other endpoints to use with CFML and Java.
- HTTP(S) - Point to a hosted zip file containing a package
- File - A local file containing a package
- Folder - A local folder containing a package
- Git - Any Git repo containing a package
- LexA Lucee Extension hosted via HTTP that's not contained in a zip file
- S3 - A package zip stored in a private S3 bucket
- CFLib - UDFs posted on CFLib.org
- Gist - A package hosted as a Gist from gist.github.com
- Java - Install OpenJDK for your servers
- Jar - A jar file hosted via HTTP that's not contained in a zip file
Full ColdFusion Package Management for your App
ForgeBox is the only full package management solution for your ColdFusion Applications, accessible from the CLI with CommandBox, and accessible by the browser at ForgeBox.io.
We think package management is great, and we’ll share a blog post on why very soon.
ColdFusion gives you a lot of great features and ways to leverage Code Reuse and there are lots of great tools to help you effectively, efficiently, and easily reuse your code.