Showing posts with label Software Engineering. Show all posts
Showing posts with label Software Engineering. Show all posts

Tuesday, May 20, 2014

Last Mile #6 – Start Putting in Graphics/Icons ASAP

When you build your application, don’t ignore the icons and graphics.  You may need some specialized graphics or icons for your application but in a lot of cases you just need some simple graphics for a button or similar.  You may be tempted to just use the same icon throughout the app  imagewith the idea to come back later and add some graphics all at ones.  I’ve found it’s better just to take a two-three minute detour to go ahead and find an applicable graphic add it to the app, see how it looks/feels as you use the app and add additional features and potentially replace it if necessary. 

One place I’ve found a great source of professional icons is from Syncfusion Metro Studio, what I like about their icons is that they have an app where you can search on icons by category and name.  When you find one you like you can customize the color, size and border.  They also go really well with a metro application.

-twb

Last Mile Tip #5 – Be Realistic

Ok, folks, this is ALWAYS they one the gets me when building a new application (or for that matter doing chores around the house).  A couple years ago, I started a weekend project to remodel our bathroom.  Originally I was disappointed that one of the fixtures I wanted to instimageall wasn’t available for a week, well it turned out I wasn’t ready for that fixture for about two months.  The project was much bigger than I had though of, I only pictured the rough work that needed to be done and didn’t think about any of the detail work or for that matter anything going wrong. 

You may have a great idea for an app you want to right, but be realistic.  If you have your unity license and setout to create the next Halo or Call of Duty app, well I would ask you to think twice.  Does that mean you shouldn’t sit down at your computer, open VS.NET and and start hacking away at something like that?  Maybe not, there are a lot of projects I work on that I  enter into with the knowledge that I’m not going to ship the app.  There are two primary reasons I do this.  First off is programming and solving problems is fun, second off and more importantly I consider this type of work “practice”.  When I commit to do something for a client that I’m going to get paid for, I don’t expect them to pay me to do “research” I want them to pay me to do “development”.  Just as with anything the more you practice the better you get, I just don’t like practicing on software that will go into production, so I try to keep my goals on software I ship realistic while I shoot for the moon on my fun stuff.

-twb

Sunday, May 4, 2014

Last Mile Quick Tips #4 – Keep Your Code Clean

As your creating your masterpiece take care to ensure that you keep your code clean.  One ByteMaster’s golden rules of software development imageis the only code that is guaranteed to not cause you problems in the long run is code that doesn’t exists.  What exactly does this mean?  use some basic principles, like DRY, Do not Repeat Yourself, refactor your code often, put some thought into your naming conventions, rather than commenting out unused code, just remove it.  If you do need to comment it out for some reason, add some comments as to why it’s commented out.  Although a personal preference, I try to keep my methods under about 20 lines, sometimes as little as 3-5 line.  Pick a standard naming coding convention and keep it consistent across your application.  One of my pet-peeves – if you are helping someone on an application, and they use a different naming convention, a you just know that yours is superior *cough* *cough*, swallow your pride and just following the app’s naming convention. 

Of course these are just touching on some of the basics, but there is a tendency when creating apps to think of them as something you can just hack together and publish, rather than something you need to put some thought into and engineer them properly.  Once you get to the final phase of your project if you don’t keep your code clean, you’ll be spending more time then you want just fighting with stupid stuff, tracking down edge cases and generally not having much fun.

-twb

Thursday, March 20, 2014

Last Mile Tip #3 – Beware of the Boring Stuff

You know how it is when you are building your application, you have the key features you need to build to make your app come to life.  In a lot of cases these key features are something new and challenging.  If you’re like most developers you are motivated by doing something new and challenging so you start on those parts of the app.  Then after you put a little time into it, things start coming together, problems start getting solved.but as you do that, there are a number of small less exciting things that need to be done to complete the app.  You know how to do it, or it really doesn’t seem that exciting so you say to yourself, yeah, I know how to do that, once I get the primary functionality in the app working I’ll come back and add in that “forgotten password” feature or that regular expression on the email address feature, or something like that.  Sound familiar?

In a lot of cases, you get the primary functionality and think you are ready to ship and then all those little extra boring tasks need to be completed.  Hopefully you read my earlier post on making lists, if you do this as you go, once you get to this point you won’t be fooling yourself in thinking, just one more thing and I can submit, you’ll have a relatively complete list of work and should be able to gauge the effort ahead of you.  As I also mentioned in that earlier post, sometimes when you come across that sort of thing, you should just shift gears a little and knock out some of the smaller items.  It may not seem exciting at the time, but will dramatically shorten your final to-do list.  Another thing that I found helpful is to start reusing assets from other projects, ideally this would be in the form of a common library you use among all your mobile projects, but even just the cut-and-paste refactoring method is better than redeveloping the wheel each time.  Also where possible if you can use an existing application frameworks they may already have dealt with a considerable number of those boring yet necessary tasks.

Last but not least, just being aware of the fact that as a typical developer you are probably deferring all the “boring” tedious development tasks as you go might be enough to change your behavior and make your last mile go a little quicker. 

-twb

Saturday, March 15, 2014

Last Mile Tip #2 – Start Using Your App as Soon as Possible

No, I don’t mean testing on your emulator.  I mean use your app in the real world as a real user would.  In software engineering terms this concept is called “Dog-Fooding”.

This is one of my top big tips that I have and is also related to something else I’ve learned about creating apps, if you are just creating an app you aren’t going to be using in your day-to-day activities or a game you wouldn’t enjoy playing, you may want to consider the premise of your app and try to find something that is a better match. 

So assuming it’s an app you will indeed use, or a game you enjoy playing, as soon as reasonably possible get it off your development machine and onto your phone or tablet you use on a daily basis and USE THE APP!  I can’t stress this enough, once you start using the app, you’ll find little things that don’t really make sense or are obviously broken but you just never come across during development.  You’ll have to trust me on this one, but for a fitness app I’m building right now, I’m using it every time I get exercise and it’s really surprising how quickly I’m moving through the last mile.

-twb

Last Mile Tips

We have a very exciting event coming this spring for Windows Phone that I’ll share more about in the future.  However in preparation for this, I’m going to be compiling and releasing a set of “Last Mile Tips” to help you release your Windows Phone or Windows Store Apps quicker and easier.

If you’ve ever written any sort of mobile application, you know that it’s pretty easy to get to the 90% mark of being done, right?  Isn’t it?  That’s the fun part where you get stuff working and the app starts to come alive.  During that 90% you come across a number of things that are just easy and will get done relatively quickly so you just skip them and continue on with the fun part of making progress and making your app come alive.

Then what happens?  You hit the last 10% and BOOM!  Death by a thousand cuts, you spend the next 90% of your time on the project finishing up those “last simple and easy things”.  If this has happened to you, welcome to the club, you’re not alone!

I certainly don’t have all the answers here to tame the last mile, but I do have a number of things that have worked.  Join me over the next few months as I share my experience as well as things I’m learning as I make a concerted to solve this last mile problem.

As we go forward, if you have any tips or tricks that you use, just add them as a comment and I might just add them as post (giving you credit of course).

Stay tuned, things are about to get exciting!

-twb

Wednesday, October 21, 2009

Software Development Moment of Clarity

I believe the following is accurate for developing 95% of business applications:

  1. People buy software to solve problems, that can be making their life easier, making money or providing pleasure (don’t read too much in to that =D)

  2. Features enable solutions to problems.

  3. When we write software, we build features.

  4. With the right level of abstraction there is a common and finite set of features to be implemented in code.

  5. Applications should be built by tailoring features to solve a user problem.

  6. If tailoring features has to be done by writing code, so be it, but this is very costly in terms of time and money.

  7. It’s preferable to have this done via configuration.

-ec

Friday, August 21, 2009

Another Perspective on M-V-VM

I was tasked by a client to port a Windows Mobile application to run on many different platforms to include the iPhone, Palm Pre, Android, BlackBerry as well as desktop browsers.  To make this more interesting where the platform allows it, the application needed to run in an offline mode. 

They wanted me to look at building this on top of Google Gears to take advantage of its offline capabilities to include SQLite a local server to serve up web pages without an internet connection.  At first I was somewhat skeptical of the approach but once I started learning about the upcoming HTML 5.0 standards and the services it provided this approach seemed more and more practical.

So what does this have to do with Model View View Model?

This was a non-trivial application of approximately 120 screens and 80 or so tables so this wasn’t something I could just “hack” together. I wanted to implement this using some sort of pattern.  My basic requirement was that I wanted the simplest possible view (remember this needed to run on many different devices/platforms with different capabilities) so creating something where we can inject some HTML code that represents the view into the ViewModel and the ViewModel would take care of all the interactions and states of the control.  This way we can have a minimalist view for simplistic browsers such as Opera Mini that run on the BlackBerry, a decent good looking UI that will run on the iPhone, Palm Pre and Android and a full-featured UI that will run on the desktop.  The only thing that changes will be the HTML template.

There are some frameworks for M-V-VM that run on the desktop, some even run in Siliverlight.  My need was to build something that ran in the browser with JavaScript and HTML.  At this point I think the churn in my frameworks has pretty much died down and I can write what I learned and discuss my approach.

Before I get into the M-V-VM portion, let me list the 3rd party components that were used:

  1. JQuery – Used to manipulate the DOM
  2. Microsoft ASP.NET Ajax Library
  3. A modified version of Jay Kimble’s Class Compiler (simpler syntax for creating JavaScript classes)

Here’s a 50K ft level view of the interaction between the areas of the frameworksimage

Model

The model is used to encapsulate the idea of access to the data store.  My data access strategy is an interface that provides the mechanisms for CRUD.  This interface has been implemented on a Google Gears SQLite database, Safari/WebKit HTML 5.0 SQLite database as well as an AJAX connection that get’s it’s data from the server.  The models are fairly traditional in that they include all of the non-trivial business logic.

View

The views are built in HTML that rely heavily on CSS.  In addition we use attributes to describe how the View-Model should create and render the controls.  For example a drop down lists might be described as follows

<div id=’Module_View’>
  <div id=’ddlStatus’ TextField=’description’ ValueField=’id’
        DataValueField=’StatusId’ action=’statusChanged’>
    <label>Status</label>
  </div>
</div>

As you can see we are using HTML attributes to describe how the drop down should be populated as well as the action that should be invoked when the status changes.

Then for different templates we can create different views that our engine can pickup based upon browser type:

<div id=’Module_View_iPhone’>
  <div id=’ddlStatus’ TextField=’description’ ValueField=’id’
        DataValueField=’StatusId’ action=’statusChanged’>
    <label>Status</label>
  </div>
</div>

So far this has been working great, I haven’t had to include any JavaScript within my views.  All the JavaScript has been “attached” via JQuery in the View Models and primarily within the JavaScript controls.  I’ve also been able to do the vast majority of look-and-feel type of stuff in CSS.

View Model

When the html template as specified for the active skin is “injected” into the View-Model, the View-Model will create instances of JavaScript classes that encapsulate the idea of controls rendered properly on different platforms. 

this._ddlStatus = new Ctrls.DropDownList($(‘#ddlStatus’),$(‘#Module_View’));

So the ViewModel will create a new DropDownList instance after we use JQuery to find this html template and specification for the control.  The instance will then be ready to be data-bound and rendered on the form.  Note this is all happening in JavaScript within the browser.

In addition to creating fields from the HTML control templates our ViewModel is responsible for binding the data to those controls.  Each ViewModel requires a Bind method that expects a Model of the data that corresponds to that form.  It is the responsibility of the view model to gather any additional data required to populate the view.  This includes things like data sets for populating drop down lists.  It is also the responsibility of the ViewModel to manage state of the data on the view and do two-way binding.  There are two additional methods defined in our interface for the view, Validate and Save.  I like to think of the workings of the ViewModel as the private interface and code used to interact with the View.  The rest of the application does not directly act upon the ViewModel.  The rest of the application acts on the view and ViewModel by going through a Controller.

Controller

Here is where my implementation differs slightly from the traditional M-V-VM implementation.  For the way I’m building the application a controller seems to solve a number of problems and provides and fairly high-level interface when interacting with the View and ViewModel.  I would consider the Controller as a public interface to the View.   Each Controller that is implemented defines the following methods (note: bold methods are defined in an interface and must be present):

  1. Show(args) – Shows the view, args are view dependent but usually contain the ID for the primary data to be displayed as well any secondary information.
  2. Restore(launchArgs, returnArgs) – If this controller launches a child view and we return back to the calling controller.  The original calling args and optionally restoring args can be provided.
  3. Save() – If the frameworks requests that the current view data be persisted to  storage.
  4. SaveAndClose(callback) – If the frameworks requests the current view data be persisted to storage and the view closed.  If the ViewModel does not have valid data, the callback will return false and the form must not be closed.
  5. Cancel(callback) – Abort any changes, if the ViewModel can not be closed then the callback will return false and the form must not be closed.
  6. xxxxxAction – These are what are considered additional actions that can be invoked for the controller and are controller dependent.  These can either be generated by the View’s controls as in the case for a drop down list selection changing or a button press or come from the outside world as in a change of status of connectivity.  This also supports a fairly robust model for doing automated testing.

Very little code exists within the controller, the controller basically either passes on data/calls to the ViewModel or invokes business logic in the model and tells the UI to re-bind.

So in summary I look at the Controller as a high-level public interface to interact with the View through the private interface on the ViewModel.

ViewDispatcher

Everything in the application get’s routed through the ViewDispatcher.  The ViewDispatcher also runs in the browser via JavaScript.

The ViewDispatcher has methods such as:

      • ShowView(“[MODULE_NAME]”,”[VIEW_NAME]”,args (optional) ) – Shows a specific view within a specific module.  The ViewDispatcher is responsible for finding the view template in the ViewRepository, creating or loading and instance of the controller, cleaning up the previous view template.
      • PopView(return args (optional)) – Take the calling view off of a “return-stack” and call the Restore() method on the restored controller.
      • HandleAction(“[ACTION_NAME]”,args (optional)) – On the active controller, invoke a method with the name [ACTION_NAME]Action();
      • Save() – Call the save method on the active controller
      • SaveAndClose(returnArgs (optional)) – Call the SaveAndClose method on the active controller, if the callback from the controller returns true, then call PopView() with returnArgs if present.
      • Cancel() – Calls the Cancel method on the active controller.  If the callback from the controller returns true, then call PopView without any return arguments.

ViewRepository

At any one time a view may be active in the UI.  The ViewRepository is the complete set of views that may be called upon to active via the ViewDispatcher.  Once the ViewDispatcher has decided that view is no longer needed (usually replaced by a different one) the view will be placed back in the ViewRepository so it can be called upon again to be active.

Summary

So in summary at a high-level here are the different components that make up my frameworks and their responsibilities:

Models
  1. Models are fairly traditional, getters and setters for fields that make up the data in our system.
  2. Additional methods to handle business logic (both class and instance methods)
  3. 1:1 relationship between the model and database table
  4. Data access goes through an implementation of an interface.  The implementations that we currently have defined are:
    1. Google Gears SQLite (synchronous)
    2. Safari/WebKit HTML 5.0 SQLite (asynchronous)
    3. AJAX Service for devices not supporting (asynchronous) 
  5. Due to the nature of Safari and AJAX all data access (and any calls that at some point need to access data) are done asynchronously via call backs.
View
  1. Defines the presentation of the forms and data to the user
  2. Contains zero behaviors or JavaScript
  3. Presentation attributes are defined in CSS
  4. Uses attributes to be extracted at run-time with JQuery to define additional behaviors
  5. Are stored in the ViewRepository
  6. Are populated into the Active content region by the ViewDispatcher
  7. Are stored back into the ViewRepository by the ViewDispatcher
  8. Use the id format of [MODULE]_[VIEW] and optionally [MODULE]_[VIEW]_[SKIN]
  9. Does not support WYSIWYG
ViewModel
  1. Think of the ViewModel as the private interface to the view.
  2. The View is injected into the ViewModel
  3. Instance variables that correspond to the controls on the form are created from html tags and attributes
  4. Exposes a method named Bind(model) that has as it’s argument an instance of the model used to populate the view.
  5. Handles two way data binding between the model and view.
  6. Is responsible for pulling any additional data required to populate the view.  This could be lists to populate drop down lists or similar
  7. Contains all logic for managing the relationship between the model and the view.
  8. Handles simple interaction of controls, based upon state another control should be enabled/disabled
  9. Provides validation services, confirms that both the content of the view and the model are valid
Controller
  1. This is where my approach is varies from the standard model
  2. Think of the controller as the public interface for the view and the view model
  3. Provides methods named Show, Restore Save, SaveAndClose and Cancel (see above for more details)
  4. Also has methods named [ACTION]Action where these are the actions that should be invoked on the controller.  This is how external forces act upon the controller.
  5. This makes testing very simple
ViewDispatcher
  1. ViewDispatcher is implemented as a singleton
  2. The ViewDispatcher launches and displays views ShowView([MODULE],[VIEW],args)All interactions with controllers and thus with the ViewModel and View go through
  3. The ViewDispatcher through a HandleAction([ACTIONNAME]) method
  4. There is exactly one active controller at any one time.
  5. The ViewDispatcher has access to the ViewModel and ultimately the View through the active controller.

-ec

Thursday, June 18, 2009

Not all Code is Created Equally (Nor should it be)

Recently I built a stand-alone component that extends the ASP.NET FileUpload control to save to the Amazon S3 web service using method calls as simple as the FileUpload’s method SaveAs(). As I was writing the code for this component, I slipped into a different mode of development where I was thinking about all the extremely rare, 1 in 100,000 weird edge cases that people using this component might run into. The primary reason for this was that this is something that was intended on being released into the wild and I just wanted to release it and forget it.  At this point, you may be saying, hmmm…this guy is a hack if he doesn’t always consider the “weird edge cases” that might occur. I beg to differ, writing really solid and truly 100% industrial strength code is extremely difficult and time consuming. To get to a point where your code is 99.99% perfect probably takes a couple of orders of magnitude more time and effort than to get your code to 99% perfection. The final usage and intended audience for the S3FileUpload component is completely different then the majority of the code we write for our business apps.

In most business applications the level of our software architectures and canned components should be to a point where our role is to write some sort of interface (UI or Service) to populate our business objects, validate the data is correct in that business object, possibly perform some business logic on that data and persist it to the database. Of course there are all sorts of new fangled patterns that can be followed to make this happen, but in the core essence that’s for the most part what they are doing.

Once we accept the majority of the code we write is never going to be used in navigational systems of the space shuttle, or even the base class library for the .NET framework, we can get on with business of establishing the right level of software quality for the problem we are attempting to solve. If you’re are thinking at this point, ok good, the way I’m putting all my business logic in the UI is an acceptable level of quality, this article assumes a baseline of experience, knowledge and quality practices so come back after you have a few more years and/or systems under your belt.

There are different concepts that need to be evaluated when choosing the “level of software quality”

What happens when your bugs sneak past QA?

  • Are you building some data entry screens that get used by two people once a quarter to update some values?  If this works correctly 95% of the time, you may have a failure once every few years or so.
  • How easy is it for your users to know that there is a failure?  Does it crash?  Does it save the wrong value?
  • What happens when a wrong value gets saved?  Do you just need to renter the value and all is well? 
  • Do you have to run a simple process that reprocesses data that takes two minutes? Does it take two hours?
  • Does this wrong value impact the pay of one or two employees?  Maybe it impacts one or two thousand?  How much work is it to issue new pay checks?
  • Is this wrong value impacting the commission charged on selling securities where one or two days using the wrong value costs the company millions of dollars?

Obviously making sure that a single value is entered, validated and saved correctly sounds like a simple thing right?  You can always get that one right. 

How much work is it to craft a 100% perfect solution?

  • For that value that is entered by two people once a quarter, do you just have a target range that you need to validate against?
  • Do you need to download values from a government site, make sure that happens properly and use those values to validate?
  • Do you need to download values, apply some corporate wiz-bang business logic and then do validation?
  • Do you need to download values, apply biz-logic and get sign-off from the CFO?
  • Do you need to download values, apply biz-logic and get sign-off from the CFO and then perform some workflow with the board of directors before this value becomes valid?

As you can probably gather, if the impact of the failure is minimal, but the effort and it’s corresponding cost of establishing a bullet proof software is not minimal, the decision on the investment in time (and money) is not an easy one.  It’s in our nature as software developers to try to achieve perfection, well at least it should be.  But in some cases the cost of perfection just isn’t justified, I’m not sure there is a empirical formula here but I think there are things that can be done.

Some strategies for dealing with being lazy (or using your time wisely)

  • If you have a spec you are working from, not only understand the words that make up that spec, but understand the spirit in which that spec was created.  That is try to read between the lines and understand what the person really wants to get out of the software and what it needs to do.  Writing a spec is not easy, even for us analytical types (programmers) for the creative types this is even more difficult.
  • Discuss with the business stake holders the importance of the features.  Don’t get too technical but try to explain your perceived efforts and get an understanding of the impacts of failure.
  • If you decide that the failure isn’t critical and time might be spent doing other work or adding other features, what ever you do don’t fail silently.  Fail quickly and fail in an obvious way.  What ever you do don’t do something like: try {…} catch {};
  • Make sure you are using a good error logging format.  If you do find yourself in an unexpected state that would cause a failure, capture that state, capture the stack trace and have the logging system shoot yourself an email.  Most of the times it’s easier to fix the problem than originally find it.
  • Write the right unit tests, I’ll have to admit, I’m not a big test first or 100% code coverage fan, but a number of well place unit tests have saved my a** more than a few times.  What is the right number, sorry I don’t have that answer, I think it is a formula of the sophistication of the software and the cost of the failures.
  • Leverage your piers, if you are working on something where you know you should spend considerably more time on, but it just doesn’t make sense for you to churn on something for a week or two.  Bring in a trusted pier, do a code or concept review, you may be too close and miss something obvious.

Just to be clear, I’m not advocating being sloppy and not thinking through the edge cases of the software you are writing, but there is a cost in the pursuit of perfection.  You may win the battle (a perfectly tested and functioning admin module, which I will argue is not perfect anyway) but lose the war, never ship the system that uses the data from that admin module.

-ec

Saturday, May 23, 2009

Don’t be obsessed with trying to fix bugs in the real world

In catching up with one of my favorite podcasts, I listened to Stackoverflow #49.  One of the points that Joel made really struck home.  At about 32 minutes into the podcast Joel made a point about Taxi Drivers trying to run him over in NYC.  I encourage you to listen to this chunk of the podcast, but let me attempt to summarize.  With the significant number of cab drivers and with an average turn over of 3 weeks, it’s futile to get upset and slap the hood of the cab that just about ran you over.  This goes along with one of my favorite sayings “Never try to teach a pig to sing, it just annoys the pig”.

So what does this have to do with being obsessed with fixing bugs in the real world?  What brought this home to me is when he started discussing what we do as software engineers, we work in a very complicated discipline, our job is literally to manage thousands or even hundreds of thousands of details, make those somehow compile and turn into something that actually compiles and does what our customers need.  In reality this is really a close to an impossible task, but its our job to search out and destroy “stuff” that get’s in our way to get as close to as perfect as possible.  Where we see a problem, we want to fix it.  Period.  It’s very difficult for us to know about a bug, know what the solution is, but just not do anything about it.

As a consultant, it’s my job to understand the customers needs and deliver a solution.  To deliver a solution, we need certain things to be successful (or save us a number of hours, which in turn takes money out of our pocket and gives it back to the client).  We also see other internal efforts or processes that are failing, and the solution is actually fairly trivial to implement. 

As difficult and as tenacious as we are about eliminating problems in our code, sometimes we need to let go and just accept that “it is what it is” when dealing with things we have little or no control over.

I’m trying really hard, but when I see a bug whether it’s in my source code or in a process, internal or clients, it’s very hard not to get involved and attempt to fix it.  I have a bad habit of offering advice where it’s not been solicited.  This comes back to the saying “Never try to teach a pig to sign, it just annoys the pig”.  I first heard this in the early ‘90s and ever since than I’ve been trying to internalize it.  I had one client that was actually a pretty good gig.  After a few years of being there, I finally felt I was starting to have a real impact on their business and their department.  However to take it to the next level required some changes I just couldn’t make without executive level support.  After about six months of lip-service and sleepless nights trying to figure out how affect change, I finally gave up.  That client is doing just fine today (at least that’s what I hear).  What can I/we take away from that?

When working with People Systems, whether that be a cab trying to run you over in NYC, a project manager staffing their “pet project” over yours or even that person that drinks the last of the coffee without making a new pot shouldn’t have an impact on your attitude and how you do you work.

So what are some ways we can combat this?  As I get older and more experienced within this industry the answer is starting to become my default answer when someone asks me a question.  It depends.  It depends on you, your personality, your team, your culture, and the specific situation.   So what are some possible solutions?  Flight, Fight, Ignoring or Empathy.  

Please excuse me for a minute, my wings are done and I need to refill my beer.

image

Ok – thanks for waiting for me, great wings, now back to your regularly schedule blog.

Where were we?  That’s right, Fight, Flight, Ignoring or Empathy.  As someone who is passionate about developing software, our first reaction will be Fight, that is to say, we see a bug and, heck we know how to fix bugs right?  Why should this be any different?  Well it is.  In some cases this is the right solution.  If your company doesn’t implement any sort of source control because it just seems like a waste of time, your first reaction should be indeed, let’s at least do some real basic blocking and tackling stuff like getting this in place (Fight).  If after three months of people not getting it and still thinking source control is just a fad it might be time to vote with your feet and pursue other opportunity (Flight).  On the other hand, if someone drinks the last cup of coffee and doesn’t make a fresh pot are you going to let that ruin your attitude for whole day (Ignoring)?  Generally if you choose the Ignoring path, you really need to be careful, if you are going to let something go, make sure you let it go.  Don’t just put up with it and take out your frustration in other ways such as being too critical in code reviews or probably more common venting scheme of have back-channel conversations with others.  This is just unhealthy and lots of small things will build over time.

This brings me to what I see as the final option which is probably the best to exercise, empathy.  What do we mean by that?  Wikipedia defines empathy as:

Capability to share your feelings and understand another's emotion and feelings. It is often characterized as the ability to "put oneself into another's shoes," or in some way experience what the other person is feeling

Everyone has a different background, priorities and experiences.  The cab driver that is trying to run you over is just trying to make enough money to send back to his family.  The selfish developer is so focused on cutting code he doesn’t realize he is always drinking the last cup of coffee.  The team that doesn’t think they need source control…wait, no sorry, no empathy there.  Anyway dealing with these sorts of issues might be considered as a change requests, not really bugs.  Does this work for me?  I wish I could say that yes, I’ve got it all figured out, but I can’t.  Managing hundreds of thousands of details and fixing bugs in our software is not even a fraction as complicated as being obsessed with trying to fix bugs in the real world.

Whew, nice to get that off my chest.  Now I can save a little money by not going to my therapists this month.  After the incident at last months session, they probably need a little time off :*).

-ec

Sunday, May 17, 2009

Thoughts after attending The Day Of Ruby

On May 16, 2009, I attended the Tampa Day of Ruby. I’m always interested in learning Florida-tampasomething new and with so many people talking about elegance of the language I was extremely excited to spend a full eight hours focused on getting a crash course in Ruby. I was not disappointed. After attending the overview, here’s my summary:

Invest some time to practice, learn Ruby and Rails (and/or other elegant technologies) to become a better programmer. Use more traditional, main stream technologies to ship high quality production code using what you learned from your studies of the elegant boutique languages.

Let me explain; but first a little background. My “Ruby-esque” language experience was a language called FORTH. It has many of the same characteristics of Ruby, with main feature that it shared being the ability to extend the language using the language. We had a shop of about 10 people. The distribution of talent was probably fairly typical: 3 – Shouldn’t be programmers, 5 – Average Developers and 2 rock-stars. Ruby like FORTH is what I would consider an “Amplifier”, where most C or traditional languages would probably be more of an “Equalizer”. With FORTH, and I suspect Ruby, it would allow the talented people to do an extremely good job building systems. In the hands of people that shouldn’t be programming, well, let’s just say, they can make a real mess that could never be salvaged. With average developers, they don’t really use any of the real power of the language and don’t see any of it’s benefits. That is to say that poor developers develop systems that are 100x worse than the average and great developers can develop systems that are 100x better than the average developer. If we contrast that with “equalizer” languages like the C-family, the poor developers may be do 5-10x worse job and the great developers can do 5-10x better.

Leveraging the power of languages like Ruby and FORTH, require some level of natural talent plus the desire to invest time and practice.

So that brings me to my point, invest time to learn Ruby (or something similar); and I’m very serious about that; however in your day-job for creating production code use more traditional technologies. Most production LOB (Line of Business) type applications can benefit less by using an elegant technology like Ruby as they can by putting in a predictable and repeatable process to deploy that technology. To leverage a technology like Ruby, you need top-tier developers to take advantage of it’s benefits. If you don’t have top-tier developers, you’ll probably end up developing using Java or C/C++/C# techniques in Ruby. This results in adding just one more layer of complexity into the already incredibly difficult process of developing software.

I know a lot of companies use boutique languages for internal or support systems. I personally have mixed feelings on this, I think it’s probably a good way to practice if it’s done in the right environment however there are two risks I see in doing this. First being that most of these are research efforts, and generally the output of research isn’t as good as if you engineer your tool. This results in support systems which are critical for your developers to do there jobs that may be somewhat fragile. If there is one thing I hate as a developer more than anything else is to work a long day, get my problem solved, really want to be done for the day and end up fighting with the support infrastructure for another two hours to get my solution deployed. In addition to that, if you develop your support mechanism in FooBat ZX V2.3, what happens when you leave the company (or want to take a vacation) and that support tools needs maintenance. You may have some one that knows FooBat ZX V2.3, but if this was done as your first application using the technology, I suspect it may not be all that clean. As I mentioned earlier, I think in the right shop, using a boutique language for internal and supporting systems could make sense, but deciding to do so should not be made on a whim or a cool write up you read in a blog post.

So in summary, I learned a lot yesterday at the Day of Ruby, it brought back great memories of some of the software engineering discussions we had while implementing systems in FORTH. However as I still think FORTH is probably the most elegant language, other than screwing around on my own, I just don’t ever see recommending using this for any production work I do for my clients. I think the same will be true for Ruby.

Finally I have to commend Cory Foy and his initiative to put this together. It was obvious he is a very talented presenter and spent considerable time putting together the materials and thinking through the topics.

-ec