Object Oriented Programming: Data Mapping

The What

Just because you use objects doesn’t mean you are programming in an object oriented manner.  A function like this defeats the purpose:

public function init()
{
    $user = new User();
    return $user;
}

It immediate creates a dependency.  Whatever object init() is in, we know it relies on User.  It also prevents us from testing init() without User.  User needs to be in place, and it needs to work.  If init() fails, we don’t know if it’s init() or User.

So why bring this up here and now?  It’s in response to a post on Forrst (which you can’t see because it’s probably behind a login wall).  I don’t mean to pick on the person posting the original thread.  It’s simple a case of not knowing.  Anyways, the follow up response to my reply included: “I guess we could also put the database code within the User class itself”.

The basic question revolved around creating a new User object.  Here were my suggestions.

My suggestions

Actually, no, you want to keep your DB code in a different object. You want a Data Mapper instead to actually send the Model into a DB object. Basically:

$user = new User("[email protected]","password");
$mapper = new UserMapper($user, new MapperStore());
$mapper->save();

Now, you could move that into User.

$user = new User();
$user->save();

You’d have save() accept two optional parameters.

public function save(Mapper $mapper = null, MapperStore $store = null)

Mapper and MapperStore are interfaces, of course. That way a user could send along a different Mapper if need be. I’ll get to why you might want to do this in a bit. Anyways, if $mapper wasn’t set, save would Reflect upon the class name (User) and grab the appropriate mapper: UserMapper, and use that.

MapperStore could default to a DB Connection, and essentially do the same thing, reflect upon the User class, and save the User information to the Database.

So, how does this all become useful?

$card = new Creditcard();
$card->save();

Simple enough. But let’s say you want to store certain information in a different location. Rather than change your Model, or your mapper, or your Store, you do this:

$card->save(new SafeCardMapper(), new FileStore());

So, your Model remains the same, and the mapper merely strips out information that shouldn’t be passed on to the storage object, in this case a FileStore.

Of course, you can set this stuff when you construct Creditcard as well, and it’s a fair argument to make. Personally, I like keeping the stuff close to where it’s being used. It means I can also do this:

$card->save();
$card->save(new SafeCardMapper(), new FileStore());

(Of course, even that smells bad to me, and I’d want to consider chaining mappers and stores together somehow so I could just call save() once. Maybe something like:)

function chainStorage(MapperStore $store, Mapper $mapper = null);
...
$card->chainStorage(new FileStore(), new SafeCardMapper());
$card->save(); // This would save both DB and SafeCard mappers

Anyways, once again, this probably goes above and beyond what you want. =)

Retrospect

Even still,chainStorage() and save() bug me.  I was branching from the OP’s original comment.  I’d much prefer to turn this around, something along the lines of a real Storage system.

$storage = new Storage(array(new FileStore(), new SafeCardMapper()), array(new DatabaseStore(), new CardMapper()));
$storage->store($card);

In this case, Storage simply accepts Store/Mapper pairs (or we could have a addStorage() method which accept both a storage and mapper.  Options are obvious.  Point is, You simply pass along what to store, Storage loads the Store, and uses the mapper to pull in the data.  Card doesn’t know it’s being stored.  Nothing changes.  Mapper would hand Card an updated ID if needed after the update.

Anyways, this is why they invented refactoring.

4JC.IN

4JC.IN is useless for anyone but me, but it’s still useful for me.  A simple tool, a weekend project, and a little exploratory on the web design side of things.  The point is to have ready my own HTML bootstrapping system.  With a quick call from the web directory, I can have everything I need downloaded and setup.  The command is short, and easy to remember.

curl 4jc.in/to | sh

Yes, I’m running a remote file from the shell.  Evil me!

Really though, it’s simple.  The name is meaningful in several ways, too.

  • JC.IN sounds like Jason.  Putting the 4 in front makes it “For Jason”
  • JC is JavaScript and CSS (the original meaning).  For JavaScript and CSS In To here.

I eventually plan on adding some additional things.  Zend Framework download and set up with some basic things I always include, other libraries I’ll pick up.  Font’s I like.  A basic template for HTML.  robots.txt, humans.txt, and privacy.txt files.

All sorts of little things.

In the grand scheme of the web, 4JC.IN doesn’t do anything for anyone.  It’s a tool for me to use.  But it was fun.  It is fun.  It’s a place to put the tools I use.  I may link them into git, so a quick command will fetch me the latest files and what not from a git repository.  I don’t know.  But it’s easy. And I like it.

Eclipse with FTP Support

FTP in Eclipse? This question gets asked a lot.  An FTP plugin for Eclipse that will put your file up onto the server with a save of the file.  I don’t use it much, but for fast projects on my home server, it makes things easy.

The plugin is called ESFTP and still works.  The files were last updated in 2007, but installs and runs just fine on a current Eclipse install.  It has few features, but all the important ones.  The key bindings in the plugin don’t work.  However, you can use the Eclipse Keys options under General preferences to set them.  Just search for esftp.  You’ll probably want to edit the Put File to Server and Save functionality.  That will save the file locally, and FTP it up to the remote server.

It currently only supports FTP and SFTP.  Passwords are stored locally as plain text.  But it works.

privacy.txt

privacy.txt is last weekends project.  It’s a simple idea.  I’m currently putting together a parser in PHP.  I also want to see about implementing browser plugins for this as well.  A little plugin that will sit and run in your browser and make a request for privacy.txt on a page it visits, and alerts you if the site has a privacy.txt file.

I also put the project up on Drumbeat, Mozilla’s new project site, as well as posting it to Forrst to get feedback.  Anyways, I’m posting it here to get additional feedback from all my one reader.  Let me know what you think.

PTI – PHP Tools Integration for Eclipse

I use Eclipse for my PHP coding.  One thing I love about Eclipse is the numerous plugins available.  The down side is you have to know about the plugins.  One plugin I find a must have on any Eclipse installation is  PTI – PHP Tool Integration.  You can find it on the Eclipse Marketplace in the Help Menu.  It has several components.  It allows you to run unit tests through PHPUnit from the editor with a click of the button.  It can do a CodeSniffer check and display the results in your editor so you can quickly and easily fix the problems.  It also include PHP Depend and PHP Copy/Paste Detector.  The system comes with all the stuff needed to run out the gate, but you can use your own versions of the various tools.

Ideas of March

Ideas of march is a nice idea, especially when you consider the recent moves by Twitter.  Controlling your own data on your website gives you more freedom.  Services like Identi.ca should help alleviate the pain of moving from Twitter, but your own blog is still your own place.

I used to write a lot more than I do now.  I thought I had interesting things to say back then.  I was a bit more naive, and a bit less intelligent, and much less wise.  Today I suffer an inverse problem: fearing I know to little.  ConFoo helped to solve that problem.  I came away realising I know more than I give myself credit for.  I also discovered that I could hold meaningful conversations with other hackers.    The problem was, I’ve been sheltering myself from the local developer community for so long, for one reason or another, and I’ve lost that sense of connection with other like minded developers in a non-work setting.

Ideas of march and ConFoo make me realise that the most important thing for a developer is community, and losing that will cause you to lose your way.  The most fun and successful I’ve been has always been a result of community efforts.  It’s realising and understanding this that makes me realise more than ever that I need to get out and meet the local community, be involved more online, and contribute back what knowledge I have.

So, here’s my pledge, for the ideas of march, to publish more, comment more, and contribute back to the community as a whole.

The Future of Apple Products

I’m calling it, yet again. Here.  I’ve made mention of this multiple times on Reddit and HN.  I’m putting it here.  The future of Apple’s Products.

First, if you look at their recent product line, their is one common theme.  Wireless.  Everything is wireless.  Wires exist if they have to exist, but if they can remove the wire, they want to. The next is size.  Everything is getting thinner.  Smaller.  Lighter.  Even the monster iMac is thinning down.  Next, mobility is key.  iPhone, iPods, iPad, the Air.  Finally, their big successes are appliances, not computers.  These aren’t things you open up, these are things they’ve created that you use.  The AppleTV is your big sign.  It’s exactly that: an appliance.  You buy it, you use it.  That’s it.  You’re not running around updating the RAM or adding more hard drive space (which is why they removed it from the second one).

So, what does this all point to?

A server/client setup.  It’s nothing new, but neither was the iPod, iPhone, or iPad.  They were existing concepts that Apple perfected.  So it will be with the future of home computers.  You’ll buy a computer.  It will be a box.  A white box.  You put it in the corner.  You plug it in.  No wires.  Just the plug.  It’s wireless.  It connects to your AirPort Extreme.  It has a screen it connects to, wirelessly though bluetooth.  You configure it with this screen.  It’s like an iPad.  Only it more of a dumb-client, so it’s ultra light and ultra thin.

Your AppleTV can connect to this computer and use it for storage.  Your iPhone can connect to this device and use it.  Your new Air uses this to do all it’s heavy lifting, leaving the Air to get lighter.  Less need for storage space, as the home computer can store it. According to posts on GamingBuff.com we don’t worry, gaming will get better.  Just look what OnLive can do.  So, you’re on your iPad, and you can access your computer and use a program.  Full screen mode on the Mac? What other OS uses full screen mode?  Oh right, iOS.  Suddenly, apps using Apple’s Full Screen mode can move to the iPad.  With the Mac App Store, Apple can ensure this is done.

Oh, we’ll still have big screen monitors for our desks.  They will be lighter, and connect the same way.  Wirelessly and with no effort.  Working on one screen, you can switch to another, and since both devices are connected to the same central computer, you’re work carries over.  Be working on an email on your iPad, then move to your computer.  Auto Saving features that apple has will make this even easier.

You’ll but this computer, and you’ll buy software from the App Store.  Apps on iOS devices and Mac’s will become indistinguishable.  Because the computing power is being handled by the central server, the devices you’ll use (the clients) will be even cheaper, meaning you’ll buy more for various needs.  Maybe all those digital pictures frames will connect into an iPhoto picture set.

Touch screens everywhere, wireless devices for input if needed, but overall, you won’t use a computer.  You’ll be doing something while using a computer, which is sitting in another room.  Oh, and of course all of this supports your typical family (if there is such a thing).

And because it’s all one computer, it’s easy to handle media.  I can buy the media on any device and stream it out to another without thinking about streaming.  I just play.

Finally, with MobileMe in place, everything is accessible via the cloud.  Leave home?  Connect your Air to your iPhone hotspot and link into your MobileMe.  Access the stuff in the cloud, or more likely, access files on your computer at home as if you were there.

What about people who still want a real computer?

Pro.

Mac Pro, and MacBook Pro’s.  They are pro, after all.  And even then, they’ll still be able to link into the main computer.

Don’t get me wrong, I think these “dumb” clients will still be able to operate detached from the mother ship, but I don’t think you’ll want to.  The real power will be that white box in the corner.

I could be completely wrong.  But Apple has everything it needs to do this, and it’s something they would do.