Tuesday, January 4, 2011

My own SDLC

If I don't have ADD, then I definitely get too interested in things too easily.  There's so much I want to learn about that it's sometimes hard for me to focus on getting something done.

The great irony is that this is something I complain about at work.  I am constantly getting pulled off one project in order to fight a fire with something else.  As a consequence, it is difficult to get anything done.  Previously, I was criticized for not being a good multitasker, but I no longer believe this is the case and more senior engineers have backed me up.

But the fact of the matter is, I need to simultaneously work on the sojourner project, including everything it entails.  Currently, the part I am working most on sojourner is just the launcher sub-project.  But eventually this thing is going to become a game.  On top of the launcher, I need to work on the documentation (which is in the design folder by the way), a web project (to view the documentation and do a few other things...most likely create characters), and I need to create some database tables for several things (the clojure launcher will use it to save classpaths, jar files, etc, and the game will use it to store in-game data).

Unfortunately, my experience with databases is limited, and my web programming next to non-existent.  A few months back, I bought a book on servlets and JSP, but I didn't get far into the book.  Although I don't mind learning about servlets (I intend to use jetty as a combined servlet container and web server) I'm not really all that interested in JSP since there seems to be a lot of negative flak around it (and templating languages in general, but JSP and even PHP really seem to get it).  Since I my knowledge of SQL is very limited, and my web-fu is even worse, that means I'll have to learn these as I go.  Nothing new for me, but it will definitely slow down the pace of the project.

I will however soon be putting up a separate open source project for the webpage.  I think I will use TurboGears as the framework, since I have read a little about Pylons, and it seems to be a model I am more comfortable with.  On the one hand, Django definitely has more uptake, and for my career, it'd probably make better sense to use and learn Django. But I don't like how Django forces you to choose its way of doing things (for example, you have to use it's ORM which others have said only works for a limited set of use-cases).  TurboGears and to a greater degree Pylons is more flexible, even if it doesn't hold your hand as much.

And besides, getting better at SQL and web programming can't hurt my career.  It seems like most jobs that aren't at the hardware level require some kind of knowledge of databases, and web programming isn't far behind.  While doing embedded programming is neat (there's nothing like actually getting physical hardware to work), I think EE and CE's are better suited to that work than I am.


So right now, I've been reading through TurboGears and created a real simple quickstart project.  There's quite a bit of reStructuredText documentation that I've been working on for my homebrew game, but there's no place to put it.  There's also the disadvantage that the docs are all static.  I'd like to be able to make the documentation dynamic and generated on the fly...for example when trying to cross-reference some documentation.

Also, I've been looking at some of the hsqldb documentation, and it's a little bit different than what I've seen in postgresql or MySQL (for example, in-memory tables versus cached tables).  The advantage is that I've got complete control of it in Java which will be useful for clojure.  But still, I'm wondering if I should ditch hsqldb and just go with sqlite or postgresql.  I'll probably need to do a little bit more research into this before I make a decision.

It's at this point I'd like to point out my SDLC.  I'm not a big fan of waterfall, scrumm, etc.  I do like SOME of agile development, but I think these formalized SDLC methods are a bit constraining.  Especially because I am unsure of the technology myself, I program in what I call a research, prototype and enhance loop (RPE for short).  I have seen before first hand the absolutely disastrous result of a certain technology chosen and used without any kind of research done into the costs of using said technology.  It may seem like a no-brainer to some, but having proof-of-concepts built, or at least a case study of the pros and cons of a technology should be done.  But believe or not, this is often not done.  Perhaps management feels that spending 3 months on a proof-of concept or getting all the pros and cons is a waste of time.  After all, aren't all programming languages the same?  Doesn't XMLRPC, SOAP, RMI and JSON-RPC all do remote procedures?  And in all earnestness, is there really any difference between Wicket, Tapestry, Ruby On Rails, Django or Lift (etc etc)?

If you think there are no tangible differences to any of these scenarios....you sir, don't deserve to make decisions.  All things have their pros and cons, and a job of an architect is to make sure that the pros help solve your problem domain, and the cons don't add (significantly) to them.  Of course, how do you know what the pros and cons are?  Are reviews on places like stackoverflow, reddit, etc really reliable?

That's where proof-of-concepts come in.  Do something simple in the technologies you are interested in and see how difficult they are.  I'll give you a real world example.  Due to some dissatisfaction with the way SWIG worked, I had been researching some alternatives.  I had played with python's ctype module, and it had some features better than SWIG (such as for example, it was highly obvious when python code had to interface with C code), though it also had some problems.  One of the problems was keeping up with API changes.  While SWIG could take header files of the C program, with ctypes, there was no such thing.  And unfortunately, despite the fact that you SHOULDNT break an API without going to a new major release, it happened all too frequently for us.  When we started playing around with Java, I started looking at ways for Java to make calls into a C shared library.  The old-fashioned way was JNI, and I had looked a little bit at before and shuddered.  I had heard of a library called JNA which promised to do away with JNI.  While JNA looks nice (it's kind of like ctypes), it required quite a bit of work to get the correct Java class matched with the correct C struct.  I then went back and tried a few JNI examples, and I found it wasn't nearly as bad as I thought.

The point of the story is that I actually USED all these technologies, even if just a little bit.  I got my hands just dirty enough to see for myself what the implications and limitations would be.  Does that mean that I would know everything?  No, but along with the reviews I see online, I now had a more informed decision.

So that covers the research part, what about the prototype part?  This is where I do something like Agile programming.  I believe that code projects of any size which has more than one developer is alive, and thus subject to "code rot".  Basically, code evolves, often unplanned (which is why I sometimes call my programming style "organic" programming).  When you are faced with a problem, it's best to model the problem as simply as you can.  This means making assumptions, often not making code robust to handle unusual input, etc.  But at least some functionality is made.  The key here is not letting others then take your code as production quality (which happens all too often).  In prototype code, the key is documentation, documentation, documentation.  Document that your code only handles certain code paths.  Document what it is doing and what still needs to do.  Don't be afraid to have a code to documentation ratio of 1:1 or even more.

The reason documentation is so important is that prototyping leads to an informal and dynamic programming style.  While you are coding something, an idea may quickly pop into your head.  Rather than stop your idea, and then add some Enhancement Request (or god forbid, use UCM enabled ClearQuest  where you have to link every code change to some CM activity) just go with the flow.  The one thing you may want to be disciplined about is branching your code or forking off a new clone...which is why DCVS's are much better than CVCS like subversion.  It's trivial to create a new repo or branch and thus isolate your new idea.  While merging isn't as easy as mercurial or git makes it sound, it's no worse than what you would have to do with subversion or ClearCase anyway.

So now that you have some prototype code, it's time to enhance it.  You will have bugs, and you will lots of TODOs, so it's time to go back and fix those.  I like to complete the enhancements and bugs before tackling new enhancement requests, otherwise, your prototyped code will never get to a "stable" point.  So the Prototype and Enhancement phases are in a feedback loop, and eventually they get done.

Well, what about getting requirements?  Ahhh, the bane of my life.  In my experience, getting requirements from non-technical people is like pulling teeth....mine and the client.  This is where rapid prototyping is supposed to help.  If you can come up with a limited functionality program, the client can give feedback on what they like or don't like, or help prioritize the still TODO items.  Sadly, it is my experience that clients will often take the prototype code as-is, because they too are under time pressure, and of course the quality sucks.  This is the danger of prototyped code.  But in my opinion, if you do due diligence and inform the client of the shortcomings, they have no one to blame but themselves.

Prototyping still doesn't help you get the very first requirements though.  I haven't ever used UML use cases or scrumm cards or anything like that.  For my own personal project, I simply ask myself what I would like, and then I write it down.  I then later try to scope out the difficulty of the requirements, and determine a priority (or dependency).

Yes, my SDLC is very informal.  Some might even laugh at it.  But software engineering isn't engineering like mechanical or electrical engineering.  Software Engineering is still in its infancy, and is more like a craft.  I see myself more as an artisan than anything.  And yes, coding is an art.

Not to rip on EE's, but I can't tell you how many 600+ line functions I have seen (and no, I don't buy the argument that pushing a new function on the call stack is THAT expensive...inline for crying out loud), or programs that were 30,000+ lines of code, that had no header files or were broken into sub-modules (ummmm, you do know that you can compile your code into into .o, .a, or .so files and link to them??).  While I have no clue how MOSFETs work, I do think I can code better than 80% of the EE's out there that I have seen.  And when I say code better, I don't mean code better bit shift functions, or create some weird function pointer callback that takes 15 minutes to look at and figure out what the return type is (man I hate function pointers that take function pointers as args....that's why dynamic functional languages rock).  But when I say I can code better, it means my documentation is much better, my code is broken down into manageable chunks (that don't require me to step through 800 lines of code to figure out where exactly the problem is that I got from a backtrace), and I can actually design better (code libraries rather than a monolithic gargantuan executable without function declarations in the c source itself....which is ok if you have a private API).

Remember what Guido Van Rossum said, code is read far more often than it is written.  And remember what General Patton said when asked about being a good leader, "don't give great orders, give orders that can be understood".  Design cleanly, code often, fix often and repeat.

No comments:

Post a Comment