Archive for May, 2009

Having Your Cake And $this->Cake->Eat()ing It

Saturday, May 30th, 2009

Well I said I would start blogging again, and – erm – that went well.
The main reason is I was struggling to find any sort of focus for my blog-rays. So I thought I’ll stick to what I do best – whinging about my geekly pursuits.

To that end, I want to talk a bit about CakePHP, which I’ve been getting to grips with over the last week or so – and share some thoughts on that, MVC, and design patterns in general.

Now, I’m a programmer who has always been subconciously searching for a way to code in an elegant and consistent way. When I first immersed myself in OO design, I fell in love with the idea that I finally had a vocabulary to talk about the structure of what I was working on. Of course, good OO design is a completely self-disciplined art, and so especially in my early days there was always a lingering assumption that I must be missing out on the secrets of glorious poetic code.

The other problem was, despite being quite comfortable with scope, inheritance, polymorphism, encapsulation and enumeration, this is all quite abstract until you really hit a substantial project and then suddenly the two-tier examples of inheritance I’d been dealing with seemed so completely irrelevantly simplistic.

The problems I thought object orientation solved really only threw more variables into the mix, and I had never actually considered design patterns at all until I read The Pragmatic Programmer, when I was finally confronted with some principles that for the first time inspired my future software design.

The over-arching principle of The Pragmatic Programmer was Don’t Repeat Yourself, and although the book fleetingly refers to the Model View Controller paradigm by name, it is essentially a prolonged testament to the idea that we have our data held in one place, and we can represent that data in a lot of different views. We change the model, we barely have to touch our views. Awesome.

Without thinking in strict MVC terms, I had actually started applying a vague manifestation of this to the next big project I undertook – Sky NewsScape – which is still under development under my combustion studios name. NewsScape is basically a visual representation of various types of news content which co-exist in a 3D environment. For all the content management, its class design is quite simple. We have three base classes:

NewsContent: An individual piece of content, such as a ‘Story’ or ‘Currency’, which all inherit this base.
NewsContentRenderer: The properties which define how different types of content are visually represented in the environment. For example, while a ‘Story’ has properties like ‘Headline’, ‘Description’ and ‘Source’ – a StoryRenderer is bound to a Story and contains position and scale vectors for the texture which will be in the environment etc.
NewsContentManager: Handles the downloading of individual NewsContent objects. For example, there is a TopStories NCM which downloads and parses XML feeds to generate a collection of Story objects.

Although it doesn’t fit squarely into the MVC conventions, as you can see, we essentially have a Model in our NewsContent type, which is solely concerned with the representation of the data itself, a Controller in our NewsContentManager which handles all the logic for building objects and setting properties, and a View in our NewsContentRenderers, which define all the properties for how to show that data on screen. It gets a little more complex in reality, as there is a fourth base class I haven’t touched on – Experience – which as the name suggests is an individual bit of the ’show’ – so we have Experiences for showing a breaking news story, for showing animated currency market boards etc.

Now, this paradigm is working really nicely for NewsScape. I’m sure if I presented it to any expert on software design, they’d swiftly inform me of how it ‘breaks MVC’, but seeing as I never actually intended it to be MVC, I’ll avoid being too offended there :P

It’s at this point I’m going to grate a bit, and whinge about MVC. I was really happy to learn about the principles, chew over them, agree with the underlying objectives that we want to abstract our presentation from our underlying data (for example, after Sky NewsScape is done, I’m planning to take the underlying codebase and use it to create similar experiences for completely different brands and content types, and because of the class design I plumped for most of the work I’ll actually be doing is essentially reskinning).

However, I’ve just started working on a web app (the specifics of which I’ll be rambling about when it’s a bit closer to being finished). I decided to try out CakePHP as my framework of choice, and although I hadn’t worked with MVC by name before, I was attracted to the idea of applying similar principles that I had done with NewsScape. Now, I’ve only been working with Cake for a couple of weeks, and I’m rather chuffed that I’ve managed to get a working site up and running so quickly. Its abstraction of the underlying SQL is *very* elegant, and the effortless way it manages relationships where MySQL failed me is very lovely. My main gripe however is the way it clings to MVC one minute, then arbitrarily decides to chuck it out, because it’s having to grudingly accept that you can’t enforce design patterns from the top down. Going back to my twisted form of MVC – I took the principles which I was attracted to, and applied it in a way that achieved all the aims I wanted to. Would having NewsContentRenderers and Experiences both as a sort of View, but neither in themselves actually a whole view, or a co-dependent part of a view, break MVC? Quite possibly…but I don’t care, because it doesn’t need to. The whole design grew up quite organically. I was never thinking in terms of MVC, but rather acknowledging that I had content, I had a means of downloading content, and a means of showing that content – and the rest grew from there.

Back to CakePHP, and once I got to grips with it all, I was quite happy with the MVC way of having a model per table, controller per model, view per action for controllers etc. and building up the general structure of the site was going nicely. That is, until I encountered elements. I knew that every page would have a login panel at the top of the screen (the usual fare of letting users login if they’re not already, and if they are logged in, showing common actions etc.) Although all this should, I’d have assumed, be the responsibility of my User model/controller, because I’m including it as an element everywhere it becomes this floating detached bit of code filled with ugly calls to try and drag it kicking and screaming into the fray of the site’s structure. It was at this moment that I lost faith in what I was doing here. Even though 90% of my site was still working beautifully within this structure, I was increasingly having to do these kludges to do what I wanted. I had started grudgingly using requestAction to start sharing functionality between controllers before reading that, as I had assumed, this was a Very Bad Thing. Realising my models were completely light on code, I figured it was this sort of highly re-usable and view-independent code that should be going here, so now my User model contains functions like isLoggedIn, my Download model contains functions like isOwnedByLoggedInUser and I have to guess this is ‘right’, because unlike NewsScape, where the organic structure that worked best for the context is what I settled for, I have this constant sense of guilt that I’ve failed the gods of MVC with every design decision I’m making here. I know I could just start writing my own base classes and impose my own design on all of this, but the convention-heavy nature of CakePHP (which I do approve of – except for the first few days where my brain refused to injest when to use camel case, when to underscore, when to capitalise and when to pluralise) has literally frightened me into building this fragile design which is loosely MVC at best.

You may be wondering if I actually have a point. I quite probably don’t. But to reiterate what I said before, I’m all for taking on different philosophies and design patterns to inform how we go about crafting code of great beauty, but other than that, I’m just not convinced it’s of benefit to our craft to hold ourselves hostage to someone else’s paradigm.