The Benefits of Reinventing the Wheel
June 9th, 2009
My last post was also my most successful to date (where success is defined by page views and comments), but it came with a bit of criticism.
I made the argument that for the moment I’m more concerned with time to release than with building a perfect design. That’s not to say that I don’t care at all about actually sitting down and designing this thing, I am; it’s just that I have a few compelling arguments for getting this thing out sooner:
- This project was originally created to attempt to solve a problem at work, and I’d really love to see this deployed and enjoyed by the 20ish developers who could potentially benefit from it.
- By and large, this is meant to be a portfolio project to help find me a job in .Net. I’d like to escape my current job sooner rather than later, and get on with my new life working in areas I’m actually interested in. No offense to the language, but I just don’t spend much time outside of work working on personal COBOL projects, and I don’t read mainframe blogs. Conversely, this project shows I do work on C# outside of work, and I routinely read a number of blogs, and frequent sites, which highlight newer languages and methodologies du jour.
- If I leave room for improvement later, I’ll gain experience with refactoring (both designs and code). It’s a great learning tool to go back to your old code and see what works and what doesn’t. Seeing how far you’ve come since you wrote that stinking, rotting, maggot-infested piece of god awful code is a great way to remind yourself that you really are learning, and that you’re constantly improving.
With that said, I’d like to address one of the comments from my last post.
Reader JS writes:
Jesse,
I’d encourage you to write at least one or two database applications before you start using an ORM. While it can be a bit more tedious writing the queries by hand and debugging them, it is a worthwhile learning experience. Once the learning is done and you’re just repeating the same busywork you’ve already done a number of times before, then the ORM makes a lot more sense.
I think this is excellent advice. While I’m sure you’ll definitely learn a lot by implementing a ready-made ORM like NHibernate, it’ll pay more in the long run to have the understanding of how things work behind the scenes. Not all projects will use an ORM, especially when you’re working on an older code base, and being able to debug a problem in a method full of objects found in the System.Data.OleDB namespace is definitely a plus for your employer.
This argument is tangentially related to a topic which was popular on the internet last year – whether or not a programmer should know how to program in C. The argument there is largely the same argument I’m making here: knowing the guts of your tool of choice will make you a better programmer.
For example, I’m really amazingly bad at computer hardware. It’s embarrassing to say, but I’ve just never been comfortable pulling pieces out of my desktop and replacing them with new bits. It’s the reason why in 2003 when I bought the machine, I opted to have 1GB of RAM installed from the start. It was probably very much overkill for my needs, but I figured it would eventually be useful and I didn’t want to deal with it.
That desktop computer I bought failed the summer after I bought it. In desperation, I got brave and opened the machine up and started pulling bits in and out. I even took apart my parents working machine and tried to swap out the power supply to see if that was the issue. When I was done, I couldn’t even get the thing back together. I left some things unplugged for fear I’d blow the whole thing up when I plugged it in, if I’d put some connector in backwards somehow. When I took it into the local shop I’d bought it from, the guys there expertly snapped all the bits together and powered up my computer. They connected their various diagnostic tools and told me my motherboard was shot. They did in minutes what I failed to do in hours on the floor with screwdrivers and hope. All this because I didn’t understand the internals of a tool I relied on everyday.
With that in mind, I’ve decided to follow JS’ advice (which is really just following what I had decided already anyway) and forget the ORMs for now. I’m going to dig in and get dirty with my database classes. I’ll write SQL by hand, I’ll learn a bunch of new classes in a couple new namespaces, and when I crawl out the other side I’ll be a better developer for it.
There is a comment on one of the answers to a question on StackOverflow which sums up my point nicely. The question was “What is the best language for a beginner to write a blog engine in?” and the answerer had questioned why the asker wasn’t just going with an established brand like Wordpress.
StackOverflow user Nelson LaQuet stated:
The OP wants to build his own; and I believe it’s not so much for the practicality but for the learning experience. Re-inventing the wheel is a good way to learn how things work – even if you end up just using a prepacked solution in a production environment.
Excellent advice. I think I’ll take it.
If You Have A Hammer, It’s Not Always Wrong To Use It
June 7th, 2009
If you asked my girlfriend, and others close to me, what my biggest personality flaw is, you would be told that I’m a perfectionist. The last few days have been a shining example of that.
In my last post, I documented my source tree for the Reviewer project – four directories of planned features, and one directory called ‘Database’ which is the subject of today’s post.
I’ve been thinking a lot about how to implement the database interop for this project, since it’s my first time doing something like this and I really wanted to get it right. I came up with two (fairly obvious) ideas for this:
- Build the database lookups directly into my core classes.
The first idea I came up with was to have a few methods in each class which would talk directly to the database. For example, the review class would include a method like getReviewsByType(ReviewType rt) which would translate the ReviewType object into a literal stored in the ReviewTypes table in the (currently nonexistant) database, then perform a lookup on the Reviews table and translate the results into a List and return that.I didn’t like this idea because I didn’t want to mix my business logic with my database logic. - Build an abstract base class to handle all the database connectivity stuff, and create subclasses for each of my business objects that would handle the nuts and bolts of translating the objects to/from the database.
I didn’t like this idea because I’d be essentially storing details of the same business object in two separate classes. The Review class, for example, would be strongly coupled to the ReviewDB class (pending some better name for it).
In the end I decided that I liked option two best. I could probably decouple the two in such a way that the Review class would be reusable, even if I didn’t want to bring the ReviewDB class with it.
With that decision made, I turned to StackOverflow yet again (those guys will be sick of me and my noobish questions soon enough, I’m sure) to ask if this sort of implementation was standard or fundamentally flawed. I didn’t get any negative feedback on the design question I intended to ask, but I did get one answer which asked me why I wasn’t using Object/Relational Mapping (O/RM).
I’m forced to plead ignorance here. The two examples I was given were LinqToSQL and nHibernate.
For LinqToSQL my reasoning was that I’m using the Jet database engine for the short term on this project. The reason for this have a lot to do with the deployment options at my work since they’re the only customer for the product at this point. LinqToSQL is simply not designed to work with Jet. It can be tricked into working, I’m told, but you really don’t get the complete experience.
As for nHibernate, well, I really didn’t know what that was until today. I had heard the name before, especially relating to Java, but had never looked into what it was.
I weighed the pros and cons of this approach, and have decided to completely ignore both of these options at least until the project makes it to the 1.0 release. My goal for right now is to ship the product soon, so that my colleagues at work can benefit from it, and also to teach myself C# and development in general. Whether I’m learning how to use OleDB connections, or nHibernate, I’m still learning something useful. For now, I’ve decided that taking an extra week to figure out nHibernate really isn’t worth it. For v1.1 (or 2.0), I’ll take another look and start refactoring my design and my code, and that’ll also be good practice. I’m also planning on adding support for multiple database engines (SQL Server being the main target here), without losing the existing support for Jet/Access. It should be exciting, if most likely horribly frustrating at first.
I know this seems like a bad case of “if all you have is a hammer, everything looks like a nail,” but I’m thinking instead that if my hammer does a good enough job now, why not use it?
Starting Off Right With Version Control
June 2nd, 2009
This past weekend, I made a mistake.
For the past couple of weeks, I’ve been experimenting with a few things in C#. I made a quick mockup of some Registry-accessing code, which turned out to be completely misguided as far as why I was writing it, but it was great for diving into unfamiliar parts of C# and the .Net framework. The code takes a file extension and retrieves the default application for the ‘Open’ command, then spits it out to the screen. It was nice to get back into ‘real’ development after spending so much time in the terrifying depths of a legacy COBOL code base, and it also segued nicely into learning a bit about the OpenFileDialog class.
One of my adventures in C# accidentally turned into the user interface of my ‘Review Manager’ project. I’ll talk about the drunken stumble to this design in a later post, but suffice it to say I really liked the way it was shaping up.
Somewhere along this journey, likely as a direct result of some StackOverflow-related procrastination, I decided that to do this project right, what I really needed was some source control.
Although Git is getting a lot of press these days, it seems good ol’ Subversion is still the recommended choice for noobs like me. I downloaded the latest version of TortoiseSVN (1.6.2) and was on my way:
- Create a new ‘Development Projects’ directory for my serious work destined for an online portfolio… Check!
- Move my ReviewManager folder out of my Visual Studio ‘Projects’ directory (which will now be used for one-off projects and some prototyping) into the new ‘Development Projects’ directory…Check!
- Create a new root level directory to hold my SVN repositories…Check!
- Create a new repository for the Review Manager project…Check!
- Check in my existing work to the new repository…Che..Wait, where’s my.. Oh God..
As I said, I made a mistake. I’m still not 100% sure what happened, but it seems my work never actually made the move out of the Visual Studio ‘Projects’ folder. In a fit of irony, I managed to completely obliterate all my work while attempting to safely secure it in my version control system.
Thankfully, all that was really in the project was mostly just some basic GUI stuff that was partially contained in one of my prototyping projects, so it wasn’t a huge loss. What it was, however, was a giant wakeup call. Even on small projects, it pays to have a nice, secure, version controlled backup of your work.
This wasn’t a total loss. I decided to restart on the right foot and have organized my project directory a bit. This structure might not be optimal, and it sure as hell isn’t complete, but it’s a nice step in the right direction:
Review Manager
├───doc
└───src
├───Database
├───DirectoryManagement
├───Estimation
├───PeerReview
└───TimeTracking
The Database directory is going to be used for db connectivity classes and the like, but the other four are the main goals of this project. I’ll talk about each of these in a later entry.
As always, all feedback (positive and negative) is encouraged in the comments. I’d love to hear what you all think of my progress!
The Project
May 26th, 2009
It’s been a long time since I wrote anything here, especially since I ended my last post by stating I was getting back on track and would write more soon.
Not wanting to go into too much personal detail here, suffice it to say that I’ve gone through a few transitions at my day job, met an awesome girl that I’ve been with for nearly nine months now, and have dealt with some medical-related issues all since my last post way back in July.
Despite all of this, I have made progress with my plan, and there is much more happening now.
The biggest issue I’ve encountered so far, is that it’s hard to learn how to program without programming, and it’s hard to get programming a hobby project without having some sort of idea regarding what you would like to build. This issue has finally been resolved for me as I now have a project.
Everything at my day job goes through a peer review process, every form I fill out and every piece of code I write has to be approved by another member of my team.
With so many people producing so much work, it can be a bit difficult at times to find someone to do a review for you in a timely fashion. Various ideas have been tried to manage this process (including scheduled review shifts and a spreadsheet for making public what reviews you need done, and by when), but for various reasons each of these ideas has met with only limited success.
I’ve decided, largely for selfish reasons relating to my desire to learn C#, that the next idea on the list should be a software solution. The application itself will be fairly small in scope, but should provide enough of a challenge that I’ll learn something useful since I’ve been told time and again that the best way to learn a new language is to “use it in anger.”
Since this project won’t have any corporate support (although my team lead is aware of the idea, and is looking forward to seeing a prototype), I won’t be able to use the company’s SQL Server installation. I worked for a year doing support for in house MS Access applications (different company), so I’ve decided to just use Microsoft Jet, in the form of an Access-generated MDB file, as the first supported database engine. This is actually nice since I can start barebones with what I know, but it will force me to design the application in a modular way so that I can add support for “real” database engines in the future.
The application itself will be written in C# using the free Visual Studio 2008 Express, and will allow developers to identify peer reviews they need done. Users will be able to see all available peer reviews, optionally ordered by certain favorite items (i.e. reviews for developers they trust or could learn from, subsystems they’re particularly familiar with, etc), and assign themselves to the reviews.
There’s actually more to this than I’m writing here, but I think this is enough information for now.
More to come soon!
A Man With A Plan
June 3rd, 2008
One of the first things I did when I decided to undertake this project was to ask the programming subreddit for help. There were many helpful suggestions thrown my way, and I tried to do my best to make sense of them all.
The most recommended, if the most controversial, was to read Structure and Interpretation of Computer Programs [US] [CAN]. This book, known as SICP, is the publicly available textbook for a (former) introductory MIT course of the same name. Another popular choice was Introduction to Algorithms [US] [CAN]. In his post, “Get That Job At Google,” Steve Yegge recommends that the best “long-term warm-up” you can have before interviewing at Google is a good review of data structures and algorithms. His initial recommendation of a good book for this purpose is The Algorithm Design Manual [US] [CAN], but later states that “if you want to come into your interviews prepped,” then you really should be reading Introduction to Algorithms.
Since I’m trying to put an honest effort into getting the best “do it yourself” education I can, I’ve chosen to take these recommendations to heart. I’m expecting the delivery of these two books from Amazon within the next 48 hours.
Before explaining my other long term goals for this project, I want to note a certain fear I have with this project. That fear is summed up for me with just one word: Math.
When I was a kid, I used to absolutely love math. Math, as it turned out, loved me right back. Up until the 9th grade, I never had an issue with math; it all seemed to come so naturally. In fact, math could be downright boring. My first 9th grade math teacher, Andrea Loken, recognized this boredom immediately and rectified the situation. Within a week of starting the class, she came to me with an offer to move me into the advanced math class. My ego decided this was quite acceptable.
In the advanced class, I found that my usual “sit back and let the math happen” approach simply didn’t work. High school in general wasn’t the best time of my life, so I refuse to blame this class for my math issues later on. My issues largely were to do with laziness in the 10th and 11th grade which created a weak foundation of math knowledge that I’ve never recovered from. As a result, I’m not actually sure what the building blocks are to get me to where I want to be in terms of math know-how. My concern is that I’ll be reading along in one of my ‘teach yourself’ computer books and some math skill I really should know will pop up… and I won’t know it.
My solution to this is to turn to the only math book I have at my tangible disposal, my college textbook: Mathematics for College Technology [US] [CA]. My original plan was to take a couple of weeks and skim through the text, cover to cover, and to properly study whichever topics pop up as required knowledge.
After thinking about it in a little more depth, I think I’ll probably end up just diving right into the computer books while concurrently reviewing the math text.
Beyond math revision, SICP, and Intro to Algorithms, my plan becomes a little less focused. I have a short list of concepts with which I intend to become familiar:
- Database design & development. Normalization of data, when to denormalize, locking issues, stored procedures. So much to know, so little time!
- Version Control, both centralized and distributed. Not only do I want to understand the functional differences between the types, but I’m also very interested in how these tools are properly used – especially in a team environment.
- Programming languages. What are the differences and relative strengths/weaknesses of programming languages which are functional, object-oriented, imperative, declarative, statically typed, weakly typed… the list goes ever onward. By the end of this, I’m hoping that the concept of “the right tool for the job” will become a little clearer to me than it is now.
- Debugging techniques. What’s the “right way” to go about finding issues when they inevitably appear?
- Testing. Methodologies, technologies, ensuring the best quality I can.
- Low level knowledge. How does a computer actually work? What’s the operating system actually doing behind the scenes? How do I optimize my code when, and if, it really matters?
- Personal skills. This one isn’t strictly about software, but how can I build teams that work? How can I communicate effectively? How do I trick a user into telling me what they really want?
- Additional math. Once I’m back up to where I think I should be, I’m going to continue onward – learning what I can about probability/statistics and discrete math.
As I stated earlier, I ordered a number of books a few nights ago. I’m publishing the list below for “internet peer review.” A complete list, as it forms itself over the months and years to come, will eventually be posted in a more appropriate place.
- Structure and Interpretation of Computer Programs, Second Edition [US] [CAN]
- Introduction to Algorithms, Second Edition [US] [CAN]
- Design Patterns: Elements of Reusable Object-Oriented Software [US] [CAN]
- The Pragmatic Programmer: From Journeyman to Master [US] [CAN]
- Code Complete, Second Edition [US] [CAN]
- Refactoring: Improving the Design of Existing Code [US] [CAN]
- Software Estimation: Demystifying the Black Art [US] [CAN]
- Peopleware: Productive Projects and Teams [US] [CAN]
I’ll admit that I’m probably already getting a little bit off target. I’m betting on the assumption that when you don’t know what you don’t know, it’s probably a decent first step to expose yourself to a lot of things and sort of feel your way out with the help of your friends.
I’m turning to you now, Internet Community. If you see any topics for which I’m desperately lacking, if you have any suggestions on further reading, or if you just want to let it be known that I’m “Doing It Wrong,” then by all means let me know.
CS 101: Introduction to Computer Science
May 21st, 2008
This blog represents the public view of my latest personal endeavour: I’m going to create my own software engineering degree. To be a little more specific, I plan to try to learn as much about the field of software development, and a bit of proper computer science, as I can. Rather than spending a few more years, and a few more dollars, in a post-secondary educational institution, I aim to teach myself the topics of computer science I would learn in the classroom on my own.
To be completely honest, I’m not entirely sure from where the motivation for this project came. As near as I can tell, there were three fundamental sources:
- A video I found on reddit by a guy called Clay Shirky that talked about our collective ‘cognitive surplus’ and what we can accomplish if we start putting our ‘free time’ to better use.
- Joel Spolsky and/or Jeff Atwood. While I’m no longer sure exactly what was said, I know there was a point several weeks ago during a stackoverflow podcast where I more or less decided to start this project. One of the two made a distinction between career programmers, those who program as a job and only as a job, and ‘geek programmers’ (for lack of a better term), who program largely for the love of programming. The latter of these being notably better because they simply care more about their craft.
- Personal dissatisfaction with my career thus far, as well as an increasing fear of skill atrophy. With all due respect to my current employer, I don’t really have any sense of identity in the work I currently perform. I got into this particular job as a way to stop my bank account from hemorrhaging funds, and am now worried that I’ll never get back into newer technologies and that this in turn will cause me to regret entering the field entirely.
This will clearly be a monumental task, which is part of the reason this blog exists. My thinking is that if I have a public record of what I am doing, I’ll be more likely to continue to make an effort to accomplish my goals. If I were to put this project on the back burner, there would likely be people (admittedly, at this point it would mainly be some close friends and selected family members) who would ask about my lack of forward momentum. This would, I hope, give me the kick in the butt I need to get back into it. If nothing else, I’m trying to follow Jeff Atwood’s advice from a year ago: “When in doubt, make it public.”
I’m not expecting this blog to ever develop a major following, but I do hope that if others embark on the same journey that maybe they will find some motivation or guidance here. The hardest part I’ve found so far is learning what I never knew I needed to know, so I’m going to lay it all out here as I discover it so others don’t need to blaze this trail again.
Wish me luck.