Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, July 31, 2011

From a Java/C# world to Ruby's: Writing modular code

For the past handful of months I've been dabbling in Rails in my free time to play with some projects.  It's a fun platform for creating applications and I (as has been mentioned) dig Ruby.  I'm starting to actually build up enough code to warrant a little more discipline than what I've had so far.  For the most part, I've been plowing through just trying to experience all the tools and tricks the platform has to offer.  I couldn't really be effective otherwise if I hadn't given myself any time to play in the sandbox.

One thing I'm trying to learn is how to modularize code in Ruby.  How and where do you draw lines of responsibilities?  Where should code live?  Should I use a module or should I use a class?  There hasn't been a straight forward answer.  Ruby being dynamic, open classes and being able to intercept/modify just about any behavior in the system...it feels like my first year away at college (well, not really but you catch my drift).  While it's a lot of fun, you have to make sure you don't run wild with your freedoms.  There's a limit and you have to govern yourself.

Again, where are the lines drawn?  What are the right things to do?  It's not apparent.  Look at models as they're known in Rails.  Models use the Active Record pattern where each instance constitutes a record in a persistent store.  So what is the typical Rails model responsible for?  Reading and writing itself from a persistent store at the least (along with any of its child models).  This alone will make members of the CQRS Illuminati grow faint.  But it doesn't stop there.  Also, you need to perform your validation there which makes sense for any stateful, data-driven creature to do.  

At first, I let everything pile into my models.  If I had 3 ways I wanted to query things from the DB?  Oh, hey, I need to query my associations too, what should I do with all that logic?  Put it in the model.  If I had extended validations dependent on certain conditions?  It undoubtedly went in the model.  If I add an authentication framework that needed to decorate the client classes?  Hey, I'll just add it to the model!

It never felt right and as I piled more functionality on, things became especially itchy.  Instead of trying to foresee how this would all pan out and try to apply some half-brained pattern of my own, I just went for it and made things a sloppy mess.  I really wanted to see what the wrong way to do things was so then the answer would be more apparent.  Just like my early days when I realized how tests benefited my code, I could learn from it.  Why?  Because Ruby isn't Java or C# and I'm a Ruby part-timer.  I've seen and read about trying to apply patterns from either of those languages that is inappropriate.  I decided to let mother nature dictate how I should proceed.

In the case of the rogue models, I found what makes me most comfortable.  First, anything related to the data and validation of a model stays in its class definition.  Second, any associations defined stay in the model's class definition.  Third, anything that demonstrates how that model behaves in its domain should stick around (if possible).  I want to be able to see and quickly digest what the model is and what it's related to.  

Last, everything else, provided that its a significant amount of code, is placed into modules.  Modules allow me to create meaningful, cohesive groups of methods and constants.  For example, the code to query the DB (in any number of ways) is pulled out and placed in some sort of data access module.  Modules, while not being the same as classes, act very much like a class in most senses.  What I don't have a feel for is how many includes is too many includes.  The models get this very facade-like feeling.  They do a lot.  It's still something I haven't quite gotten used to yet.  

So, the short of the long, modules are nifty and I can draw parallels with how I used interfaces (and ultimately their implementations) in Java/C#.  It's the same song, just a different dance.  Use them to decompose the larger objects and group logically related functionality.  

Sunday, February 27, 2011

On the fence about Java, open source is the shiznit and .NET build automation sucks

I moved to a new team more than half a year ago and at first things were rough.  The team itself was fine but I was giving up my precious C# for Java and I was entering a whole universe of new software.  My technology stack changed from Microsoft branded IDEs to that of the open source crowd.  I was out of my element but I thought, "Hey, time to try something new!".

Let's just get this out of the way; as a language, Java is not aging well.  Certainly not in comparison to C# which is getting updated more frequently with a lot better language niceties.  When .NET rev'ed itself up to v3 it brought along lambdas and extension methods which makes for some really nice, clean code.  This is noticeably absent from Java.  Even the simple act of passing around functions is no where to be seen in Java.  I have to create a full-blown class that implements one method.  It feels like Java is more worried about being pulled from the holy scripture of Design Patterns than it is about making a language that is enjoyable.  Ah, you can pass an anonymous class but it's still waaaay too verbose.

But that's the thing with Java.  It seems like it tries to be as horrifically verbose as possible.  One of the common Java practices is to mark everything final.  You see final everywhere.  Final member variables, final arguments, final variable declaration, final classes, final final final.  You'd wish that they marked things NON-final because there are far fewer instances of that.  Better yet, choose a language where variables are immutable by default.  You end up with a lot of chatty code, which is unfortunate since it's already a static language...you don't want to be known for pushing the envelope on verbosity.  Here's my favorite quote about it,
Whenever I write code in Java I feel like I'm filling out endless forms in triplicate. 
-- Joe Marshall
I can forgive these sins because I've finally been exposed to open source software.  Software built by the community.  For us, by us.  Open source software has a distinctly different flavor to Microsoft software.  Tools load faster.  There's less fluff.  It's more of what you need and less of what you don't need.  If something has a bug, it's fixed quickly and you can get the patch as soon as someone posts it.  You don't have to live with the same crap for years because it just doesn't show up as a priority on Microsoft's radar.  You know, like the "add reference dialog" that has been the bane of our existence since early 2000 that they only recently addressed (sort of).

I was introduced to Maven which is build and dependency management for Java.  For anyone who cares about build automation (and that had better be ALL of you), Maven beats the ever living snot out of anything you can find in .NET.  .NET's build automation story is absolutely abysmal in comparison.  I know some people think Maven is kinda crappy but it's still light years beyond what the .NET crowd has going on.  The only thing that seems to be standardized in .NET is using NAnt (and possibly but incredibly doubtfully, Albacore/Rake).  Here's a simple scenario that is more difficult to do in .NET,

  1. Gather dependencies
  2. Compile code
  3. Run Unit tests
  4. Run Integration tests
  5. Deploy the application
  6. Run smoke tests

Step 1 was always something that was custom to whatever shop you worked at.  This is where someone had to copy third party libraries somewhere your build process could access them (probably a lame network share).  This is a problem that has been solved for years with things like the Maven repository in Java and Gems repository in Ruby.  Maven just does this out of the box.  When you run a build, it will retrieve your dependencies prior to compilation.  There's a project NuGet for .NET that is supposed to alleviate this problem and I admit I haven't tried using it.  I can only hope it gets integrated into another project like Maven for the .NET community.

Steps 2-3 are straight forward (and usually) don't introduce too much pain.  Step 4 usually requires partially constructing the environment of your application which includes databases, web applications and other such "heavy" dependencies.  This is where the open source community trounces .NET.  When I tried automating testing of web applications it required that IIS be installed, that I had the correct users/authentication, that I figure out the mystery of the Web Deploy tools that are anything but intuitive and extremely prejudiced to IIS 6, blah blah blah.  It was a process that required massive manual intervention and implementation.  It's brittle and no company wants to pay for the time it would take to implement that.

With Maven, I just reference the Tomcat web server plugin, tell it to start a web application on the fly, install it, and run it.  It's disgustingly simple to do and it's actually running a very good analog of my production environment.  You don't get Tomcat Home Edition or Tomcat Developer Edition or some other lame neutered version of the web server product (I'm looking at you Cassini web server).  You get the real deal and you get it with only a handful of XML declarations.

Step 5 in .NET has no real public support or method.  It sucks.  Using the same Maven Tomcat plugin I mentioned above, deploying your web application is a breeze.

I don't think I care to carry on describing how immature the state of build automation is in .NET.  Suffice it to say, we .NET devs should stop waiting for Microsoft to make it for us.  It's a glacial development.  There's too much to be learned from the open source software projects.  First lesson, not all .NET projects need to be monetized.  Yes, you can be compensated for your hard work but there are tons of opportunities to do that outside of selling a product.  Embrace your community, have them push the feature list.  We can go from there.

So while I get a lot better developer tools in open source software, it doesn't come without a price.  I'm not impressed with documentation and it's difficult to find the answers you need.  Unless you subscribe to their IRC channel or mailing list, you aren't going to find help from available online content. Sure, it can get you going but once the rubber meets the road you will inevitably hit an issue that doesn't seem to be covered in anything you can find with conventional Google searches.  I've come to loathe all the websites that index mailing lists, jira and java documentation only to provide you with advertisement-laden dead ends.  You'll have to subscribe to a mailing list, post your question and pray that somebody wants to respond to a question they've probably seen a dozen times before.

The open source world isn't perfect but I love the tooling and the low barrier for entry.  If you've been living in the .NET bubble for some time, take a break and try something new.  The worst case is that you recognize ways to make your life easier.