I've been exploring different methods of structuring my ColdFusion applications and I'm looking for some opinions on the best way to provide application wide UDFs.
For each of my apps, I generally use a bunch of extra functions that don't really belong in any particular object. Data manipulation stuff mostly.
I want these functions to be available throughout my application, both for use in CFM templates and in Application instantiated CFCs.
The way I see it there are various methods of achieving this, but they all have their own limitations:
Instantiate a base Utils CFC in the Application scope.
This is the method I've used most often. All the functions are available app wide, but if I instantiate the same CFC from multiple applications then they'll each have their own application scope - meaning that each has to instantiate their own base Utils CFC.
There's nothing wrong with this but it feels like I'm not encapsulating the CFC well enough. I'm not keen on referencing the Application scope from within the CFC.
Create an base Utils CFC and make every other CFC extend this.
This works fine, and it means the CFC can reference the Utils functions directly from the CFC's THIS scope - However it means the Utils functions are kept in memory for every CFC.
It also doesn't sit right conceptually as my other CFCs have no relationship with the Utils CFC.
Inject my base Utils CFC into my other CFCs.
Another method I've been playing with is instantiating my base Utils CFC in the Application scope, but then passing that as an object to an argument in my other CFCs.
This works for me conceptually, and for encapsulation. In the same way that I'll set up my datasources in my init method, I can do the same with my UDFs.
This has the same issue that the UDFs are included in each CFC. When I dump all my CFCs I get each UDF multiple times - however as I'm passing an instantiated object, I'm assuming that it's not taking any extra memory space.
If anyone could confirm that, it'd be helpful - I'm just assuming!
The only real problem I have with this method is that it seems a bit convoluted.
Have my Application CFC extend my Utils CFC.
This is what a lot of frameworks seem to do. I've not used this method, but I'm sure there are pros and cons.
CFInclude my UDFs from separate templates, directly in Application.cfc
This is functionally similar to instantiating in the Application scope.
Add my UDFs to the server's Components.cfc
It's a great idea in theory - I can maintain one copy of the base Utils and be sure that everything on the server can access them - However, if I want to run apps across multiple servers then they'll all need those functions. Plus any update to the server may overwrite the components.
It just feels like hacking the core - which I'm sure we can all atest from bitter experience, is bad.
So - my question is this:
What is the best practice for extending CF with UDFs in an elegant and reusable way? Any of the above options or something I've not thought of?
If you are really concerned about structure and keeping things independent, don't even start with singletons or inheritance that extend functionality. Instead extend the base functionality within ColdFusion by appending your non-component library on runtime/request, see ColdFusion Developer's Guide. This doesn't magically solve all problems, but at least that's the proper way to implement general purpose functions.
Related
I'm trying to make a base in-repo addon that provides functionality through namespace like platform/services/whatever.
In addition to that I want if another addon isEnabled() that extends or reopens that same service (in some way) I want it to all be merged together without having to call the second addon's service by name like platform-second/services/whatever
I just want a nice clean abstraction. The reason I'm doing it this way is because based on an ENV variable, I need to build / inject different stuff into index.html and different app.imports.
and I want it to be completely separated into separate little in-repo addons to keep it clean.
I want the app to not need to know the platform but just be able to utilize methods of the general platform addon.
So for example platform.services.whatever.myMethod() might be a noOp by default, but if the second addon extends that and implements that, it'll fire that version instead automatically.
Wonder if I'm making any sense at all LOL
If you have any tips or advice on how one might implement this setup, please let me know.
I currently have the in-repo addons built but ideally I'd have the base platform addon be the one that actually has the app folder contents and the other addons that "extend" or "override" the methods / properties of that addon's objects would just be isEnabled() based on that ENV variable.
I should add that I can't simply do merge tree and override the original file because I need the base functionality of those files.
So if I extend one method of the base platform.services.whatever.myMethod() then I still need the rest of that services methods and properties as well.
So, it's hard for me to be too specific because your question was a bit vague as to the details, but no worries. I'll throw some ideas out and we can hopefully reach some useful conclusions together :)
If you need different objects at runtime, the trick is to register different versions of your service in the dependency injection container depending on configuration (as is common in DI based programming). So have your base service in your addon, and even some concrete implementations that extend the base with different implementations of certain methods. And then, in your app, you have an initializer that looks at the different ENV variables and determines which of the services to inject. You always inject under the same key service:some-service. So, baseClass = Ember.Object.extend() and impl1 = baseClass.extend({methodToOverride: ...} allows you to keep all of the baseClass methods except for the methods you override. So you have successfully avoided the caller having to know whether some parent or child is handling service.someMethod
Now if it's only at build time, then your in node.js land (require() and module.exports. With pojos or es6 you have a number of ways to achieve inheritance (prototype inheritance, $.extend for hierarchically merging pojos, es6 extends)...take your pick. But just from a programming design pattern perspective, it seems like your addon would need to expose a factory that abstracts out the creation of an object that conforms to some interface. So export some module that has a create method that takes in an options object and returns the correct impl.
I'm writing a small Clojure application which has a lot of interaction with a MongoDB database with 2-3 different collections.
I come from a OOP/Ruby/ActiveRecord background where standard practice is to create one class per data model and give each one access to the database. I've started doing the same thing in my clojure project. I have one namespace per "data model" and each has its own database connection and CRUD functions. However, this doesn't feel very functional or clojure-like, and I was wondering if there is a more idiomatic way of doing it, such as having a data or database namespace with functions like get-post, and limiting access to the database to only that namespace.
This seems like it would have the benefit of isolating the database client dependency to just one namespace, and also of separating pure functions from those with side effects.
On the other hand, I would have one more namespace which I would need to reference from many different parts of my application, and having a namespace called "data" just seems odd to me.
Is there a conventional, idiomatic way of doing this in Clojure?
A nice and, arguably, the most idiomatic (scored 'adopt' on the Clojure radar) way to manage state in a Clojure app is that proposed by Stuart Sierra's great Component library. In a nutshell, the philosophy of Component is to store all the stateful resources in a single system map that explicitly defines their mutual relationship, and then to architect your code in such a way that your functions are merely passing the state to each other.
Connection / environment access
One part of your system will be to manage the 'machinery' of your application: start the web server, connect do data stores, retrieve configuration, etc. Put this part in a namespace separate namespace from your business logic (your business logic namespaces should not know about this namespace!). As #superkondukr said, Component is a battle-tested and well-documented way to do this.
The recommended way to communicate the database connection (and other environmental dependencies for that matter) to your business logic is via function arguments, not global Vars. This will make everything more testable, REPL-friendly, and explicit as to who depends on whom.
So your business logic functions will receive the connection as an argument and pass it along to other functions. But where does the connection come from in the first place? The way I do it is to attach it to events/requests when they enter the system. For instance, when you start your HTTP server, you attach the connection to each HTTP request coming in.
Namespace organization:
In an OO language, the conventional support for data is instances of classes representing database entities; in order to provide an idiomatic OO interface, business logic is then defined as methods of these classes. As Eric Normand put it in a recent newsletter, you define your model's 'names' as classes, and 'verbs' as methods.
Because Clojure puts emphasis on plain data structures for conveying information, you don't really have these incentives. You can still organize your namespaces by entity to mimick this, but I actually don't think it's optimal. You should also account for the fact that Clojure namespaces, unlike classes in most OO languages, don't allow for circular references.
My strategy is: organize your namespaces by use case.
For example, imagine your domain model has Users and Posts. You may have a myapp.user namespace for Users CRUD and core business logic; similarly you may have a myapp.post namespace. Maybe in your app the Users can like Posts, in which case you'll manage this in a myapp.like namespace which requires both myapp.user and myapp.posts. Maybe your Users can be friends in your app, which you'll manage in a myapp.friendship namespace. Maybe you have a small backoffice app with data visualization about all this: you may put this in a myapp.aggregations namespace for example.
I heavily rely on CFC. Sometimes within an application, I would have multiple CFC containing dozens of functions per CFC. So over time, it's easy to forget or miss out on already created functions.
So my question is how do you guys manage all these functions? Do you keep a separate document listing all the functions and indexing them that way? Is there an automated feature built in that we can use?
What I've been doing is naming functions more meaningfully but it's very tedious. There has to be a better way to do this. Just looking for your thoughts.
Thank you in advance.
I don't think there's a magic bullet here. Programmers with a bit more OCD than I will likely respond and give you an iron clad solution. For me (or my team) I keep a library of common components in a folder that I reuse for various sites and applications. Then I add them as a /util or /lib folder for a given project and use them (or extend them) as needed. Good planning - good documentation (a Wiki is a great choice for a team) is a must.
Planning carefully whether to extend a CFC is especially important. Otherwise you have to chase down nested function that are part of some super class way down in the weeds (as in, this works, but I really have no idea why it works).
This is where frameworks can provide much needed structure. For common functions and events they generally provide a location and a convention for creating such things. That makes them easy to decipher (as long as you've been indoctrinated into the framework). They have some downsides but they make life a lot easier :)
-You should follow the proper naming conventions for each and every cfcs.
-Each cfcs should be meant for a particular purpose. i.e. login cfcs should should only contain the login related functions.
-All common functions should be kept together in a cfc and that can be extended by the other cfcs.
-You can use a generic cfc for random functions.
Now, if you want to add a new function for any functionality then you can scan only 3 cfcs i.e. dedicated to that functionality, common and random. And you add the new as per the best fit.
I currently have my model and controller cfc's extend a cfc, via a Proxy component, that has all my functions. This makes all those UDF's available everywhere in the app. Are there security or performance risks in doing this? I use my models in an OO fashion. Including these functions like this makes them a part of each object as well. Specifically, could that cause performance issues when creating a lot of objects in a single page request?
I'm using CF 9 and 10 with this framework.
Thanks!
I think this is less a security/performance concern and more a... "ick" concern. ;) CF, especially in 9 and 10, has very fast performance, especially after the first hit. I remember doing some testing with including a 1000 or so UDFs and after the initial hit it was pretty much instantaneous. That being said, just because you can do it doesn't mean you should do it. The Application.cfc is specifically built as a way to manage your Application and how it acts. Your model/service/controller CFCs should not be extending them. The normal rule for extension is "Does A pass the 'Is A' test for B?" and your CFCs definitely are not "Is A" Application.cfc type.
What I'd recommend instead is to create a CFC for your utility functions. Heck, call it util.cfc. Then if your model or other CFCs need these functions, inject them in via a setter (and something like ColdSpring could make this even easier).
I have some common UDFs and CFCs that I'd like to make available to all my controllers. I'm using Model-Glue 3. I've thought of several ways of doing so:
Create a base controller that has <cfinclude>'s to the UDFs and instantiates the CFCs. All other controller inherit from this controller.
Convert all UDFs to CFCs and use ColdSpring.xml to make the CFCs into beans. Then make it available to the controller using the beans attribute in ModelGlue.xml.
Store the UDFs and CFCs in the helpers folder and access them using the helpers scope. However, this looks like it was intended to be used by a view rather than a controller.
Create a global onRequestStart which will instantiate the CFCs and store them in the event object. Then the controllers will access the CFCs by grabbing them directly out of the event object.
My question is, what is the method used by most people to make a common set of UDFs and CFCs available to all controllers?
I would use option 2 above.
For those objects that need the helper methods I would use DI to inject a helper object into them. This will be more flexible going forward.
I do not like the idea of a base object with all of the helpers. Here is why:
What if later you want to break up the helpers in multiple CFCs? You can't. Depending on how many help functions you have and how many it could grow into, this could make your objects ugly. What if you someday have 50 helper functions. Do you really want your controllers having 50 extra methods that really have nothing to do with their primary concern.
Separations of concerns. Controllers should worry about being controllers. They should nto be loaded down with additional functions so that they know how to format strings. That should be handled by a StringHelper or something.
The other two options just don't sound great. What is the Helpers scope?