posted under category: ColdFusion on October 26, 2007 by Nathan
This is one I never thought I'd see, but unfortunately I have seen it a few times.
Think twice when you extend a class/component! In ColdFusion, that would be with the extends attribute of the cfcomponent tag.
When you extend a component, you are saying that that component, the one you are writing the "extends" text into, is a type of the component you are extending.
Ok, let's have an example.
Let's say we have a logging component. We say:
myLoggingService.log(message); and it does it for us. Easy enough.
Also, we have a user component.
User.setName(form.name); User.save();, and it saves it somehow. Basic stuff, easy to grasp.
Now, how do you write a log message after you save a user? There are, of course, dozens of ways to do this.
The way you should NOT, EVER under ANY circumstances do, is say that the user extends the logging service. That doesn't make any sense. Is a user a type of logging device? I certainly don't think so. A user doesn't write logs, a user has a name and probably knows what object to call to persist itself. The logging service writes logs. That logging service needs to be its own separate entity. It just doesn't make sense any other way. You can call it from within the user object, or better yet, from some kind of controller or service layer, but don't integrate it too deeply within an object that it doesn't need to be deeply coupled with.
Oh I know, it's a matter of convenience, you can just say
log(message);. Oh wow, it saved you 17 characters, but you missed the point entirely.
The correct way is to leave the logging service by itself, then call
myLoggingService.log(message). I think it's somewhat a matter of style where you call that from, of course be consistent. The rule is this: Favor composition over inheritance. Your User object can be composed of a logging service (among other things), and you should do this whenever possible.
Now, if you have a database logging service, this is a prime candidate to extend a more generic logging service. Or how about an error logging service? Those are types of logging services. Inherit up from a generic implementation, down to a specific one.