Andy's Fun House

30Jan/160

Weekend Projects Gone Awry, Part 2

MortalKombatRound2

The Idea: Outmoded

A friend visited me recently in Boston, and while we were being typical lazy gentlemen, the prospect of developing a game together at this year’s Global Game Jam (GGJ) surfaced. Though lately I’ve found it hard to be interested in anything to do with games or game development, but we agreed we’d like to make something without “graphics” that simply ran in the console. And so it was, that I created a project called “Outmoded.”

 

Executing

The first revision of Outmoded was done over two days while at the Barker Engineering Library in MIT. I chose C# so that I could finish the work in a few hours, and I’d estimate a total effort of about 5 hours was put into the project. The system worked within acceptable constraints and only had problems if you found yourself clearing the entire screen repeatedly for animation effects.

However, as the GGJ drew gloser, Alex asked if it wouldn’t be more performant to build the system in C++. Anyone who knows me well knows that I have an addictive relationship with C++, so ultimately it took very little for him to convince me this was the obviously correct path for the project. I created an experimental branch, scrapped the code, and got to work.

Over a couple work sessions I rewrote everything and had a simplistic proof of concept working on both Windows and certain flavors of Linux/BSD/OSX.

 

Tech Notes

As it turns out, moving to C++ was potentially a final nail in the coffin for the GGJ collaboration. Though I got to relearn things I hadn’t used in well over a decade (potentially closer to 15 years), makefiles were never a strong suit and OS X appears to have some fascinating ideas on development, which is no surprise to anyone who has used XCode. Also, there was a lot of struggling with Clang as the compiler on Linux, eventually forcing me to revert to g++ in order to get the makefile working.

This was excellent practice for some upcoming cross-platform C++ work I’ll be doing before the summer, and I’ll be very thankful for the rust removal this work provided. There’s a very obvious advantage for using Windows as a development environment, I was much more productive/effective there than on Linux.

 

Conclusion & Reveal

The GGJ theme, “Ritual”, seemed like a great opportunity to build an interesting yet simple game, but the fatigue of debugging the engine’s production proved too much of a negative for some of the team. Thus we have opted to bury the project and explore other avenues. What does that mean for Outmoded? Not much, frankly. I’ll probably fix the remaining bugs if they aren’t too troublesome and maybe add a frame feature, but I’ve gone well past the amount of time I intended to pour into this trivial thing.

https://github.com/AndyM84/outmoded/

 

- Andy

29Jan/140

The Repository Pattern

[UPDATE: 01/30/2014] I have been informed by a friend that common terms for these two types of repositories are 'generic' and 'specific'. As a result, I have updated the post to use this terminology instead of what I'd chosen (monolithic and disparate).

Having finally found myself being introduced to the finer points of computer science at my new job, I am enjoying the foray into a touch of philosophical programming discussion. This will be (hopefully) the first in a haphazard series of posts outlining my own thoughts on those discussions. Full disclaimer, I am still pretty new to correct terminology and thus likely to fumble with their use…I’m not sorry, but I also don’t mind being corrected.

Repository (As I Learned)
When I first learned of the Repository pattern, I was shown an approach to encapsulating access to data entities that simply removed the business layer from having to touch queries. You provided an object that wrapped around your entity and thus made it so there was only one place to go when it came to add/edit/delete methods used by the rest of your code. A simplified example of this might look like this:

Monolithic

It’s simple, and it tends to significantly clean up your business logic if you’re the kind of person who just tosses their queries hither and tither. One coworker seems to have coined the term ‘monolithic repository’ when trying to describe this approach, and I’ll be using the word ‘monolithic’ moving forward. Apologies to anyone who thinks they came up with it first. The common way to refer to this approach seems to be calling it a 'specific repository', so we will be referring to this hereafter as 'specific'.

IRepository and IUnitOfWork
At work we are beginning to implement what I have been told is a “pure” version of the repository pattern. As it was explained to me, there are really two patterns, the first being the Repository and the second being the UnitOfWork. To simplify what I was told, you would say that a Repository provides access to a set of data and UnitOfWork writes any changes to the set of data to their source.

In order to accomplish this we’re using a bit of dependency injection (DI) along with two interfaces:

Disparate

We also have a Repository<T> class and IUnitOfWork<T> class which are used by the DI to satisfy the requirements a class may have. The implementations can be found pretty easily with a web search, so I hope you don’t mind me skipping them for now. For the sake of this post, I will be referring to this approach as ‘disparate’. The common way of referring to this approach is to use the terminology 'generic repository', so we'll use that from here on out.

Bridging the Gap
The specific approach provides repository objects which are fairly customized for entity interactions. Initially the generic approach does not, but there is a fairly easy way to overcome that in C# using extension methods:

ExtensionMethod

Since we are using DI in our system, we know that we will always be initially referencing the repository dependencies by their interface, IRepository<T>. With this in mind, we can easily create an extension method for all sub-classes of the interface giving them access to the FindUsersByEmail() method, just as we had implemented with the specific approach.

The specific approach can easily be rearranged to reflect the basic UnitOfWork separation from the Find/Add/Remove methods, so I won’t waste the space showing the simple movement of the Db.SaveChanges() call into its own method.

Fight! (And Conclusion)
Ok so there isn’t really a fight here, at least not from my perspective. Both approaches afford the ability to swap out sub-classes and instead use mock data storage (probably through a List<T> or similar) for building unit tests. Both approaches encourage users to keep their business logic devoid of direct queries to the data layer (assuming you use something similar to the extension methods above to provide custom entity-specific methods for the generic repositories). It almost feels as if the choice between the two comes down to a personal preference, since with either I can easily implement the behavior of its counterpart.

Still, the times that I have discussed this with my coworkers I got the sense that there was a natural desire to side one way or the other. Purists seem to prefer generic while pragmatists mostly side with specific.

One of the reasons I wanted to write this post is to see if anyone could show reasons one approach is truly better than the other. Do they perform differently to an extent worth citing? Are they easier to implement than the other? Do they save significant effort? I certainly can’t say. My only thought is that it would be much more difficult to adapt the generic approach to a data access system which doesn’t rely on in-memory storage of change sets (perhaps direct SQL).

Regardless of the result of any argument, it’s at least been fun grilling coworkers. Here’s hoping this is just the beginning of the study of the ‘finer points’ in programming.

 

- Andy