IT Crossing
Saturday, July 05, 2008 | Register | Login 
Minimize
 IT Crossing Blog
Author: Don Worthley Created: 9/12/2007 3:12 PM
Business, Technology and everything in between.

When Fred Brooks wrote No Silver Bullet in 1986, he was convinced that the majority of complexity left in the software development process was not a result of what he called accidental complexity, the complexity that results from the way we go about solving a problem; rather, it was a result of essential complexity, complexity intrinsic to the problem domain. 

I'm not as interested in Brook's speculation regarding whether we would see a 10 fold increase in productivity over a 10 year period of time.  I honestly think we're getting close to this through the use of code generation, better design patterns and advancements in object-relational mapping (ORM).  I'm fascinated by the bifurcation of the software development process into these two discrete segments: accidental and essential complexity.

It's an exciting time to be working in the software development industry, and I think the excitement builds as we are able to more clearly separate the complexity of any project into that which is related to the business problem and that which is related to the way we go about solving the business problem.  

I heard someone say on a training video years ago about component development that you wanted to "keep things separate that should be separate and keep things together that should be together."  At first, I thought, "How simple. who wouldn't follow this principle?"  But after years of working as a developer and trainer, I realize now that this rule of separation is extremely important to the development process, and in a much larger sense to the ability to create working solutions in the enterprise.

As I think through the architecture of a solution now, I realize that my mind is sifting through the problem domain trying to identify orthogonality.  In some cases, this can be hard to identify.  One of the questions that I can ask myself is "What are the areas intrinsic to this specific problem that are intrinsic to the last 10 problems I've had to solve?" 

It is this attempt to identify orthogonality which has lead to the growing interest in things like attribute-oriented programming (@OP), ORM frameworks and software factories

In spite of all of the advancements in areas related to the accidental complexity of software development, we still find ourselves slogging through a jungle of process and technically oriented difficulty before we ever reach the complexity of the actual business problem.

Why is this?  In part, I think it's due to the relative age of our profession.  Yes we've been around for some 50 or 60 years, but as Steve McConnel notes in many of his books and more recently in Construx, his blog and a discussion forum of his for software engineers, we still have our work cut out for us when it comes to solving problems like our engineering counterparts in other industries. 

While wonderful advancements have been made in our industry, we still fall short--in part, because of the overabundance of competing approaches to solving this problem.  I was having lunch with another software developer in the area who was describing the frustration the developers felt in their shop when they had to support a solution with a middle tier generated by LLBLGenPro.  Although I haven't used this particular ORM tool, I've heard great things about it.  The issue was that most of the developers on the team didn't have experience with this ORM either.  They've probably had experience with other ORM tools, but unfortunately the infrastructure of each ORM tools is different.  Take .netTiers, for example, which--although, like LLBLGenPro, generates the classes based on your data model-- does not use the same templating engine.  .netTiers uses CodeSmith, which is a great code generation tool, but has its own learning curve.  Or take NHibernate, or Hibernate if you're a Java developer (I realize Hibernate came first, but I'm a hopeless .NET developer).  With NHibernate, you develop the description of the domain model and the tool generates the data model to support your domain objects, kind of the reverse of .netTiers and LLBLGenPro.

Even Microsoft has jumped on board the ORM wagon with LINQ and LINQ to SQL.  As you may have seen in previous posts, I have grown fond of SubSonic, a very simple, easy-to-use and open source ORM.

But the issue of orthogonality isn't just about ORM tools.  As I mentioned above, attribute-oriented programming techniques have helped tremendously in the effort of dividing the technical and business related domains.  In fact, attribute-oriented programming probably should have been called orthogonality-oriented programming, but OOP was already taken.  The whole goal with attribute-oriented programming is to identify those aspects of business solutions that are orthogonal to the business logic, aspects that occur in almost every business application written, aspects such as logging, wrapping operations in a transaction or enforcing some form of authorization.  You can see this in action with the Enterprise Services features built into the .NET framework. 

Additionally, the recent interest in Service-Oriented Architecture (SOA) has lead to wonderful improvements, on the technical side, in how business process are properly organized and made available to disparate solutions within an organization.  At the heart of these improvements is the desire to identify the proper kind of separate between business logic and the technical aspects of how that business logic is organized and made accessible.  Over the years, we have found that further dividing our business logic into orthogonal services that are accessed with clearly defined and immutable contracts makes it easier to reduce the duplication of effort that had become so common in enterprise development.

So how is all of this important to me on the business side?  It's critical in today's market to be identifying solutions that have implemented a high degree of orthogonality between the technical and business domains as well as between different technical areas that need to be properly separated.  Hire an independent consultant or have your in-house architects take a look at the infrastructure of any proposed solutions within your organization in light of this issue of orthogonality and ask questions about how the proposed solution makes use of current best practices to keep things separate the should be separate and keep things together that should be together.  The solution doesn't have to use an ORM or to even be programmed in an environment that makes use of attribute-oriented programming or SOA, but it does need to be extensible and maintainable, two areas that suffer the most when an application is not designed well. 

Here are some issues I would consider when thinking about the orthogonality of a proposed solution:

  • What tools, frameworks or factories have been used in the development of the solution? 
  • Are they proprietary or open source? 
  • If they are proprietary, how widely has this platform been adopted in the industry?  What kind of documentation is available and how active are the support forums?
  • If they are open source, how widely is the open source project adopted and how active is the community?
  • Has the vendor re-invented the wheel in solving common technical infrastructure issues?  For example, have they written their own workflow engine when they could have used an existing workflow framework?
  • How has the business logic been organized internally and what are the APIs for accessing that logic.  Are they using industry standards or principles such as SOA? 
  • If the solution provides access through web services, how have the web services been developed?  How is authentication handled?
  • What design patterns were used in the development of the software?  For example, does the solution use MVP or MVC to keep business logic separate from the UI?
  • How have the extensibility layers been developed? 
  • Have best practices been used to help ensure that extending the product won't cause issues with upgrades to the baseline product?

Recently, I've spent some time looking at Microsoft Dynamics CRM 3.0, and, although I haven't had the chance to write an application on top of this framework, I've been very impressed with what I've seen, especially related to the orthogonality of the business and technical domains.  While there are some limitations such as the inability to natively handle many-to-many relationships between entities, a limitation that I hear will be addressed in the next release of CRM code-named Titan, the framework seems to provide a way to begin focusing on the business domain without spending an inordinate amount of time writing your own infrastructure.  The extensibility points are there, and they have been designed so that upgrades to the baseline product should have minimal to no effect on customizations.

How about you?  What software have you used in your organization that has maintained a high degree of orthogonality between business and technology? I’m interested to hear from you!

WARNING:  This is a technical entry with no business related information.  It relates to Microsoft SQL Server, SubSonic and .NET with code written in C#.

I was responding to an issue in the SubSonic forums a few weeks back when I discovered that the INFORMATION_SCHEMA.PARAMETERS view didn't contain information on the nullability of a stored procedure's parameters.  No problem, I did a little searching and found the following two stored procedures: sp_sproc_columns and sp_procedure_params_rowset.  Excited at the promise of valuable information on the nullability of my parameters, I ran the following script to create a quick stored procedure that contained both a parameter with a default and one without.

CREATE PROC TestProc (@intDefault int = 0, @intNoDefault int)
AS
SELECT @intDefault as 'ValueEntered'

I ran both of the stored procedures above only to find that the nullability for both parameters was the same:  nullable.  Hmm.  Ok.  I must be misunderstanding what it means for a parameter to be nullable.  At this point, I began to see that I had confused having a default value, which determines if having at least some value (maybe NULL) is required, and being nullable.  So I dug into SQL Books Online and found that parameters are nullable by default.  So in SQL Server you can have a parameter that's required, but nullable.  That is, the parameter is required, but you can pass in NULL as a value for the parameter.

That said, let's jump over to SubSonic, my favorite ORM of late, which, by the way, I'm really hoping continues to maintain a critical mass of developer interest even as Microsoft is working hard to release LINQ to SQL.  I think Rob, Eric, et. al. have done a great job balancing simplicity and ease of use with critical features.  There's a lot behind SubSonic, but it's also easy to use,  an extremely important balance that's needed for any technology to survive.

One of the things I absolutely love about SubSonic is the fact that it supports the strongly typed use of all of my stored procedures.  I wish there was a named indexor for the parameters collection, but that may be a good topic for another post.  The issue at hand with SubSonic's implementation of the stored procedure parameters is that it uses nullable types for all of the parameters regardless of whether there is a default value assigned.  Phil Haack mentions in this issue on CodePlex that it would be great if SubSonic could distinguish between parameters that have default values and those that don't and are therefore required parameters.

Having searched high and low through the meta data available to mere mortals like me in SQL Server, and having seen a post in the newsgroups from someone who said that the only way to determine if a stored procedure parameter had a default value was to parse the TSQL, I decided to write a routine to do just this using regular expressions. 

The routine is available inside the patch download in the SubSonic Issues log on CodePlex.  I've also included code you can use to test retrieving the default value status of each of a stored procedure's parameters.  To use the following code, create a web form with two textboxes, two labels and a button as follows: txtDatabase, txtSproc, lblSproc, lblArguments and btnProcessSproc.  In the click event of the button, place the following code (Written in C#):

        string cnString = @"Data Source=Server;Initial Catalog=" + txtDatabase.Text +

                          ";User ID=sa;Password=password;";

        string SQL = "EXEC sp_helptext " + txtSproc.Text;

        SqlDataReader sprocReader;

        StringBuilder sprocBuilder = new StringBuilder();

        string sproc = string.Empty;

        string arguments = string.Empty;

        string[] argumentArray = new string[0];

        Hashtable parameterNullibility = new Hashtable();

        using (SqlConnection cn = new SqlConnection(cnString))

        {

            cn.Open();

            SqlCommand cmd = new SqlCommand(SQL, cn);

            sprocReader = cmd.ExecuteReader();

            while (sprocReader.Read())

            {

                sprocBuilder.Append(sprocReader.GetString(0));

            }

            sproc = sprocBuilder.ToString();

        }

       

        //Replace Newlines with spaces

        sproc = Regex.Replace(sproc, @"\r\n", " ");

        //Replace multiple white spaces with just one space, also replace tab characters with single space

        sproc = Regex.Replace(sproc, @"\s+", " ");

        //Remove extra spaces around commas just to be safe

        sproc = Regex.Replace(sproc, @"\s*,\s*", ",");

        //Remove any comments

        sproc = Regex.Replace(sproc, @"/\*.*?\*/", "");

        lblSproc.Text = sproc;

        string regex = @"CREATE\s+((PROC)|(PROCEDURE))\s+((\[.+?\]\.?){*}|(\S*))(?<Params>.*?)\s{1}as\s{1}";

        RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;

       

        MatchCollection matches = Regex.Matches(sproc, regex, options);

 

        if (matches.Count > 0 && matches[0].Groups["Params"] != null)

        {

            Match match = matches[0];

            arguments = match.Groups["Params"].ToString();

            argumentArray = Regex.Split(arguments, ",");

            foreach (string sArgument in argumentArray)

            {

                //first retrieve the name of the parameter using Regex

                MatchCollection paramMatches = Regex.Matches(sArgument, @"(?<ParamName>@\S*)", options);

                MatchCollection nullMatches = Regex.Matches(sArgument, @"(?<NullString>=\s*)", options);

                if (paramMatches.Count > 0 && paramMatches[0].Groups["ParamName"] != null)

                {

                    bool isNullDefault = (nullMatches.Count > 0 && nullMatches[0].Groups["NullString"] != null);

                    parameterNullibility.Add(paramMatches[0].Groups["ParamName"].ToString(), isNullDefault);

                }

            }

        }

        foreach (string sParam in parameterNullibility.Keys)

        {

            string nullability = ((bool)parameterNullibility[sParam]) ? "Default value is set" : "No Default.";

            lblArguments.Text += sParam + ": " + nullability + "<br />";

        }

       

Change the connection string information and run the page to view the information about the defaults.  You may also want to change the names of the variables which reflect my initial focus on nullability before I realized that the broader issue was whether a parameter had a default value.

This code could be extended to retrieve not just a boolean value determining whether a parameter contains a default value, but also the default value itself. 

If you find this useful or have any questions, let me know!

I forgot to mention that I tried to test this against as many formatting scenarios as possible. If you find a stored procedure that doesn't work with the script, please let me know by posting here in the comments!

I've been investigating an open source Data Access Layer(DAL)/Object Relational Mapper(ORM) lately that I really like.  It's based on the ActiveRecord pattern and it also provides strongly typed access to your stored procedures.  If you haven't seen it yet, you can check it out here.

You can optionally download and install a SubSonic Visual Studio Add-In which allows you to generate your entire DAL in a matter of minutes from right within Visual Studio.  I've been using SubSonic on a small project related to Recipes and after generating the SubSonic ActiveRecord objects, I had access to a Recipe class complete with great ActiveRecord features, like FetchAll and LoadByKey.

One of the things I wanted to do with my SubSonic objects was retrieve them at run time as some supertype and access some of the features available through a base class named AbstractRecord.  I didn't want to specify which kind of ActiveRecord (ActiveRecord derives from the AbstractRecord base class) object I was dealing with at compile time.  I wanted to determine this at runtime.

In effect, I didn't want to be forced to plan the details of my bar-b-q ahead of time, I just wanted to grab some SubSonic objects at the local SubSonic drive-through based on some kind of superclass that exposed the functionality I needed, which was basically just access to the GetColumnValue and SetColumnValue methods, both of which are defined in AbstractRecord.

The problem is that AbstractRecord is a Generic abstract class of the form AbstractRecord<T> where T : ActiveRecord<T>, new().  This means that if I want to pass instances of my specific AbstractRecord classes around, I'll have to at least identify ahead of time what specific type of AbstractRecord I'm talking about.  And that's more like a sit down restaurant than a drive-through window.

With all of this buzzing around in my head, I read this post by nayt at the forums for SubSonic.  Although I had already come up with a solution to the problem, I realized it wouldn't solve the problem in the post.  The issue raised in the post was that a BusinessDictionary object was needed with a generic (with a little g) indexer which would return an ActiveRecord object based off of some kind of key, most likely the name of the specific ActiveRecord class as a string.

As an aside, it would also be really nice to be able to write something like this:

DynamicActiveRecord dar = new DynamicActiveRecord(“Recipe”);

Where dar would provide access to generic versions of all the properties and methods that would make sense for an ActiveRecord object created at runtime for the Recipe Table, something akin to the un-typed DataSet.

But even if there isn't a dynamic ActiveRecord object available in SubSonic, it would seem that creating a new supertype just above AbstractRecord<T> would help address some of the issues we face when we try to retrieve ActiveRecord objects dynamically at runtime. A supertype that wasn’t generic would make it possible to make use of polymorphism more in our solutions. It would be wonderful, for example, if there were an interface named IAbstractRecord which defined all of the properties and methods that didn't rely on <T>. 

Anyway, I still think we can add a drive-through window façade on top of the SubSonic library, but we'll have to use reflection.  Here’s some code I worked up to see if how this idea would work:

//Code Reference:

// “SubSonicClasses” = Name of assembly containing my generated ActiveRecord classes

// “WTS” = Namespace of generated ActiveRecord classes.

// “Recipe” = Name of specific class to instantiate

// “CreatedDate” = Column from the Recipe table to be retrieved.

****Sample Code to Retrieve Column Value****

Object oActiveRecord = GetActiveRecordByClassName("SubSonicClasses","WTS", "Recipe");
LoadActiveRecordByKey(oActiveRecord, 0); //Load the data for a Recipe with recipeID=0.
string columnValue = GetActiveRecordColumnValue(oActiveRecord, "CreatedDate");

****End Sample Code****

****Static Methods Used in Sample****

private static Object GetActiveRecordByClassName(string assemblyName,
string namespacePrefix,
string className)
{
Assembly subsonicAssembly = Assembly.Load(assemblyName);
Type t = subsonicAssembly.GetType(namespacePrefix + "." + className);
Object oActiveRecord = Activator.CreateInstance(t);
return oActiveRecord;
}
private static void LoadActiveRecordByKey(Object oActiveRecord, Object key)
{
MethodInfo mi = oActiveRecord.GetType().GetMethod("LoadByKey",
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
mi.Invoke(oActiveRecord, new Object[] { key });
}
private static string GetActiveRecordColumnValue(Object oActiveRecord, string columnName)
{
MethodInfo mi = oActiveRecord.GetType().GetMethod("GetColumnValue",
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
Type[] genericType = new Type[] { typeof(string) };
MethodInfo gmi = mi.MakeGenericMethod(genericType);
Object retValue = gmi.Invoke(oActiveRecord, new Object[] { columnName });
return retValue.ToString();
}

****End Static Methods****

This code will only work if you have generated your SubSonic classes in a separate assembly. That means no build provider and no generating your classes inside of your App_Code directory. It also requires that you have the necessary permissions to use reflection. You’ll need to generate your classes inside of a separate project that you compile into an assembly that you can load with reflection. At least, that’s the only way I could get this to work while I was playing with it today. I created an assembly named SubSonicClasses and set a reference to this assembly in my test project.

You’ll notice when you use reflection to call the GetColumnValue that this method is defined to use Generics. This means that you’ll need to use the MakeGenericMethod to let the reflection engine know that you want to call the string version of GetColumnValue.

I realize that there are some obvious limitations to using reflection, like the fact that everything retrieved from GetColumnValue is retrieved as a string and cast as an object; but it does allow someone to use the SubSonic classes dynamically. I'm hoping that future versions of SubSonic will provide a more generic, Non-Generic supertype for AbstractRecord such as the IAbstractRecord described above as well as some kind of factory method which allows you to create an instance of one of your ActiveRecord objects by simply passing in the name of the Table or specific ActiveRecord class name.

If you haven't used SubSonic, check it out and let me know what you think.  If you are using it, I'd be interested to hear what you think so far.

Software Architect.  At least that's what is says on my last business card.  Senior .NET Architect if you looked at the web site.  It seems that this is becoming one of the hottest job title buzzwords, especially within the Microsoft community; but what does it actually mean? 

It's certainly up there in that realm of questions that have about as many answers as there are respondents; although, I believe that's changing as more focus is placed on this much needed position within organizations. 

I was gazing up into the beautiful blue sky pondering this very question this morning (OK, it's actually morning-ish...well, alright, technically it's in the afternoon, but my internal clock was reset by a bout of the flu) when it occurred to me that software architects are the people who make a living by working at the very intersection of business and technology.

A software architect is one who has mastered enough of both the business and technical domains to stand in the gap (in many cases, what seems to be a very great divide) between those who are responsible for running the business and those who perform the magical technical incantations behind the scenes so that the information of the business is handled effectively.

I realize there are others who are close to this gap. The product manager for a product being developed either by an independent software vendor (ISV) or a consulting company must stand in this same space, but they seem to stand more to one side. On the other side, you have LOB managers or business analysts who think more from the business perspective, but who are trained in the proper linguistics and special arts required when speaking and negotiating with representatives from the technical crowd.

Though there are others who work in or close to this gap, architects are distinct in at least one aspect of their job responsibility. Unlike the business stakeholders, product managers and business analysts who speak to one side or the other of the gap, the software architect is unique in his/her responsibility for providing guidance and establishing specific means of governance in both directions.

An architect must learn to communicate with the key business stakeholders and in so doing must learn to value key business issues related to technological decisions, issues like ROI and cost/benefit or risk/benefit ratios. The architect needs to either know the enterprise architecture (EA), either through documenting the EA themselves or through communicating with other architects in the organization who are responsible for managing the EA.

From the technical perspective, the architect must have enough experience with a wide variety of technologies to allow them to quickly sift through the never ending stream of new technology and make important technical and business decisions such  as whether to build or to buy, or maybe to extend an existing open source project.

And that’s just from the technical and business perspectives. There’s also the expectation that the architect has enough experience as a manager to know how to motivate other managers--on the business side to manage necessary changes in expectations or in process improvement, and on the technical side to encourage product and project managers to create a fun and productive environment for the technical staff.

Of course, one size does not fit all. I like the way Microsoft categorized the different kinds of architect you might find in a variety of organizations.

  • Enterprise Architects are typically employed by a large organization and focus on the EA. A CTO would function as an enterprise architect. 
  • Solutions Architects are typically consultants hired to function as an architect for an organization.
  • Infrastructure Architects are typically employed by large organizations to oversee the business and technical issues related to operations.
  • Product or Depth Architects – are typically responsible for the implementation of a specific product within an organization. They are often consultants who represent a consulting company or an ISV.

If you’re like me and you’re interested in growing your skills on both the business and technology side, here are a few resources I would recommend.

  • Every book or resource on design patterns and best practices you can get your hands on. For design patterns, I highly recommend Head First Design Patterns (Head First).
  • Good books or training material on managing software development projects. I highly recommend studying and using some flavor of the MSF Process. I just finished reading The Mythical Man-Month.
  • Start a business of your own.  This is a different kind of resource, but one that's invaluable to those of us who don't have an MBA.  There's nothing like experiencing the challenges of being a business owner to help you understand how important good business decisions are for your customers.
  • Subscribe to Microsoft's free (at least it's free as of writing this in July of 2007) publication for architects: The Architecture Journal.
  • Create a user account at Microsoft's new site for architects and those aspiring to become one.  It's called Skyscrapr.
  • Hone your communication skills by taking courses on communication, reading books and giving presentations whenever you can.  If you haven't already, join your local Toastmasters.  Excellent oral and written communication skills are essential for a software architect.

I'm interested to hear from you!  What resources have you found to be useful in your quest to grow as an architect?

As I mentioned in my previous post, I've been studying design patterns lately.  I've also had the opportunity to work with the Telerik suite of controls over the past year and half and was so impressed that I volunteered to do a demo at our local .NET users group on the capabilities of their controls.

I recorded both presentations and they are available on our local .NET UG website (http://www.sgfdotnet.org)

MVP (Model View Presenter) Video

Telerik Video

screenshot

I'm interested to hear your feedback as these are my first screencasts!

A student asked me about design patterns in class about 6 years ago, and, although I knew the term from engineering, I wasn't familiar with any of the design patterns documented in the GoF text.  How I wish I would have taken this guy up on his invite to meet for lunch after class! 

The problem for me was my schedule.  I was so busy working on so many things that I didn't have time to keep up with changes in my industry.  Yes, I tried to read as much as possible from trade journals, but even this time was choked out by an ever increasing sense of urgency to meet deadlines and get software completed.  What I needed was a design pattern for staying up-to-date in my field.

So what is the design pattern for staying afloat?  I'm sure it's different for everyone, but for me it's recognizing the need to schedule time for professional maintenance. 

Up until just a few months ago, I found myself working long hours with a partner trying hard to establish a reputation for getting projects done right and on time.  You may be different, but what I've found is that software engineering is very different from other forms of engineering in that the level of unanticipated decision variables (unk-unks or unknown unknowns as Donald Rumsfeld likes to call them) is much higher than in other industries.   This means that it's pretty risky to say that x can be completed in y weeks.  On every project, we run into these unknown unknowns and yet we are still able to make almost every one of our deadlines?  How?  By working day and night for days on end and ignoring anything not related to the achievement of the goal. 

I've learned to accept the fact that in most cases customers don't understand why you can't provide an exact estimate for a specific set of features.  And while I may try hard to properly set customers expectations, I also believe in a fixed ship date mind set for software development.  It's the best way to actually get things done.  All this to say that while I'm working on a project, I've come to accept the fact that I won't have a lot of free time to read up on the latest developments in my industry.

But, what I do have control over as a consultant and what I would encourage many of you who manage a development staff to consider is the amount of time that is allocated between projects (or even during projects if that's feasible for the personalities of your developers) for continuing education in their field. 

What am I talking about?  Well, here's a short list of resources that I would recommend making available to your developers for self-paced study and research; and I would encourage you to plan for between 15 and 20% of your developer's time to be dedicated to using resources such as the following for professional development:

I've heard that Google allows their developers to dedicate 1 day a week to professional development.  I think this would work great for some developers; but, for others, it would be best to plan for time between projects to allow for more extended and in-depth research.  I've dedicated the last 3 1/2 months to research and I feel like I could spend another 3 1/2 months if it weren't for the fact that I need to make some progress on projects that are of significant interest to me. 

I'm interested to hear back from you regarding how you or your development staff are managing to stay afloat.

While it's true that the main reason I moved from the Washington, D.C. area to Southwest Missouri was to be closer to family, a close second was this growing desire to settle into a small community where the pace of life doesn't leave you completely exhausted at the end of a work day.  I have this vision in my mind of a the perfect community, a planned, green community that is almost entirely self sufficient in terms of energy resources.  The community would be designed with wireless access available anywhere within the city limits and schools, grocery stores and shopping centers would be within walking distance for everyone. 

I'm not really an environmentalist, at least not in the tree-hugging, sandal-wearing sense of the word, but I'm all about minimizing our footprint while enjoying nature to it's fullest.

Anyway, having just come in for a ride with a friend this morning on some local motorcross/ATV trails, I was filled with a renewed appreciation for the wonder and beauty of God's creation and I saw a story on CNN (I used to have a link, but the story's gone now) about a planned community in Sky, Florida very much like the dream community I've envisioned. 

I believe that this is the beginning  of a new trend that will increase in popularity as the technology to work remotely becomes more readily available.  Clearly, there are professions that don't support working remotely, but there is a sizable and growing  percentage of information workers who would find that working remotely, at least part of the week, would actually boost their productivity.

When living in Virginia, my commute to D.C. was an hour and a half one way.  So, three hours of every work day were spent in a car or on a train.  Now, I like to drive, so the first 30 to 45 minutes of that commute in the evening provided a good buffer between my day at work and my life at home; but the last half of the commute was like leaving the lights of your car on without the engine running.  By the time I made it home, I was completely drained.  There are entire years of my life from the D.C. era that I simply do not remember.  

I understand that a presence in the office is still important for many workers, but I'll never forget how much more productive I was for my last employer when they finally gave me the go ahead to work from home part-time.  I probably gained an extra 2 hours a day in time not spent trying to filter out other people's conversations from across the office.

Given the right tools and the right software, the staff of your organization should find working remotely to be both more rewarding and more efficient. 

So, what kind of tools could be employed to help keep remote employees working effectively and staying connected?  Here are some that I have either used personally or have seen demonstrated and about which I have heard great things:

  • SharePoint Server 2007 - This product has come an amazing distance over the past 6 years.
  • Groove 2007 - Recently acquired by Microsoft, this collaboration tool makes it extremely easy for members of a team to work remotely.  Based around the concept of a workspace which is shared by team members, its like a peer-to-peer version of Lotus Notes.
  • Basecamp - Keep your eyes on the products from 37 Signals, the creators of the popular Ruby on Rails framework for rapidly developing web based applications.  BaseCamp is a great product for small teams or departments within a larger organization.  It's also inexpensive.
  • Remote Desktop - If security is a concern, there are wonderful VPN solutions that help to ensure the safety of remote access.
  • GoToMeeting - I don't know what I would do without this tool.  the best part is that it's wonderfully affordable.  I've found that WebEx and Live Meeting are overkill for most of the meetings I have with clients. 
  • Wikis - The concept of a wiki is simple.  It's a website where members can edit the content. But this simple idea has come to be an extremely powerful tool for teams working remotely.   Wikis are increasing in their use within the enterprise and if you haven't used this kind of tool before, check out this definition.

I'm interested to know what your experience has been with working remotely?  Has this worked well within your organization?  If so, what tools do you use?  Anyone interested in starting a planned community in rural Missouri?

Is it me, or does everything run slower these days?

Most recently, I've struggled like so many others with the speed of Outlook 2007. My assumption is that as a product progresses, it's performance will actually improve; either that, or the feature set will increase without significantly degrading performance. I honestly haven't had the time to look into the new and improved features of Outlook 2007, but regardless of any of the amazing new things this PIM can do, it's so unbelievably slow that it's tempting to uninstall it and revert back to Outlook 2003.

I had a similar experience with my upgrade to WinZIP 10.0, which I decided to purchase a few years back after using it for most of a decade in trial mode. Over the past year, it has taken considerable longer to unzip large files.

Now that the whole world has decided that web applications are far superior to native desktop applications (I would call them Windows applications, but I don't want to offend any Mac OS X or Linux enthusiasts out there) because of their ubiquity and their ability to solve the thorny deployment issues so common to desktop applications, we are stuck with enterprise applications that are an order of magnitude slower than their desktop counterparts. There are few web applications that have made use of keyboard shortcuts and even with the advent of AJAX, the performance of a web app fails in comparison to the same application running in a local network, assuming, of course, that you haven't designed the application to use web services, which inherit the same HTTP latency as web applications.

Don't get me wrong, I'm all for web applications. It's what I do; but, the issue I face is the loss of productivity that businesses are experiencing as a result of all the 'advancements' being made in the software industry.

This is particularly evident for organizations that have switched to web based versions of their management systems. The loss of productivity for day to day users of these systems is astounding, and this presents a risk to many organizations who are depending on technology to help their staff work more productively. I believe this risk can be mitigated by software vendors by adding the following to the requirements for any new application.

  • No performance change for high traffic use cases. This will require identifying the usage scenarios in an application where the end user will be performing a large number of repetitive tasks such as switching between screens or selecting items in a screen which have dependencies. The new solution should allow the end user to perform their work without seeing any
  • Separate presentation and business logic. Decouple the user interface from the domain specific logic as much as possible by making use of design patterns such as MVC and MVP to ensure that if a web to desktop transition is required, it can be made with the lowest level of effort possible. These designs have the added benefit of making your code easier to test.
  • Choose an appropriate presentation technology. After identifying the usage scenarios with the most repetitive tasks and the highest volume of usage, choose a technology that will help to mitigate the risk of losing productivity with the new solution. Depending on the platform requirements, this may involve creating a native Windows application or the use of some of the new technologies such as WPF/E

Some of these requirements will require gathering metrics for each usage scenario such as number of clicks to complete the process and the average amount of time to complete the scenario. By studying the differences between the existing and future states for each of the high volume scenarios, designers will have specific data that they can use to determine the impact on worker efficiency related to the proposed solutions; and by thinking about worker efficiency up front the final solution will have a much greater chance of making the end users more efficient and the business in general more profitable.

What do you think? Have you performed efficiency testing and subsequently changed your architecture based on the results? I'd be interested to hear from you.

--------------------------------------------------------------------------------

As an side note, WinZIP operations can be significantly improved for large files by right clicking the zip file, choosing Properties and clicking the Unblock button (See posting on WinZIP site):

It turns out that Windows assumes that the contents of zip files could be unsafe for users--go figure!

Now, if only I could find some way to fix my issues with Outlook 2007. Of course, it probably has something to do with a 1.3 GB pst file.

Technorati tags:

Thanks for stopping in to Business, Technology and everything in between. I have discovered over the years that I am an entrepreneur at heart and that business just absolutely fascinates me. When I was a kid, I went from one start-up idea to another. I sold greeting cards door to door when I was in elementary school and started my own woodworking business when I was in Junior High. Try as I may, I can't seem to shake the dream of starting businesses.
It makes me feel old to say this, but I've also been programming for 22 years now. I'll never forget taking computer lessons at a family friend's house over one summer. I started with the simple BASIC programs that left your name floating in patterns across the screen and, of course, it went downhill from there.
I wish now that I had majored in Computer Science rather than Math and Physics. Of course, everything I did involved computer programming. My senior project was a computer simulation of the electric field distribution in multi-layer slab waveguides and while working as an intern with the high temperature superconductor group at Argonne National Laboratory, I added color and shading to a 3-D graphing program I had written in high school and dedicated my time while on the clock to updating and writing new data acquisition programs. I just can't escape writing code.
And so, here I find myself, 22 years down the road, fascinated with the intersection of business and technology. For all of the advancements in the area of software development, you would think that we would have developed software factories (Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools) like Jack Greenfield describes in his book, but it seems that we are only at the point now where we're thinking and talking and strategizing this approach but not actually doing it in an established way in the enterprise.
So, I dedicated this blog to the ponderings and musings on the topics of business, technology and everything in between. There's certainly no end to the content that could be added here.
Currently Reading:
Head First Design Patterns (Head First)
Dreaming in Code: Two Dozen Programmers, Three Years, 4,732 Bugs, and One Quest for Transcendent Software

 Print