By Peter Bell

Playing with Stub Pages

The idea of a stub page is a simple file that sets some page specific properties before then including a front controller style index.cfm. So, if you go to about-us/history.html (with ColdFusion enabled to process .html files) the stub file might look something like:

<cfscript>
   Page.Title = "History";
   Page.Name = "history";
   Page.SectionName="About Us";
   Page.SectionName="about-us";
   Page.FilePath = "about-us/history";
   Page.Feature = "PageDisplay";
   etc. . . .
<cfscript>
<cfinclude template="/index.cfm">

Originally, page stubs were just a way to avoid problems I was having getting URL rewriting to work on IIS back in 2001/2002, but now as I revisit them, I see them as a potentially interesting way of decoupling the process of generating URLs from the process of consuming them . . .

[More]

Where Should the Metadata Go?

The key to LightBase is dynamic programming based on rich metadata to give you much more than just simple scaffolding for your business objects, but that raises the question "where should the metadata go?" . . .

[More]

Proof of Concept - Component based rendering

I love the idea of using cfc's to abstract the calculations from templates while still using cfincludes for the pure templating.

Here is an *extremely* rough proof of concept that I whipped up in about an hour. Will be playing with this tomorrow, but any thoughts much appreciated . . .

[More]

Generating 80% of your applications: Step 1 - Implementing Custom Data Types in ColdFusion

I love the idea of scaffolding. The more routine work that the computer can do for me (especially in terms of CRUD), the better. But the biggest complaint most people have who have used scaffolding is that they usually have to replace it for production because the code is too naive.

If you look at most of the reasons you have to replace scaffolding it is simply because you know that a field is a phone number or an age rather than a string or a date time (which is all the database knows) and you typically want to apply more specialized form fields, display rules, transformations and validations. The solution is to improve scaffolding with Django style custom data types rather than Ruby on Rails style database metadata.

So, why not have a system that just allows you to describe custom data types in terms of their form fields, display rules, transformations and validations and then simply define all of your object properties using those custom data types? That is exactly what I have been doing for the last few years in my application generator, and I’m currently in the process of trying to upgrade the way this works to make it a little more OO.

[More]

Why write methods when you can just describe them?!

One of my goals with the base classes I’m working up is to make much more of my programming declaritive so I can more easily store the metadata to describe my programs in a database which will in turn make it easier to generate a higher proportion of my applications.

For example UserService.getbyEmail() is really just a special case of BaseService.getByUniqueAttribute() which can be fully described by a small amount of metadata. Same goes for a lot of the common methods we write (especially the CRUD methods including most transformations and validations).

While I’m prototyping this I thought it might be cool to write a “generic method” allowing you to call different methods which are described declaratively in the configuration files for your objects so instead of having to write a bunch of methods you can just set the metadata and it will automatically provide you with the methods at runtime. Obviously this is just for declaritive methods using base methods – there would be no benefit in this approach for “real” methods with actual business logic or other programming constructs within them.

I just wanted to prototype this up quickly, so I’ve just added a base “call()” method so you can call(MethodName,ArgumentCollection). If the method name exists in the object (if StructKeyExists), it runs it, if it exists in the metadata it uses the metadata to call the appropriate base method with the appropriate parameterizations, and if the method doesn’t exist, it flags the (fatal) error condition by setting an error variable, dumping it and aborting.

This is not a great implementation. The “call()” syntax is non-standard and non-ideal, but it allows me to play with the approach of handling and creating methods dynamically and if I like this approach (I will probably end up deciding to generate methods instead) I can always to look at what language features CF provides for doing this “properly” and to see if there is a way of dynamically specifying functions at runtime (other than using a concatenation or template to generate, publish and include scripts which is seems to be a rather crude way of having to go!).

Improving the Iterating Business Object

So, I’ve been living with the Iterating Business Object (IBO) for a while now and it seems to be working out really well. It allows me to abstract access to recordsets with support for information hiding through the gettableAttributeList and SettableAttributeList, generic getters and setters that honor the information hiding and that automatically include any custom getters or setters that exist.

However, in throwing together some projects ASAP I ended up putting a bunch of things into my IBOs that I knew belonged elsewhere. I have no problem with the IBO handling transformation and validation of fields (via composition), but the IBO is fundamentally part of the model. My BaseIBO, BaseDAO and BaseService between them comprise a pretty good starting point for replacing a lot of model methods with simple declaritive code. So when I started dropping in DisplayField() and DisplayValue() both of which were HTML aware I knew that it would be time for a refactoring shortly.

I started by revisiting all of the IBO methods, adding some additional functionality which I needed for finding, ordering and paging and then broke out the view methods into a BaseHTMLIBO view helper which automatically decorates IBOs in the view. I could have just mixed in the additional methods, but I’d never used a decorator and (more importantly) I felt that by using a decorator I would more accurately be “describing” my intent in the code.

Later today I’ll post on the new IBO interface and why I made the choices that I did. Then expect a series of posts on the latest BaseService and BaseDAO components. I’ll release code over the next few days.

Objects or Services - how do you design your model?

In this post I look at service mania, overreaching objects, why the real world sucks and what the smart kids are doing!!!

[More]

How do YOU Handle Errors in your beans and model?

I have a Product IBO (lets call it a bean for the purposes of this discussion). I have loaded it with unverified values from the form scope (which I don't want to error - I want to be able to put a text string into a date field without CF falling over - one of the reasons I like dynamic typing).

Now I am ready to validate the input and save the product. Lets use an AR style Product.Save() which (for me) orchestrates transformations, validations and (if valid) the save. How do you report on the validity of the data?

Do you keep it in the bean with an if Product.IsValid() Product.Save() or do you do an Error = Product.Validate() - if NOT Error Product.save()?

I'm guessing I know what most people do with the above case (although I'll be interested in feedback), but what about other kinds of errors? Lets say you have a db connection error - how does that get reported? Do you have a Product.saved() which confirms whether the save worked? Do you do a Error = Product.Save() and explicitly return an error object?

Any ideas appreciated as I'm trying to refine my rather ropy error handling within the model.

Also, does anyone pass around an Error object or even an ErrorStack object for catching the n-errors that could bubble up. If so, what kind of methods and/or properties does it have?

Any advice, experience or wild asses guesses much appreciated!

Application Generation: Orchestrating the Process

If you store metadata about your applications in the same way that you store data about pages or users or products, then an Application is just another business object making it easy to list, add, edit and delete entire applications in the same way as you list, add, edit and delete articles or product categories (see why I like putting my metadata into a database?!).

[More]

Extends Still Easier

So, I played around with dynamically mixing in all of my methods at runtime using class based mixins instead of extending from base classes.

An interesting experiment, but not worth the trouble. The problem is that you lose the Super.[methodname]() capability to overload a base class (or custom class) and then still call the super method.

There is a fairly easy solution which is you look for any overloaded methods and rename them dynamically as Base[MethodName] or Generated[MethodName], but now your code is dependent on a very non-standard convention. It is easier just to generate the base, generated and custom class files and to have them extending each other. Main thing to remember is that you have to generate the class files rather than copying them as the extends property must be static so your class files are dependent on your application mapping (e.g. extends="myapp.com.base.BaseDAO" - when you post to myapp2, you need to regenerate the class file with an extends="myapp2.com.base.BaseDAO" - you can't just variabilize it at runtime with "extends="#application.name#.com.base.baseDAO").

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.005.