Wednesday, September 30, 2015

The non-technical side

Normally I can explain away a long absence by sheer laziness. Like anybody else, I slip into the grind and don't really feel like thinking about what I did at work once I slink home.  That's not the case this time, however.  At the time of my last post, I was at a very large retailer working on a sort of a "Skunkworks" project to improve the quality of a few aspects of its IT experience.  Though I was "technically" function in the role of a technical lead, I mainly developed software.  I was lucky enough to build up a highly democratic team, and with a project leader that didn't have much of an interest in all of the trappings of agile, we managed to get a very effective Kanban flow going and each did our turn in the leadership chair.  By this, I mean that the weighty "architecture" decisions and even ideas about how we could improve our day to day were completely democratized.  There wasn't an executive decision maker on the team, and things worked well.  Mind you, this was a team of very experienced, very agreeable developers, which isn't something that grows on trees.

Now, let's return to the "until recently" part of this post.  Though I was enjoying my stint at said large retailer, they decided to start going a different direction vis-a vis contractors.  I tested the waters and ended up finding an amazing opportunity right before the large retailer decided to extend me the extension I'd asked for.  Off I went to another, slightly less-large retailer.  In addition to being an altogether new technical challenge, the opportunity represented an extra set of responsibilities.  I spent a good deal of my time at my prior contract in a "people" role, figuring out how to make a team work better together, establishing effective procedure and sometimes, tearing down and restaffing teams.  I was tasked with doing a lot more of these "people" things at my new gig and a lot less straight "tech" stuff. 

Though I'm only a few weeks in, there are a few insights worth sharing about the transition and some of the things a technical person notices in this role.

You can't change everything overnight
I have to remind myself of this every day.  There are a lot of things that need fixing at my current gig.  From the lack of tests, to the waterfall-in-disguise "agile" process, to frequent micromanagement by developers.  These are all things that need to be fixed, but there's no better way to confuse, upset or anger your engineers than by shaking everything up at once.  Given, there probably are times where you could go "scorched earth" and roll an entire team over, but chances are you're going to need to maintain some existing software. And on that note...

Things are the way they are for a reason
Regardless of controlling one individual on a team may be, the status quo of a team is the result of a variety of factors.  If a team has delivered software, they've achieved some kind of success doing things the way they do.  As I mentioned above, I'm an advocate of the "unassigned and prioritized" backlog approach.  At my current gig, all tasks are pre-assigned during IPMs.  This made my blood boil at first (frankly, it still does) but I realized pretty quickly that the developers on the team weren't comfortable or capable of self-directing their work.  The only way the product team could get movement on tasks was to force them down to developers.

Leading by example goes a long way
This one is pretty simple.  If you want to earn a team's trust, the best way to do this is to be a part of the team.  When I was getting started, the expectation was that I was going to be a management "type," dictating terms and expressing my degrees of satisfaction from my ivory tower.  This has never really been my style.  I found that my team became a lot more comfortable with me when I embedded myself in the lab and did some programming.  Sadly, time is a precious commodity, and this it's sometimes difficult to find time to do this. 

There isn't one perfect way to do things
One thing I've noticed with my teams is that they do their best to "rigorously" follow the standard agile methodology.  Standups, user stories, iterations, IPMs, retros and so on.  Believe me, it's entirely possible to do these things and be completely non-agile.  If the team doesn't understand the purpose for the ceremony of agile, they're not going to glean the value of it.  When standups are becoming glorified status meetings, they should be cancelled.  When retros don't result in any tangible feedback and improvement, they should also be canned.  The whole purpose of agile is to be more effective in how work is completed.  Not every little part of it is going to work for everybody.  In fact, in my experience, I feel like trying to cram the trappings onto a team that doesn't understand them is a great way to get waterfall in disguise. 

Stay positive
There's always a light at the end of the tunnel.  Chances are, if you're not happy with the way things are going, you're not the only one.  Nobody wants to work around the clock, nobody wants to get beaten down by the business and similarly, nobody wants to be bored out of their minds.  If you start showing the right way to do things incrementally, chances are you can get some momentum in the right direction.  Also, it doesn't hurt to bring in some like-minded individuals. 

Wednesday, June 24, 2015

So you want to Mongo?

After a good 6 months of solid Mongo-ing, I think it's finally time to share some insights on the platform.  I can't remember if I shared my initial reasons for delving into Mongo, but the driving reason for moving on was a need to persist objects with a variety of nested properties.  Without exposing company secrets or boring you, it fit neatly into the problem we were trying to solve.  Imagine a standard table row with a varying degree of metadata underneath.  The standard way to do this in the SQL world is to have a secondary table that essentially serves as a key-value store (ironically, how some NoSQL databases store data).  Resulting access to the table would require a JOIN and things would get complicated when it was time to model your data out on the object/software end.  

After a lot of discussion amongst the team, we decided that the variable nature of the data (as well as the resulting oddness in data modeling) called for a change.  We had previously modeled our structure in PostgreSQL and the transition over to Mongo was pretty seamless.  The beauty of using Mongo for our specific platform was how it plugged into Spring.  Spring's Mongo support is absurdly easy and simple, and allowed us to store our metadata as a simple Map.  Mind you, there are most assuredly ways to do this with SQL databases as well, but Spring Mongo is perfect for this right out of the box. 

Anyway, let's get into some of the advantages and pitfalls of using Mongo and some reasons why you might want to consider it, and other reasons you may want to avoid it. 

Pro: Your data is best expressed as "documents," rather than "rows"

Mongo makes no qualms about being a "document store" rather than a traditional database.  What this means is that you store "collections" of JSON documents.  You can query these documents based upon facets of field values quite easily, with decent performance.  When you start to spread your data out across several collections, however, you're going to run into a wall.  The concept of a JOIN simply doesn't exist here, which leads us to...

Con: Your data structure changes frequently but your model can't

If you're going to use Mongo, you're going to need to be flexible on your modeling/software side.  Where SQL databases allow you to stitch new tables together with old tables via JOINs, this sort of thing can only be done in Mongo by doing discrete queries and stitching the data together in memory.  What you'll ultimately want to do is change the way your documents look, which often means subbing the type of data you store in specific fields -- this can be incredibly problematic for a system that doesn't allow for change at the same cadence and the database.  You should also be prepared to "sunset" some data as your structure changes. 

Pro: You don't like being a DBA

Mongo is incredibly easy to setup and administer.  Even doing things like sharding and replicating is a snap.  Additionally, Mongo's language of record is JavaScript, something that most of us are comfortable with.  There are a few domain-specific idiosyncrasies to learn, but beyond that, your confidence will build quickly.  You can also back your data up with ease.  I say this with a minor caveat: beware the "journal," especially if you're using things like database references.  Journal space can get absolutely enormous, and if your hard drive space is at a premium, this can bite you.

Con: You need to aggregate/summarize data

Don't be too alarmed.  Mongo has all of the summary functions you'd expect.  But prepare to have a bunch of JavaScript objects with nested objects expressing how you want to summarize your data.  If you're used to a nice, compact SQL statement followed by a GROUP BY, you're in for a rude awakening.  Once you start messing around with the aggregate(..) function, you'll gain a degree of familiarity.  This may or may not stop you from holding your nose as you write the code though.  

Pro: You aren't afraid of indexing for performance

When you're starting with Mongo on a small scale, you'll be suitably impressed with its performance.  Once you're dealing with tens or hundreds of millions of documents, you will notice a marked degradation in query performance.  The beauty of Mongo is that you can generally throw an index in and improve your performance to a spellbinding degree.  A protip is to use dex, a tool to automatically determine which fields could be indexed to increase your performance. 

Misc

There are a few tools you can use that will make your life incredibly easy.  I'm going to assume that you, like me, are a sane person and use a Mac in your development. 

Robomongo - My favorite Mongo querying tool.  The UI isn't much to look at, but it performs beautifully and is very query-friendly.  

MongoHub -  Another visual Mongo tool.  It brings nice UX to the table for certain operation but generally performs a bit more sluggishly and crashes in weird situations. 

Mongo Prefpane - A nice visual way to control your local MongoDB.  Another awesome aspect of Mongo is that it can be run locally with very little baggage.  You can also import and export data from a production or staging environment with ease.

Sunday, May 10, 2015

Jumping into Swift/iOS

I'd say that one of the most compelling things for lifetime software developers like me is the realm of mobile development.  Most of us spend the majority of our waking hours staring into the screens of our beloved mobile devices.  To deliver an app that would penetrate this world would be a huge contribution to this world, a way to get some great acclaim, and if you're very lucky, make a few bucks along the way. 

I've only just gotten started, but I figured I could give a look into some of the pitfalls a beginner might encounter.  The first, and perhaps most important, thing to consider is that you need to cough up $99 for the privilege of writing code on an iDevice.  This seems a bit asinine, but I guess it is what it is.  Everybody wants a piece of the pie in the Apple world, and they can get away with charging for the privilege of developing code for their ecosystem. 

The next thing to consider is the nature of that ecosystem.  I'd say the biggest hurdle to getting me into iOS development was the language.  Objective-C was (is) an unwieldy leviathan loaded with strange details and syntactic qualms.  Once i made the jump to Java, I never found myself missing the pointers and explicit references of yore.  Every time I'd get started on an app, I'd start writing code and end up so frustrated that I'd just abandon my project and move onto something less productive but more gratifying.  

Swift has really changed all of that.  It looks a lot like JavaScript or Python and does away with the old fashioned ceremony that plagued Objective-C.  The really good news is that Apple is reportedly stepping away from Objective-C completely.  This means that the entire ecosystem will be accessed via a shiny new language.  

Not all of this is wine and roses, though.  My first move was to procure a copy of AppCode, JetBrains' answer to the pitfalls of writing Objective-C (and Swift).  As I've said many times in the past, JetBrains is really the premier shop when it comes to delivering tools that make programming pleasant.  The refactoring is fast and seamless, and the UI is very intuitive.  My past experience with XCode, which is the stock Apple IDE, was a lot less friendly than I'd like.  Much like Objective-C, it feels like something from the '90s.  That or there are just a lot of assumptions built in to tailor to a long-suffering development community.  Either way, I figured this would all change with the installation of AppCode. 

There's good news and bad news to this.  The good news is that AppCode works just like IntelliJ.  It's a great tool  as one would expect.  There's the full complement of refactoring tools and the lovely Darcula color theme.  It's also got an integrated UI composer, which is relatively new.  The good news, unfortunately, sort of ends there.  I'm guessing this is just a side-effect of Apple having a "closed" ecosystem, but AppCode can't function without XCode.  My initial take is that it taps into it for things like the UI composer and the other settings that it needs to operate.  

Where things start to get cool, however, is when you can have a barebones app running on your phone within seconds.  To get there, however, you have to register your device on Apple's developer site.  And then you need to refresh your XCode configuration.  Then you're good to go.  

I'll do my best to document my (mis)adventures as I get my first app out into the App Store.  The app is a simple thing that will allow bee-minded folks (like yours truly) to document where bees are seen feeding.  All it will really do is upload a photo and allow fellow bee-minded folk to view the sort of plants that bees seem to like.  It's not very sexy, but it's an idea. 

I do apologize for my long absence.  It's been a pretty eventful few months, filled with more Groovy shenanigans, a lot of fun with Mongo and some nodeJS too.  I'll try to get into some of those exciting topics soon. 

Sunday, February 1, 2015

The Holidays are Over



Well, the holidays as we know them are officially over.  Somebody in Scottsdale is sweeping up red, white and blue confetti and many people are sobbing into their beers in Seattle.  With that, we enter the cold months of winter.  The months where football-obsessed software guys like me can finally achieve a sense of clarity and take up the pet projects that got no love during the nail-biting weekends. 

A few things to stay tuned for -- a look at the advantages of AngularJS and single-page applications (SPAs to the initiated).  

And (probably) more excitingly, a look at mobile development as I undertake a few apps that have been clanging around in my head for some months.  As well as a quick glance at the Swift language -- something that's actually got me excited about writing an app for iOS. 

Also, after a few months of working with a new team in my primary development endeavors, I have some thoughts on pragmatic automated testing... be it unit, integration, functional or otherwise.  

Wednesday, December 3, 2014

Things are getting spocky

As another year passes, I find myself privileged to say that I've been working in "agile" (we actually called it XP or eXtreme Programming, back then) since the dawn of the 21st century.  It'll be about 15 years as the new year dawns.  I was a part of an upstart team of fun and quirky dudes at a small startup, flush with capital.  If you can believe it, our angle was mobile development.  We got to work with Motorola's first GPS phone prototypes, and their Java MIDP-compliant VMs.  It was equal parts exciting and frustrating. 

Along with pair programming, using a cutting-edge IDE called "IntelliJ" and using a continuous integration server, we adhered strictly to test-driven development, using JUnit.  This was a fairly kooky practice at the time, and in an era predating things like annotations, unit tests had to extend from a base JUnit class.  

As the years continued to roll by, I stood by the practice of TDD and rejoiced at the introduction of new libraries and techniques.  Mocking out dependencies was a revelation, and I thought EasyMock was the bee's knees.  Then Mockito came along and blew the lid off of everything. 

For a good few years, I felt I'd plateaued -- writing what I thought were fantastic tests, laden with @Mock annotations and builder pattern-style callouts for the behavior I wanted to provide.  Not to mention the anonymous inner classes for flexible "matchers."  I stood dutifully by my practice of hammering out long and elaborate tests, many of which were insanely difficult to read at the end of it.  "At least I have regression protection," I would tell myself, and sneer at my fellows that eschewed testing. 

It wasn't until a couple of years ago that a new technology came around and turned my understanding of testing completely upside down.  This coincided with my first full-on brush with the Groovy language. 

This revelation was spock.  Of all of the technologies, libraries, techniques and platforms I've come across in the last several years, I'd call spock the best and most interesting one.  Spock is perfectly representative of what makes Groovy a great language.  It's also learned from the things that made testing in a world of dependency injection so painful.  

Rather than using something like JUnit and picking some sort of a mocking library, you get all of this with spock.  It has its own powerful mocking concept, taking full advantage of Groovy's proxying capabilities.  It also makes things like mocking out static methods a snap.  
The features and functionalities of spock aren't its greatest virtues, however.  What makes spock great is how expressive it is.  In case you're not familiar, this is what a spock test looks like:

def "Calls the payment service and returns the result"() {
  setup:
  PaymentController controller = new PaymentController()
  controller.paymentService = Mock(PaymentService)

  when:
  PaymentResult result = controller.pay("MyAccount", 55.50)

  then:
  1 * controller.paymentService.acceptPayment("MyAccount", 55.50) >> new PaymentResult(accepted: true)
  result.accepted
}

What you're seeing here is something that reads like prose.  And the beauty of it is that verification and behavior are captured in a single line.  Using the rather old school concept of labels, Spock is able to skip from block to block in the method.  No assertion statements are required in the verification block. 

Do you remember how this looked with JUnit? 

You would have to spell out the behavior before your method call with a chained statement, looking something like:

when(controller.pay(eq("MyAccount"), eq(55.50))).thenReturn(new PaymentResult())

Further down the line, you would have to verify the behavior

verify(controller).pay( ... ) 

And you'd have to call out the matching parameters once again.  If you're disciplined enough, you can keep your JUnit pretty tight.  But frankly, when I've had to work with legacy code in my post-spock career, I've found myself trying to cram everything into the BDD-style given/when/then flow.  

What surprises me about spock is that it hasn't taken off at an even greater speed.  I overheard some coworkers from a different project talking about spock today, and both of them were clearly unfamiliar with it.  I'll admit that I was reticent about embracing spock at first, but even then I recognized how readable and succinct the tests were.

Even if you're saddled with writing Java as your production code, I highly recommend tapping into spock as your testing platform.  There are a few gotchas (Mock/GroovyMock/Spy/GroovySpy) when you're strictly using Java, but it's well worth it.  

Remember, a good test will generally result in good, tight code. 

Thursday, November 20, 2014

Going the other way

As my career in software has trundled along, it's become increasingly important to me to try to give back to the community that has given me so much over the years.  From a sheer numbers perspective, most developers simply enjoy the largesse that the "givers" put forth.  Given, many of these contributors are paid to put these things out there as part of their day jobs, but the giving and sharing nature of the software community is one of the more remarkable -- and less discussed -- facets of the profession.  

My resolution for the last couple of years has been to share any code I write that could possibly be of use (and, of course, isn't proprietary) with the community.  The hope is that one of those tidbits can help somebody solve something, and maybe start a spark that can get something widespread going.  

As a part of this, I've been doing a bit of (for lack of a better word) "backsliding" to writing Java code.  As an ardent supporter of the Groovy language (and most other JVM languages), I rarely use the "mother language" to complete my day-to-day tasks.  But one thing I've realized as I've tried to get involved with the JVM-based community at large is that not everybody has this luxury.  Or indeed this opinion.  As much as I'd love to write all of my library code in Groovy, I realize that you're asking a little something of your users if you force them to include Groovy and its associated libraries as one of their dependencies.  Taking the long way around with Java results in a much cleaner set of dependencies for the end user.  

A library I offered recently was a Java implementation of the wildly-complicated "National Retail Federation 4-5-4 Calendar."  When I wrote it initially, it took advantage of Groovy's date shortcuts, with things like: 

Date aWeekLater = date + 6

There were a few bumps in the road with Map interactions, but the conversion over to Java was pretty painless.  To be honest, it was almost comforting in a way, like reminiscing about the old days with a friend.  I used to dutifully rattle off the long, repetitive lines (with the requisite semicolon at the end) and have that intuition of where I had to stick that cast statement to make things compile.  

The other plus is that you can use Spock to test the code, since it's all going to be bytecode anyway.  The library user can simply ignore the unit tests. 

I had a small sense of cockiness as I proceeded to my next conversion task (all of my code starts out as Groovy).  As part of a reporting suite I built, I put together a Java wrapper for Adobe's absolutely atrocious SiteCatalyst API.  I did my best to unfurl the insanely complex rat's nest of JSON that they return.  It was easy enough with Groovy -- JsonSlurper and JsonBuilder could marshal and unmarshal with the greatest of ease.  I decided it was time to unleash to the world, since I no longer had use for it, and also invested a pretty large amount of time figuring out how to get meaningful data out of Adobe's analytics vault.  

This where I started to appreciate the strength of Groovy.  With the single groovy-all dependency, you get everything.  Fantastic JSON support, and all of the wonderful shorthand for map access.  The work on this conversion is still in progress, but here's an example of where you can really save yourself with Groovy: 

    def requestStructure = [reportDescription: [
            reportSuiteID  : omnitureReport.reportSuiteID,
            dateFrom       : omnitureReport.dateFrom.format(OMNITURE_REPORT_DATE_FORMAT),
            dateTo         : omnitureReport.dateTo.format(OMNITURE_REPORT_DATE_FORMAT),
            metrics        : omnitureReport.metrics.
                    collectAll {[id: it.id, segments: it.segmentId ? [[id: it.segmentId]] : null]},
            sortBy         : omnitureReport.sortBy,
            dateGranularity: omnitureReport.granularity?.value(),
            elements       : omnitureReport.elements?.collectAll {
              [id            : it.id,
               top           : it.limit == -1 ? omnitureReport.limit : it.limit,
               search        : getSearchKeywords(it.elementTypeAndKeywordFilter),
               classification: it.classification ?: "",
               startingWith  : it.startingWith,
              ]
            },
            segments       : omnitureReport.segmentIds ? omnitureReport.segmentIds.collect{[id:it]} : null
    ]]
Nothing complicated, right?  In one statement, I'm building up the structure of a report with a handful of succinct expressions.  Let's just take a peek at how we'd do this in Java:

DateFormat dateFormat = new SimpleDateFormat(OMNITURE_REPORT_DATE_FORMAT);
Map<Map<String, ?>> requestStructure = new HashMap<>();
Map<String, ?> reportDescription = new HashMap<>();
requestStructure.put("reportDescription", reportDescription);
reportDescription.put("reportSuiteID", omnitureReport.getReportSuiteID());
reportDescription.put("dateFrom", dateFormat.format(omnitureReport.getDateFrom());

This is all pretty doable, but where the rails really come off are on some of the compound statements:

omnitureReport.metrics.collectAll { [id: it.id, segments: segmentId? [[id: it.segmentId]] : null ]}

How does this look in Java? I'd start by busting it out into a method: 

private List<Map<String, ?>> getMetrics(List<OmnitureRequestMetrics> metricsIn) {
  List<Map<String, ?>> result = new ArrayList<>();
  for (OmnitureRequestMetric metric: metricsIn) {
    Map<String, ?> row = new HashMap<>();
    result.add(row);
    row.put("id", metric.getId());
    if (metric.segmentId != null) {
      row.put("segments", Collections.singletonList(Collections.singletonMap("id", metric.getSegmentId()));
    } else {
      row.put("segments", Collections.EMPTY_MAP);
    }
  }
}

And frankly, it only gets worse from here.  

Thankfully, there are some wonderful JSON libraries out there, namely Jackson, which makes marshaling and unmarshaling pretty simple.  Not as simple as in Groovy, I'd dare say, but at least palatable. 

I suppose I should go and keep working on this conversion task... 

Thursday, November 6, 2014

... And now for something completely different

Like so many others in the IT community, I can directly trace my path into IT back to gaming.  I was 5 years old when my parents sprung on an 8086 PC clone.  It sounded like a vacuum cleaner when it booted up.  The dulcet tones of the boot sequence are hardwired into my brain even today.  First, a RAM check, then the hard drive would spin up and give a gratifying "BEEP-BEEP."  I'd say that my old man was actually quite a trailblazer -- he had a primitive modem in this behemoth and dialed in to his college's e-mail system on occasion.  None of that mattered to me, however (not until a while later anyway).  What I loved the most about that system were the games.  Much to my delight, the computer came with a pretty extensive array of games: a healthy combination of bootable 5.25" floppies and games installed on the hard drive. 

I cut my teeth on Moon Bugs, Bouncing Babies, J-Bird, Bushido, BurgerTime and a bunch of other ones that aren't even worth mentioning.  As the years went on, I started to feel crippled by the constraints of our old metal-clad behemoth.  You see, the main purpose of the PC was word processing.  For both my academic father and my aspiring siblings and me in our school projects.  I couldn't cajole my parents into fitting it with the hardware necessary to interface with a joystick, and it was equipped with a CGA monitor: a 4-color affair that was quickly eclipsed by EGA (16 colors) and VGA soon thereafter.  I clearly recall looking at software boxes at Radio Shack and seeing "Joystick Required," or "EGA/VGA" and feeling my heart sink, knowing that I was missing out on yet another game.  A lot of my friends were getting newer machines, equipped with the ubiquitous joystick hardware, and some even with the mind-blowing SoundBlaster card.  With this hardware, games had soundtracks and effects that were nothing short of staggering.  Coming from a machine with a "PC Speaker," this severely limited the possibilities.  Most game publishers didn't push the envelope much.  But occasionally, you'd see some brilliance on the part of the developers.  Two that come to mind are Where in Time is Carmen Sandiego? and the unlikely and addictive Street Fighting Man.

Like so many other families, my folks eventually allowed us to modernize, and we got a Pentium-powered Gateway machine and entered the "cyber age."  At this point, my interest in games really started to wane.  Development became much more interesting to me, and as first-person shooters became de rigeur, I bowed out from gaming essentially for good.  In later years, I would go to "guys' weekends" and be the only one that didn't want to get in on a networked game of Halo.  

My interest in games didn't really spark up again until the faux-musical games exploded in popularity.  I was a Guitar Hero phenom that could devastate nearly anybody.  And a few of the arcade-style games on the Wii would hold my attention.  My Wii, though, saw most of its action in "Virtual Console" mode, where I could play my old 8-bit favorites.  Blades of Steel was a frequent go-to, as was Punch Out. 

Mind you, this was YEARS before the iPhone.  I was shredding up the Guitar Hero with a wonderfully durable Nokia dumbphone in my pocket -- and I was happy about it.  When smartphones DID come around, I think it revealed to us what really worked with games.  

You see, I've noticed that a lot of iOS/Android games that have exploded in popularity of late have really leveraged that old 8-bit style.  Case in point -- Flappy Bird.  This brutally simplistic game came as close to plagiarizing NES graphics as possible: the pipes, the fishy-looking bird, the bright and simple sounds.  There's another game that I enjoyed playing for a while called The Firm.  It reminds me a lot of games I used to play on the old 8086.  

This got me to thinking.  What was the major turning point in gaming?  Where did it go wrong?  At least from the perspective of a person like me?  I really pinpoint it to the era of the affordable home PC.  I look back fondly to the Sunday paper inserts from Best Buy and Circuit City, toting ridiculously cheap Packard Bell systems with 15" CRT monitors flanked by cheap speakers.  Even with Windows 3.1 as an operating system, game publishers started to outkick their coverage.  Games like Myst really heralded the end for simpleton gamers like me.  I liked things simple and easy to learn.  Something that was minimal and insanely difficult to master.  I got a lot of mileage out of some Disney-licensed titles as a kid: Matterhorn Screamer and The Chase On Tom Sawyer's Island, the latter being a fanciful Pacman ripoff.  

Games like these didn't have ridiculous resolution capabilities and required very visible pixels to render their sprites.  This look was always very comforting to me.  And in a way, it's great to see it coming back with games like Flappy Bird and the Firm.  But what it really boils down to for me is simplicity in play.  I've really enjoyed the Plants vs Zombies games, and whiled away many hours on Angry Birds until they started to introduce complexities like gravity that overcomplicated things. 

Recently, I've been doing a lot of exploring of Abandonware and developing ideas for a game that I could develop and release to the mobile world.  If you're a Mac user like me, I highly recommend downloading Boxer.  It's a DOS emulator that is extremely well-acquitted when it comes to playing old games.  Certain games require some monkeying with processing power, and you can actually sandbag things pretty well to get them under control with cues from the program of where you're at with processing power (XT, 386, 486, etc).  It's really a lovely program. 

I also recommend doing a google search for "abandonware."  You'll find that just about every game from your childhood is out there for the taking.  You'll be amazed at how well these emulators can recreate the experience.