Initiatives and Mandates, or, Why We Try To Shove Square Pegs Into Round Holes

Imagine that you have a board in front of you with a series of holes. Each of these holes are different shapes and sizes. In the pile to the left of you is a is a set of pegs, of all different shapes and sizes. Your task is to fill all the holes in the board.

To complete this task you would probably analyze each hole, get a feel for its size and shape, possibly make some measurements and take some notes. You would then go to your pile of pegs and find the peg that most closely matches the hole you have analyzed. Maybe the peg you find doesn’t fit perfectly, but it fits well enough to plug the hole. Accomplishing this task may not be easy, but with the plethora of pegs available to you there is a good chance you will finish it.

Now imagine if you were given the same task, but were told to use only square pegs. Some of the holes could still be filled, and filled well, but most likely your task would become exponentially more difficult, and you would be left trying to fit these square pegs in round holes.

Software development is problem solving activity, much like filling holes in a board. As software engineers we are presented with a series of problems (holes in a board). We analyze these problems, come to an understanding about how they could be solved, and then go out and find the solution that best solves them (find the peg that fits the hole the best). When mandates are places on the solutions we are to develop, there may be some cases where those mandates are helpful, but more often than not you are left trying to solve a problem that cannot be solved or solved well with the mandated solution (shoving square pegs into round holes).

What do initiatives have anything to do with all this? First, let me say what I mean by an “initiative”, it’s a strategy to fundamentally improve the quality of the software solutions we develop. Examples of initiatives include striving to become platform independent, moving to component based software engineering, or finding ways to utilize cloud computing technologies. Initiative are positive, awesome things. So why am I calling them out?

The devil of initiatives is in how they are implemented. Too often those making the decisions hear an initiative and interpret it as a mandate, or feel that the best way to achieve the goal of the initiative is to make mandates in support of it. This is completely counterproductive to an initiative. The problem with mandates are that they can overrule the best solution to a problem. If the purpose of initiatives is to improve the solutions we develop, then it doesn’t make sense to build inferior software in support of the initiative.

It’s not just the quality of software that can suffer from mandates. Mandating a software engineer make the wrong design decision in support of an initiative creates frustration for them. It is counter to everything an SE stands for. It just doesn’t feel good. This frustration can affect teamwork. When you are developing a component under a mandate and all you are doing is churning out kluges in attempts to find a way to fit that square peg into that round hole, more likely than not the members of your team will have a hard time understanding why you aren’t done building it yet and why it isn’t of the highest quality. You begin to hold up their progress, and then they get frustrated with you. Suddenly everyone’s opinions of each other begins to drop, and you are left with a dysfunctional team.

So, what’s the solution? We need to understand initiatives and stop the mandates!!!

The best way to view an initiative is as a green light to extra devote money and resources in support of it, but only when it makes sense to do it. For instance, if you have an extremely performance sensitive application, and the initiative is to move development to python, don’t mandate it be written in python! C is far better suited for performance sensitive applications. Bottom line, you can achieve the goal of an initiative by allocating resources and money towards the pursuit of it, not mandating that everything be done in support of it.

Tagged with: , , ,
Posted in Advice, C, Software Engineering

Legacy System Replacement

Its funny, when you tack the “legacy” adjective to a system it suddenly is something that must be replaced. However, like any other asset whether or not a legacy system should be replaced is determinable by a cost-benefit analysis. The following matrix is a good way to decide whether to replace a legacy system:

  High Business Benefit Low Business Value
High Quality Maintain Maintain
Low Quality Replace Scrap

If a legacy system is a high quality system then there is no need to replace it. This follows the old cliché: “don’t fix what isn’t broken”. If a system has low quality and low business benefit (measured by how many people use it and how vital it is to their job) then its better just to scrap the system and not replace it. The only place where it makes sense to replace a legacy system is when it has a high business benefit but is of low quality.

This was a question on my last exam, I felt it was worthwhile information.

Tagged with: , ,
Posted in Software Engineering

Training SE’s: Top-Down Vs. Bottom-Up

As I blogged about a few weeks ago, I am now responsible for training new developers at my place of employment. The training program is in need of an overhaul and I am exploring options. One of the things I have considered is switching from a bottom-up approach to training to a top-down.

Let me explain.

Currently we train developers on the language we use, then we teach them to use some of the libraries, then we start adding some business logic, and then they go on to learn more about the business as the develop. Basically, we start at coding (bottom) and work our way up to learning business. I would like to change this so that they start by learning a bit about the business, and then work their way down to coding. They would start by learning about the functional business areas, then about IT and the SDLC processes, then a high level look at the systems that support the business, then an architectural overview followed by an in-depth look at the architectural mechanisms used in the areas they will be working in, and end it all by learning how to code in the languages used in their areas.

The bottom-up approach has some problems. First, the languages taught are not always the languages the developer will be using in their functional area. They don’t really get an understanding of where they fit in the company and how the company uses what they develop. These things would be corrected with a top-down approach.

So… I am really looking for opinions, any thoughts out there on what’s the best way to train new developers?

 

Tagged with: , , ,
Posted in Advice, Career, Education, Software Engineering

New Responsibility At Work: New Developer Training

After a few weeks of uncertainty, I found out today that I will be taking charge on new developer training. The chance to help new developers succeed is something that I have desired to do since I first found my passion for software development. This is the reason one of my professional goals is to one day teach a course in computer science or software engineering at a University. Taking on developer training allows me to fulfill some of this desire, and gain experience in how to successfully educate others (something I will need if I hope to be succesful in my professional goals).

In addition to training, this responsibility includes full involvement in the recruitment process including on campus interviewing and participation in recruitment events.  I look forward to this because it gives me a chance to develop my communication skills as well as providing the opportunity to interact with the community of developers outside of my employer.

I will be starting work on this immediately as we have a new developer starting next week. I will be working with the previous and interim trainer to get me caught up to speed. In April I will be attending the MICS conference at St. Scholastica in Duluth Minnesota. Then I have a little over a month before we welcome in larger group of new hires and interns.

If you look at my professional goals you will see that my first goal is to take on a least one major initiative at my current employer within 2 years. I believe that this responsibility will afford me the ability to carry out this goal. The training program for new developers is in need of a facelift, and that this task is exactly the type of iniative I am looking for.

Posted in Career, Education, Software Engineering, Uncategorized

Weaknesses

When I was in college and was starting to seriously look to where I was going to go after I graduated, I had a mock interview with the CIO of an insurance company in Minnesota. She was a graduate of BSU and had offered her time to help students improve their interviewing skills. As most interviews go (even mock interviews) I was asked about perceived weaknesses. My answers involved lack of experience in Linux and Mac OS along with not knowing a foreign language. These weaknesses were calculated, and she called me on it. She advised me to reflect on true weaknesses and develop them for my next interview. One of my strengths is that I take the advice of people I respect and admire to heart, and this particular piece of advice I took seriously. I reflected on my experiences and took it upon myself to discover my true weaknesses.

At my next interview (for an internship at the company I am now at) I came ready with one true weakness. I am a poor reader. Not only that, but I am weak when it comes to absorbing knowledge through reading. With this weakness it may hard to believe that I made it through my undergraduate degrees in Computer Science and Philosophy (especially Philosophy) with as great of marks as I did. In the light of this weakness are the strengths that allowed me to overcome it. I was able to succeed in college because I am both an exceptional auditory learner and I excel at absorbing knowledge through “tinkering”. My father never understood why I could memorize song lyrics quickly, but I couldn’t remember what I read in a history book, his observation is indicative of these strengths and weaknesses.

I think that this weakness has subsided as of lately.  I have started to read more, especially books about software development, and I have felt myself improving at this. However, I thought it prudent to return to the concept of exploring weaknesses because it is important to know who you are. There is nothing wrong with weaknesses. We all have them. Being aware of them enables us to be honest about our abilities, and being honest about abilities is a desirable trait.

Though my interviews are long over and who knows when/if I will have another one, I still feel as if it is important that I continue to think about my weaknesses. I have shared this first weakness, and I plan to share more as I reflect upon them. For now, I have assignments to do.

Posted in Advice

My New Popcorn Maker!

PopcornMakerSo, for my birthday I purchased a popcorn maker. This is something I have wanted for a while, but I had always figured they were very expensive. Not so! I picked up this Lincoln Eight Ounce Popcorn Maker on Amazon.com for $165.95. I also have Amazon Prime (which is a great service for anyone that buys online a lot) so my 2 day shipping was covered (I don’t know what the shipping would be). It does a pretty good job.

I picked also picked up the “Great Northern Popcorn, 8-Ounce Portion Packs” at Amazon as well. These I would not recommend however, as the popcorn did not taste as good as some I have tried. Plus the coconut oil was all congealed :(. Maybe my next batch will be better (as the first bag I loaded was missing the salt!).

This is about the right size I wanted, and I am happy with my purchase. I would recommend this to anyone in the market who is looking for a popcorn maker, but thinks they are too expensive. It’s perfect for a home theater or bar. It would probably do well for a small concession stand as well!

Does anyone know of a good source of popcorn, oil, flavoring for these kind of machines? I am looking for any suggestions! 🙂

Tagged with: , , ,
Posted in Uncategorized

Semi-Object Oriented C Development – Part 4

An Alternate Way…

I haven’t added to this series in a while, but a friend of mine named Cole left a comment on my first post that I thought I should share. He recommended an alternative implementation for typedefing your “C” object.

For those of you that remember from part 1, I typedef’d my C object as a void pointer…

typedef void *Vector2;

This works well, but, as Cole points out, it is horrible for debugging because you cannot see what the members of your C object are while in the debugger. This would still be the preferred choice if your library is closed source and a debug version will not be available. However, if you are developing an open source project or internal company code there is a better option that works with the debugger.

Cole suggests you forward type your struct as follows:

struct _Vector2;
typedef struct _Vector2 *Vector2;

Then, in your C code you would define things as such:

struct _Vector2 {
     float x;
     float y;
};

Vector2 vector2_Create()
{
     Vector2 vector2 = (Vector2)malloc(sizeof(struct _Vector2));

     if (vector2 == NULL)
          return NULL;

     vector2->x = 0.0f;
     vector2->y = 0.0f;

     return vector2;
}

void vector2_Destroy(Vector2 this)
{
	if (this != NULL)
		free (this);
}

/* and so on... */

For the skeptic, I tested this and it is perfectly acceptable. It works wonderfully, thank you for this one Cole :).

Some Other Tricks…

Type Casting

If you also remember, I suggested you use a C preprocessor macro to type cast your C object. Something like this:

#define _TVECTOR2(this) ((_Vector2 *)(this))

I have since abandoned this in favor of type casting when you receive the variable. If you remember the Normalize “method” from part 2

/* in the .H */
void vector2_Normalize(Vector2 this);

/* in the .C */
void vector2_Normalize(Vector2 this)
{
     _Vector2 *vec2 = ((_Vector2 *)this);
     double sizeSq = 0.0;
     float scaleFactor = 0.0f;

     assert(this != NULL); /* fyi assert.h */

     sizeSq = (vec2->x * vec2->x) + (vec2->y * vec2->y);
     if (sizeSq < 10e-20) return;

     scaleFactor = 1.0f/(float)sqrt(sizeSq);

     vec2->x *= scaleFactor;
     vec2->>y *= scaleFactor;

     return;
}

I type cast “this” as a (_Vector2 *). This can be done automatically by typing it as _Vector2 * in the parameters (only in the .C file) as such:

/* in the .H */
void vector2_Normalize(Vector2 this);

/* in the .C */
void vector2_Normalize(_Vector2 *this)
{
     double sizeSq = 0.0;
     float scaleFactor = 0.0f;

     assert(this != NULL); /* fyi assert.h */

     sizeSq = (this->x * this->x) + (this->y * this->y);
     if (sizeSq < 10e-20) return;

     scaleFactor = 1.0f/(float)sqrt(sizeSq);

     this->x *= scaleFactor;
     this->y *= scaleFactor;

     return;
}

This is easier than using the _TVECTOR2 macro.

NOTE: If you use the method described in the “An Alternate Way…” above then you don’t need to type cast at all because the offsets will already be known to the compiler.

C++ Compiler

If you are using C++ to compile any of my C object examples, using “this” as the name of the C object will not work because it is a reserved word. I would suggest using “self” instead.

Character Limits

At my job I use a C compiler that only recognizes the first 31 characters of a subroutine name. For instance, if you have the following function:

void connectionObject_SetReconnectAttemptCount(ConnectionObject this, int count);
void connectionObject_SetReconnectAttemptDelay(ConnectionObject this, int delay);

The C compiler will ignore anything after 31 characters, so the routines above look like this to the C compiler:

void connectionObject_SetReconnectAt(ConnectionObject this, int count);
void connectionObject_SetReconnectAt(ConnectionObject this, int delay);

The problem here is obvious, these subroutines will map to eachother. This can be overcome by using the C preprocessor to shorten the subroutine names…

/* In the .H file */
#define connectionObject_SetReconnectAttemptCount connObj_SetRecAttCnt
void connectionObject_SetReconnectAttemptCount(ConnectionObject this, int count);

#define connectionObject_SetReconnectAttemptDelay connObj_SetRecAttDel
void connectionObject_SetReconnectAttemptDelay(ConnectionObject this, int delay);

The C preprocessor will replace the long over 31-character subroutine names with the shortened form you define. As long as connObj_SetRecAttCnt and connObj_SetRecAttDly are not present somewhere else in your libraries then you are golden!

Tagged with: , , , ,
Posted in C, Coding, OOP
Categories