By Peter Bell

Inheritance without extends: a practical use case for class based mixins

I find when developing a software product line that I need some way to pull together base methods, generated methods, custom (reusable) methods and project specific custom methods. While an extension tree works (CustomUserDAO extends GeneratedUserDAO extends BaseDAO), if I want to have different base methods for different projects (either different versions – kind of like an abstract method factory, or a different set of capabilities so I only add the base methods that my other methods depend on), sometimes I want a more flexible approach.

[More]

The Benefits of XML Config Files (and why I don't use them)

XML configuration files are almost always the smartest way to handle configuration information. I’m about to do (and post) some stuff that DOESN'T use them and rather than waiting for everyone to tell me all of the benefits I’m missing, I thought I'd post them upfront (feel free to add any benefits I’ve missed) so it is understood that this was a choice, not an accident. Maybe a bad choice . . . :->

[More]

An Evenings Craziness

So, I don’t love XML for config files (I know all the reasons they make sense, but a guy can have a preference, can't he?!), and I like my transient objects to know about their services, but I do like the idea of all of my configuration information in a single file, I need a good factory, and Dependency Injection sounds cool.

What’s a guy to do?

Well, I though it might be nice to prototype a very basic DI factory which is capable of lazy loading, is lightweight enough to use for all of your objects and which uses an included config file for people who swing that way. I wrote this in under three hours and it depends on a base class. It isn’t pretty, but I thought it was kinda fun. The code is up and running on a test project so it works.

[More]

OO and the DB – Approaches to ORMs

In an ideal world, all of our objects would just exist. No databases, no joins, no discussions over table inheritance. We’d just go to an object and the data we want would be there.

This is not an ideal world.

There is no such thing as the perfect ORM as database access is one of the tasks that has the greatest impact on application performance (this is more than just premature optimization) and every application wants different information in a different way. I want to look in this posting at some broad approaches to retrieving relational data for an OO application and some of the implications of each.

[More]

A Sample Newsletter Application

I still have to post about handling validations, transformations and value lists, but for now I think it is time to write (and post) some code to see how this works, so tomorrow morning I’m going to start to work up a simple newsletter application, reworking all of the objects to see how the new interfaces work out.

I’ll just start with a simple system comprised of User, Newsletter, List and EmailMessage objects, together with a UsertoNewsletter joining table. User will have UserID, FirstName, LastName, EmailAddress, Unsubscribed and Lists. Newsletter will have NewsletterID, Subject, From, PublishedAt, Status, HTML and Text. List will have ListID, Title and ShortDescription. EmailMessage will have To, From, Subject, HTML, Text, UserEmail, UserID, NewsletterID, SentAt and Status.

Screens: List, view, add, edit and delete for User, Newsletter and List along with Publish and Test screens for the newsletter. Not much of a newsletter system, but hopefully just enough of an application to test out the core features of the new interface. I may also throw in a page based content management system as well just to round out the simple test case.

Interfaces: Improving the Iterating Business Object

I’ve had quite a wild ride with the Iterating Business Object. I have no doubt that there are projects I would not have been able to complete nearly as fast as I did without this pattern, and I’ve ended up with some really maintainable code, but in the rush to get projects out the door I now have a pretty bloated base IBO that needs some serious refactoring.

[More]

Interfaces: Doing the DAO

The core DAO interfaces are pretty similar the to CRUD service interfaces: getbyUniqueAttribute(), getbyFilter(), deletebyUniqueAttribute(), deletebyFilter() and save(). The biggest difference is that the get methods should return a recordset rather than an IBO.

Often there is the question as to where save() should be broken out into insert() and update(). Most commonly, you insert if the Object.ID is 0 and update if it is not, but sometimes it is nice for a DAO to be able to test an object for uniqueness in some other manner (email address or first name, last name and address1) and to follow certain business rules depending upon whether the uniqueness test is passed (check out Steve Bryants seriously underused DataMgr for an example of this).

All things considered, I’m going to delegate the decision of whether to insert or update down to the DAO and it can decide whether to call its private Insert() or Update() method for each record to be saved.

There would be a real argument to adding a validate method to the DAO that would specifically validate the passed data against the db introspected metadata to make sure you’re not trying to save a float in an int or 100 characters in a varchar(15). For now, I’m not going to implement that as it is doing at runtime what could quite easily be done at generation time by writing a tool to ensure that every custom data type is validated in a manner that is consistent with its underlying persistence requirements.

Interfaces: Starting with the Service

So, what methods does a base service need to support? Lets start with taking care of CRUD (Create Read Update and Delete).

Getting Data I want my service layer to be able to return an iterating business object loaded with 0..n records depending on my requirements. I’ve spent a LOT of time thinking about this and I like the idea of getbyUniqueAttribute () and getbyFilter() as being the two main methods for requesting a loaded IBO. I may add An additional getReport() method to handle reporting where there needs to be a much richer set of grouping and aggregation, and (if possible) a getStoredProcedure() to handle n-parameter calls to stored procedures (might require a little bit of runtime generation), but these two methods have a lot of flexibility for most use cases.

With getbyUniqueAttribute(AttributeName required,AttributeValueList required,AttributeNameList optional), all we need to provide is the Attribute Name and the comma delimited list of 0..n Attribute Values. By definition, the filter is the objects which match the attribute values passed in and the order is the order in which the attribute values were provided (I get that there could be a use case for getting a list of products based on an ID list and then ordering by price but I’d handle that edge case using my IBO order method which I’ll describe later tonight). I also allow for an attribute name list where you want to load only a subset of the properties for a given object.

With getbyFilter(Filter optional, Order optional, AttributeNameList optional, Page optional, RecordsPerPage, optional), you can specify the filter, order, attribute name list, and optionally the page and number of records per page.

If anyone is wondering why there isn’t a get(), getAll() or getList() . . .

In my opinion, get() isn’t sufficiently meaningful for a service method query as I have no idea what kind of get it supports. getAll() can be implemented in this API using getByFilter() with no value for the filter clause and I don’t use getAll() very often. I may add it if this becomes an issue.

As for getList(), I’m personally (and it is mainly a personal preference) not a big fan of this naming as while it is extremely common (which makes it good because it is expected and understood). I could never justify using getList() for filters when I might well get back a list using a comma delimited list of attribute values as well. This was probably driven by the fact that I do a lot of admin systems where you can pick 7 products to edit or 4 users to approve so I often have a comma delimited list of email addresses, user ID’s, product skus or product ID’s that I have to return using an IN clause. I always saw that as closer in nature to a getbyAttribute() than a getByFilter(), and if my getbyAttribute() could return a list, I couldn’t very well call my getbyFilter() “getList()”!

Just to further clarify, the reason I don’t have a separate getbyAttribute() and getbyAttributeList() (where the first expects a single value and the second supports 1..n values) is that if someone does select one of n options on an admin screen I want to encapsulate the process of determining whether to use an EQUALS or an IN clause. I don’t want to have to keep writing “if ListLen(AtrributeValueList) GT 1 call x else call y” all over the place.

The fact that my API is non-standard is a distinct weakness, but I feel the benefits derived from the clarify of the naming are worth the trouble of having to explain them (at least to me :->).

Of course, we haven’t talked about ORM gets. That is because I’m going to add some very simple relationship methods in tomorrow.

Save I like the idea of a single save() method handling both inserts and updates. Just pass in the appropriate iterating business object and the save method runs any transformations and validations before saving the data if it is valid. This needs to return error information and/or status, but that is a whole other post!

Delete I see deletes as extremely analogous to gets. You could want to delete product 17, users 3, 4 and 6 or all shopping baskets more than 2 weeks old. So I use deletebyUniqueAttribute(AttributeName required,AttributeValueList required) and deletebyFilter(Filter).

It’s All About the Interface

The most important part of any application are its internal and external interfaces. They almost completely determine the elegance, flexibility and maintainability of the system. It is also much easier to refactor code before you write it as you don't have to worry about syntax errors!

As always wanting to keep at least one chapter ahead of my work(*grin*), I’m now finishing up Ken Pugh's great book on Interface Oriented Design (what can I say – I must be going through my Pugh phase . . .). It certainly wasn't the first book on designing to interfaces and it isn't the last word on the subject, but I’m still finding that it raises some nice subtleties and heuristics which are worthy of consideration.

I'll be posting some of those concepts and then I'll start to work up an improved set of interfaces for my base classes. And then soem code - I promise - code tonight or in the morning!

Abstract Data Types: The Future of Scaffolding

Scaffolding is a great way to take a lot of the tedium out of coding applications, but database metadata based scaffolding is usually too naive to be of much use (providing a prototype rather than generating production ready code). The addition of richer metadata allows you to generate scaffolding that doesn’t need to be rebuilt, allowing you to generate huge swathes of your applications. One of the easiest ways to implement this is using Abstract Data Types.

I have seen the concept of abstract data types used to mean a number of different things. I’m using it (as Ken Pugh does in his excellent book Prefactoring) to describe the ability for a programmer to assign attributes and methods to rich custom data types like "phone number" and "social security number" (attributes and methods – see why I sometimes wish that everything was an object?!).

[More]

More Entries

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