Monday, November 09, 2009

XCode Quick Keys or Key Short Cuts

When learning any new programming environment there will be lots of experimentation. Often being unfamiliar with the IDE becomes a frustration while trying to learn a new language like Objective C or learn new classes and libraries found in Cocoa.

Frustration with the IDE may cause you to give up. I know my impatience is the culprit!

So, here are three Quick Keys that were not obvious to me, and I was too impatient to drop down all of the menus or read the key stroke preferences to discover.

Switching between the source file and header file:
Option Command Up Arrow (Opt Command UpArrow)

Commenting code "in" or "out":
Command Forward Slash (Cmd /)

Move to the next argument in the auto-completion list:
Control Forward Slash (Control /)

⌘ Command key
⌃ Control Key
⌥ Option Key (aka Alt Key)
⇧ Shift Key

Sunday, November 08, 2009

Objective C Method Signatures and Method Keywords

Objective C "looks" a bit different than the object oriented languages I have used previously. Object C and Pascal (Remember Lightspeed C and Pascal, single inheritance languages), C++, Java, and C#. I have not taken the time to learn Small Talk and so I do not know if Object C takes after Small talk or not.

I noticed that method signatures in Objective C have multiple "method keywords".

What is a method keyword? It is a word that proceeds the parameter type.

Here is a method from NSMutableDictionary:

-(void)setObject:(id)anObject forKey:(id)aKey

The method keywords are "setObject" and "forKey".

Because of many years developing in languages other than Objective C I find myself in the habit of decorating the method name. For example, if I have a method that inserts an object into some container and the object is stored by name then the method name would be like this:

void InsertObjectWithName (object insert, string name)

This habit shows up in my Objective C code.

@interface Foo : NSObject


-(void) insertValueWithName:(id) value : (NSString *)name;


However, in Objective C you can have more than one method keyword.

@interface Foo : NSObject

-(void) insertValueWithName:(id)value :(NSString *)name;
-(void) insertValue:(id) value withName :(NSString *)name;

(I intend the two methods to do exactly the same thing. Both are valid Objective C methods.)

This additional method uses two method keywords:

-(void) insertValue:(id) value withName :(NSString *)name;

At first I thought I liked either style the same. The more I use XCode the more I like the method with two method keywords because of how auto-completion reads.

Here is the single keyword style in XCode with auto-complete:

Here is the multiple keyword style in XCode with auto-complete:

For me I find that the method with two keywords reads clearer. Also I like the way the separation and highlighting of the auto-complete looks when multiple method keywords are used.

So, I am going to use multiple keywords in Objective C and avoid techniques that I use in other programming languages.

Slightly Off Topic

Syntax is just syntax and it doesn't take long to figure out the need to use brackets to invoke a method, or better said, to send a message to an object. For me it is still a bit painful to anticipate how many open brackets that I will need and I have to go back and forth in the source code inserting them as necessary.

It goes something like this:

Foo *myFoo = [Foo alloc]

Oh yeah, I better call the init...

Foo *myFoo = [Foo alloc] init]

Oh yea, I have to have another bracket at the front...

Foo *myFoo = [[Foo alloc] init]

And on and on I go back and forth inserting brackets where I need them.

Tuesday, September 15, 2009

How do you rotate an NSButton, NSTextField, or NSView?

How do you rotate an NSButton, NSTextField, or NSView?

First, you can do it and it is fairly easy to do! Here is what it will look like!

There are two NSView methods available to do this.

In OS 10.0 you have:

- (void)setFrameRotation:(CGFloat)angle

And in OS 10.5 you have:

- (void)setFrameCenterRotation:(CGFloat)angle

For some the above information will be sufficient. For those desiring more information please continue to read this posting.

Create a new "Cocoa Application". From the File menu choose "New Project" and then select "Cocoa Application".

Name and save the project whatever you want. I named my project "RotatedControl".

In XCode add to the "Classes" folder a "New File". Choose "Objective-C class".

I named my class "Controller"

Add your IBOutlets to your new class. Here is my code:

// Controller.h
// RotatedControl
// Created by Geoffrey_Slinker on 9/13/09.
// Copyright 2009 Area 51. All rights reserved.


@interface Controller : NSObject {
IBOutlet NSTextField *textField;
IBOutlet NSButton *button;

@property (retain) NSTextField *textField;
@property (retain) NSButton *button;

- (void) awakeFromNib;


// Controller.m
// RotatedControl
// Created by Geoffrey_Slinker on 9/13/09.
// Copyright 2009 Area 51. All rights reserved.

#import "Controller.h"

@implementation Controller

@synthesize textField;
@synthesize button;

- (void) awakeFromNib
//[textField setFrameRotation:45.0];
//[button setFrameRotation:30.0];

[textField setFrameCenterRotation:45.0];
[button setFrameCenterRotation:-45.0];



Now open the NIB file. In XCode double click "MainMenu.xib" found in the folder "NIB Files". This should launch Interface Builder (IB).

Add an "Object Controller" and set its class to be the class type you created above. In my case I set it to "Controller". See "Where is the Classes Tab" for detailed information.

Still in IB add a Button and a Text Field to your Window. Just select them from the Library of Objects and drag them onto the Window.

Now "hook up" the IBOutlets of the Controller to the controls on the window.

You can see I have "wired" or "connected" the button outlet to the button on the window. The same was done for the text field.

Also wire the the "Referencing Outlets" delegate to the "Application". The "Application is above the "Controller" in the MainMenu.xib view.

If I haven't missed any steps then from XCode just build and run the application.

Monday, September 14, 2009

Where is the Classes Tab in Interface Builder? It has been removed.

Where is the Classes Tab in Interface Builder? It has been removed.

Interface Builder 3.1.2 does not have it. I do not know which version was the first to "not have it" but I know my version doesn't.

This can cause some confusion with tutorials, texts, books, etc., that refer to the Classes Tab.

Many examples refer you to a screen shot of IB's UI like this one:

Well, stop looking for it because it is gone.

Interface Builder 3 looks like this:

For instance, if you are creating a class that has some IBOutlet's then create that class in XCode, add the IBOutlet's that you desire. Launch Interface builder by doubling clicking your NIB file in XCode.

Select an Object from this panel:

Drag the "Object" to "Main***.xib" window, the window that has "File's Owner, First Responder, etc".

Make sure this new object is selected and from the Tools Menu open the Identity Inspector. There is a menu at the top labeled "Class". Click this and select the class that you created in XCode. The one I created I named "Controller", so I select "Controller" from the Class drop down menu.

I hope that helps clear up things for some.

Friday, August 14, 2009

Out of Browser and Desktop Applications

I have been researching the use of Silverlight and Adobe Air for creating a cross platform desktop application.

Michael Wolf blogged on this topic: Silverlight Out of Browser deep dive.

My research has discovered that there are many that want a development platform that will run on different Operating Systems. For my interest those systems are Mac OS X and Windows.

Not only is it desirable to run on different OS's but also to run in a browser.

This desire is based on code reuse and development effort. If the same code can run "in browser" and "out of browser (OOB)" businesses view this as a significant win.

The limitations of OOB solutions are justified and at the same time make it unrealistic to use the solution as a desktop application that has high system resource utilization. Don't misunderstand, I think the demand is great and will cause solutions to be developed. Certain companies/products can justify the "glue code" that is necessary to get to system resources but many can not.

For now, those companies that have desktop applications that need to run on various operating systems, don't forget Java. Microsoft and Adobe have no reason to mention Java for cross platform solutions.

For later let us watch the direction of Silverlight and Air, and at the same time watch for new solutions in the Platform as a Service (PaaS) arena.

PaaS technologies and Web Application technologies that I am watching include:
  • Cappuccino, Objective-J, Cocotron
  • SproutCore
  • Windows Azure
Silverlight and Adobe Air do what they were designed to do well enough. Using either to make desktop applications is "living on the edge".


Monday, July 20, 2009

There is no Agility without timely Acceptance

There is no agility without timely acceptance of features or changes. Need I say more?

If you answered no then don't waste your precious time reading any further.

For the rest of you I will continue.

Lack of timely acceptance of features/changes requires detailed requirements, which in turn leads to traditional waterfall development. "What?" you say. "Yes!" I say, "Big Up Front Requirements gathering which necessitates flow charts, prototypes, etc..., and other such activities will become necessary."

When a feature/change is completed and the users of the product run the features on real data and on real hardware and finds issues the developer will still remember the changes needed for the implementation. Therefore the developer is more likely to correct the issues in the right places.

When a feature/change is completed and the users do not exercise the new code for days, weeks, or months the developer may have difficulty correcting any issues found. Why? The most common cause of difficulty is that the developer doesn't remember the ramifications of the changes. The developer will have to find the changes in the revision control system and review the check-in comments and maybe even walk through the code in the debugger just to get their mind wrapped around the code again. Even worse (and yet very common) is that the changes were built upon and used by other aspects of the product. Now the developer or developers have to figure out all of the possible side effects of working on this code because it is coupled to other features!

At this point the developer will say, "Enough is enough. Next time you tell me exactly what you want in great detail. You spend your time and effort instead of you spending mine."

Why will the developer say such a thing? Continuing with the above scenario (based on real world experience) the developer knows that since the acceptance test of this feature has taken so long that the odds are that the related features have not been used either. It is possible that the related features work correctly, and in that case the code has to remain the same for those features and all new code has to be developed for the feature in question. It is possible that none of the related features built are correct and that some should be one way and some another. Do you get the picture now?

Such work is very costly. It costs time, money, and morale.

Maybe I will blog about Morale Debt some day (previous posts have been made on Code Debt, Market Debt, Product Debt, etc).

Without timely acceptance of features/changes the costs of corrections increase. In an attempt to avoid issues caused by untimely acceptance the natural tendency is to require more detailed specifications, requirements, and designs. When this happens you can officially kiss Agility good bye.

Acceptance of features/changes by users is more important to me that having unit tests! If you made me choose between users giving timely feedback on acceptance or having unit tests I would take the users timely feedback.

Timely acceptance, in my opinion, is less than three days.

If you do not have timely acceptance of features/changes then you can be sure your development process is not Agile. Being Agile shouldn't be the goal, but being efficient should be the goal. Maybe I should rename this post to: "There is Waste without timely Acceptance". Yes, I like that title better!

Tuesday, June 23, 2009

What can I do to help us succeed?

Have you ever been working on some difficult issue and have someone come up and say "What can I do to help us succeed?"

I am not going to talk about the "peace and love" version of this story where everyone magically finds synergy because caring people have joined together.

"What can I do to help us succeed?" Some of the possible responses are :
  1. "Us, where did this 'Us' come from?"
  2. "Nothing, shut up and quit bugging me!"
  3. "You caused this mess I am fixing, get out of my face!"
  4. "You could find a new job!"
  5. "Do you know of any companies hiring?"
  6. "You could learn to mind your own business."
  7. "Instead of talking about how we might work around here, why don't you just let me work like I know how!"
Sometimes the above responses may be the correct response. However it might not be wise to say these things out loud.

When someone is under stress trying to get something done that is urgent a well intending person might interrupt with the question "what can I do to help us succeed". This well intending person needs to realize that a response like one of those listed above may be accurate and the best thing to do to help is to stop asking or looking for ways to inject themselves into the solution and allow the situation to run its course.

Does that make sense?

Friday, April 17, 2009

People CHOOSE Process

To me it is not people versus process or even process versus people. People choose the process they will follow and choose how closely they will follow it.

The choice of process should be based on issues, problems, and concerns that need to be confronted. This is a basic thought of all of the Maverick papers I wrote years ago.

[Label: 1]
As the choices are implemented, the implementers (the people), watch to see if the issues are being corrected. If so, they continue forward, if not they re-evaluate and re-implement.

These implementers are the founders and early adopters.

From this point there are many paths that can be taken, one path of evolution is that there are those that come after the founders and early adopters and these people are the ignorant believers.

These ignorant believers become dogmatic and assume they are the guardians and defenders of this newly founded ministry. This is an opportunity to roust those that have held the power, those with which many feel were the cause of some problem. Any failure of the previous regime will be used as a reason to oust them and adopt the new methodology with it's new set of leaders.

Once the new authorities have taken charge they must institute a means of policing actions and judging conformity. Here is were Process versus People begin.

Now the rules have been established and the means of judging conformity in place the next thing is to rank people according to their compliance. Decisions are made on actions to be taken if someone poorly complies. These are known as the consequences.

Now the authorities have the power to fire, with-hold rewards, reward, and promote.

There are those that come in even later. They do not understand why the process is the way it is. They do not understand why the people who are in charge where chosen to be in charge or how they got to be in charge. Others of these new-comers seem to fit in and thrive, while some fit in and perform with mediocrity.

If an employee refuses to follow the process then the machinery that has become the process will act upon that employee.

Most likely there will exist some employees who seem to have an almost magical ability to fight the process but never seem to reap the consequences. I have seen this many times. Usually two or three people can project the reasons why they do not conform in such a manner that they are not punished.

At some point a group of individuals will sit down and analyze the current situation and list a set of problems, issues, and concerns. They will use their experiences to devise a plan to address the issues and they will create an opportunity to put those plans into play.
[GoTo: Label: 1]

If you are not the creator of a new process then you should study the processes that are in practice. As you study them you should try to "fit" the process to the ways you choose to do things and they ways you imagine things should be done. Then you should try to work somewhere that uses that process. This will allow you to fit in, to understand, and most importantly to imagine the next step in the evolution of that process. This notion of the gathering of people based on some common ground has often been attacked. It has been said that this idea limits diversity. That is a statement that has not been proven true. Once you gain experience and seek understanding in the underlying goals of a process and the problems, issues, and concerns being addressed then you can build on a solid foundation.

If you choose to be a mediocre participant then be prepared for the process to "grind you up and spit you out". If you choose to halfheartedly do your job, put in your eight hours, do as little as you can to avoid work and to avoid consequence you will eventually find yourself facing situations of poor performance rankings and you may not even know why and did not even see it coming. If you assume that your co-workers are not studying and experimenting on their own time you are mistaken. There are those that seek to gain knowledge and experience on their on time and dime.

As you study on your own do not become another breed of the dog-matic (get it, dog breed). Do not bring the latest thing you have read about into the work place and shout, "We should do this now!" First experiment with it, use it, and understand the problems, issues, and concerns it addresses. Then do a gentle analysis of your work and see if these problems, concerns, and issues exist. THEN see if the current process has methods to address these issues. Often there exists a way to address the issue and no-one is doing it. If there is no current way of addressing the issue then look at the current system and figure out how to create an interface to use to plug this new method into place. Do not be a bull in a glass/china shop.

Some say that people are never the problem. My level of enlightenment is not sufficient to see things that way. Maybe some day I will see it that way, or maybe not. Maybe I am ahead of them already. The problem is there is no way to know for sure!

At this time I believe this: People make the choices, and people enforce the consequences. (I am not talking about people choosing to break physical laws but people choosing to break impositions.) People choose their response to the consequences. People choose how to judge and they do so inconsistently and imperfectly and therefore the results vary.

(This was originally posted to the Extreme Programming Users Group)

Thursday, March 26, 2009

Runtime Adaptation

Runtime Adaptation is the ability for an object to increase and grow into another type of object at runtime.

In most Object Oriented languages an object is "born" with a set of abilities. Typically this is done through inheritance or interfaces.

class JackOfAllTrades : IPerson, IHandyMan, IPlumber, IBrainSurgeon, IAutoMechanic

JackOfAllTrades can be used in any method where an IPerson, IHandyMan, IPlumber, IBrainSurgeon, or IAutoMechanic is needed.

At runtime JackOfAllTrades can not become IDentist. JackOfAllTrades can not learn to be a dentist and cannot act in the role of a dentist.

Runtime Adaptation allows JackOfAllTrades to become a full fledged dentist at runtime and retain this ability carrying forward. JackOfAllTrades does not have to use another object that implements IDentist and then have that object do work in his behalf.

Just as JackOfAllTrades wants to increase in ability JackOfAllTrades may want to loose abilities as well and give up plumbing.

The acquisition of new abilities could be considered "Behavior as a Service" and I could vend the IDentist capabilities to your JackOfAllTrades.

Just a small glimpse of the sandbox in which my mind plays.

Tuesday, March 17, 2009

Design by Use to the rescue... AGAIN

Just a quick note. Yesterday I was bogged down in a serious piece of code re-work. It was the changing of part of a framework. Since it is a framework, everything built on it is affected by change.

I was changing from an Event based model to what I term a "usage" based model. Remembering the advice of Stroustrup that resource acquisition is allocation I used this knowledge to begin to make the changes. I became stuck very quickly. Stuck in the overwhelming amount of code and all of the many classes that had overridden these framework interfaces.

Once again I remembered, Design by Use. When I did this the paralysis ended and the solution began flowing. I started at the level from which the new model/framework would be called and I wrote the code as if the new framework already existed. Often the old code was harvested into the new methods where appropriate. Everything flowed and it was more like writing new code with no dependencies than re-working code. Why? Because that is what it became, new code!

All of you must try Design by Use! It has really made a difference for me. When ever you are stuck try it out!

Monday, March 16, 2009

Solutions and Opinions

Applying my knowledge of Computer Science and recalling experiences from years of application I find myself contemplating "solutions" and "opinions".

When I am writing code, when I am actually typing in the code, I am working towards a solution to a problem.

These problems are constrained to be solved in the environment in which they exist. For instance the code has to be in C#, it has to work in Windows Forms, etc. There are other constraints such as memory usage, and performance. And still there are constraints in how the code will present itself to the user through the User Interface. The User Interface is constrained by accepted and common interactions defined by the domain of the product. What I mean is a Word Processor has a certain set of UI expectations and constraints placed on it by the user community just because it is a word processor.

Solving problems as a developer is a difficult task. The breadth and depth of knowledge and experience must be large and ever increasing. I have seen many people never gain enough knowledge and experience necessary to continue to advance as a software developer. Some of these people were aware of their situation and made appropriate career choices. Others were oblivious to their position and found themselves locked into dead end tasks or even fired.

Currently I find myself re-working some code. The code came into existence because of a short coming in the design. The code was the results of considering what would be the simplest thing to do while fitting into the current design. As with all code once it is wrote it becomes part of the environment in which any new code will exist and has influence over how the new code will be implemented.

Honestly my head seems to hurt at the thought of re-working the code so that current needs for improved resource usage can be realized.

The burden of the solution rests upon me. The idea of sharing the problem with others and getting their opinion on how to develop the solution is interesting and maybe even therapeutic but ultimately shallow. In all of my years of experience I have never seen anything more than a superficial "pre-flight" check from having others review a design that is based upon a large set of code that the reviewers have no real knowledge of the inner workings, couplings, code-arounds, and all the other things that make up that piece of working code. If the code had a boundary with some other system then it would be beneficial to talk to the owners of the other systems. This current problem is completely encapsulated in "my" code.

As I sit here focused on the problem at hand a tinge of jealousy seems to rise up. Jealousy of what you ask? Jealousy of those around me working on things where opinion is sufficient and no further effort is required.

The solution I have to invent has to meet those many constraints I mentioned before. It will be domonstrable that I have met the requirements through running the profilers and passing the programmer's tests. I literaly sit at this desk for hours without end and yes it is hard.

So, I am a bit jealous today of the buzz I hear going on around me where people are making decisions based on opinions and where people can declare "It must be done like this" on one day and then the next day say "It now must be done differently" and those that actually have to "do the doing" are different people. Do they feel more important? Do they feel more job satisfaction? Do they feel less pressure? Do they have the burden of constantly improving? Do they have the burden of constantly replacing the core tools of their trade with new and shiny tools that are completely incompatible with the old tools and basically no better (i.e. Fortan -> Pascal -> Modula 2 -> Ada -> C -> C++ -> Java -> C#). I am absolutely sure I could have created the current product that I am working on using Structured Analysis and C and it would be just as good as the one we have now that uses Object Oriented Design and C#.

So, I sit here, improving the resource utilitization of the product and I wonder what difference does it all make. Someone else in the product could be making a choice right now that uses all of the RAM I am trying to save. Somewhere someone is making yet another GUI toolkit to which I will have to eventually port the current system.

Oh yeah, I remember my motivation. A pay check. Yep that must be it. Because it surely is not all of the opinions I hear every day and change with the current weather.

Wednesday, February 25, 2009

Always "Releasable"

Recently I was trying to describe code that is always releasable.

One simple criteria is if someone came to a developer and said "We are going to doing a build this afternoon and release it to the public" the developer would not say "Well you need to wait because I need to go back in and change _____".

Can code be inter-iteration releasable? That is, right in the middle of the iteration can a build be made to release? It can be. I have found because of troublesome code merging issues caused by source control I often check in things that are not complete or done. These things compile and even pass their tests but the task is not finished. I check in often because I have had significant "fights" with source control not recognizing "new items" because the project file was modified by another developer, etc. If the "sand box" or "shelf set" were better I would not be inclined to check in to the main line of the code until the task was complete.

So, code can be always releasable if only completed tasks are checked-in. Incomplete tasks are safely backed up and stored in a sand box or shelf set or jump drive or something.

Thursday, February 12, 2009

Software Quality: Customer Facing -vs- Developer Facing

There are, at least, two different types of quality to software. Customer facing and Developer facing.

Customer facing quality is defined by the customer and has to do with any aspect that the customer finds important. If there is some aspect of a software product that the customer dislikes for any reason the customer can deem the product to be low quality. For instance, if the software takes too long to load at startup the customer may complain about the quality of the software. If a button in a GUI interface is not where the user expects it then the customer may complain about the quality of the software. In these two examples often the user will say, "Did anyone test this before it went out the door." This line of questioning also leads many to think that enough testing will find all quality issues.

Developer facing quality is defined by the developer when making judgments about the code or the systems upon which the code is developed. Code quality is often discussed in terms of such things as no duplication, no go-to's, no global variables, etc. Code quality also encompasses such things as which database was used, which OS is the target, etc. Yet another aspect of code quality has to do with the architecture, design, and metaphors used to compose the software.

Let me be clear, the customer does not care about the code quality. (Now if you are developing software libraries, tool kits, frameworks, etc., and provide the code to your customers then this is obviously different.) To the customer it is all product quality. If a customer finds problems with their software and the customer actually has the opportunity to talk to the developer of the software and the software developer says, "Well the problem is we have way too much duplication in the code and there is this static class filled with values that get changed all over the place, yadda yadda yadda" all the customer hears are EXCUSES.

Does this mean that the developer's concerns and efforts to have a level of quality in the code are ultimately worthless? Well, if you think that then I suggest you are trying to convince yourself of something other than reality, whether you are denying the fact that you don't really have enough money or skill to be in the business or some other reason you want to blame development. Developer's have compelling reasons to address code quality issues.

Does the customer care if the software was developed by the greatest programmers? The first answer is "NO", they do not care. One reason is they don't care because they do not understand how software is made and how the making of the software is tied to the customer facing quality.

Should developers try to get customers to care about code level quality? No because I feel it is not possible to communicate such things.

So, if I am correct that customers do not care about code quality and it is difficult to imagine that the majority of customers could be enlightened. So then, what is the purpose of this posting?

There are at least two types of quality spoken of when talking about software. Often one person is talking about customer facing quality and the other is talking about developer facing quality. It causes endless discussion which get no where!

In my opinion these items are realities of software:
  1. The customer cares about product quality.
  2. The customer DOES NOT care about code quality.
  3. The customer believes product quality is the results of testing.
  4. A product can have minimum "product quality" issues and be filled with "code quality" issues.
  5. A product with poor code quality will not be able to keep up with competing products in an agressive market space.
  6. A product with poor code quality will not be able to attract or retain the talented software developers needed to move the product forward
  7. A product with great code quality may receive a low quality product rating by the customers.
  8. The customer will leave a product that lags behind the competition.
  9. The customer will spend their money how they see fit.
  10. A company with more money can produce more low quality code and be able to afford the incurred costs in order to push a company with less capital out of the sector.
  11. A company with more money can address customer facing quality issues through the use of customer service activities such as phone support, books, tutorials, managed users groups, etc., thus the company's wealth is sufficient to afford the costs of issues with product quality.
This list could go on and on.

In the developer community can we at least be clear when we are talking about customer facing quality versus developer facing quality? Call it out when it is not clear which type of quality is being discussed or maybe it is yet another facet of quality still.

Is it obvious that this is a complex system with many inputs and feedbacks. Cash is king, up to a point. Product quality is king, up to a point. Code quality is king, up to a point.

Monday, February 02, 2009

Where does Quality Code come from?

I have commented and blogged about code quality many times. A recent discussion has influenced me to review my old posts.

A current blog entry entitled "Quality-Speed Tradeoff - You're kidding yourself" asserts that quality is a primary factor in obtaining and sustaining a high speed of software development.

The Maverick Software Development blog contains an archive of the most interesting posts from the old Maverick Software Development group. On that blog can be found "Quality Code" where an analogy is presented to show some of the various definitions of a quality automobile.

So, where does quality code come from? Another question could be where does poor/low quality code come from?

If those questions can be answered could we arrive at the "cause" of poor/low quality code and the "cause" of high quality code?

Another question that comes to mind is this, "Can a high quality software product be made of low quality code?" This question causes one to suppose that the quality of the software product and the quality of the code may be independent. Is this true?

Consider read-ability to be an aspect of quality code. Readable code is another term for code that conveys an accurate message of what the code is actually doing. It is beyond "intent revealing". Intent revealing code is supposed to convey the intent of the programmer. What if the programmer did not meet their intentions? Readable code makes it apparent to what is actually taking place.

Can a quality software product be developed with code that is not easily read?

Here is a consideration for you. Assembly languages are not easily read by the human programmer. There have been quality software products developed in assembly language. Therefore quality software products can be developed with code that has poor readability and therefore a quality software product can be developed with poor/low quality code.

Can poor/low quality code be modified correctly as fast as high quality code?

Consider the development of what is termed "high level languages". One of many reasons that languages such as AGOL, Pascal, COBOL, C, Ada, ...., C# and Java have been developed was to decrease the burden and cost of understanding existing code that needed modification. Simply stated it is that high level languages are more readable. Given this known aspect of programming it can be stated that readable code can be modified correctly faster than less-readable code. Therefore quality code allows for increased speed when maintaining code, or stated another way, quality code takes less time to modify than poor/low quality code. Can this be said for all facets of quality for code?

Consider another attribute of quality code. Quality code has little or no duplicated code. Let's go back to some of the previous questions. Can a quality software product be developed with low quality code? Can a quality software product be developed with duplicated code? I propose that the answer is again YES.

Can code with duplication be correctly modified as fast or faster than code with little or no duplication? The answer is NO. The time to locate the duplicate code plus the time to insert the modification in each location are just two of the factors of the increased time needed to deal with duplicate code. Once again code quality is related to the speed in which correct modifications can be made to the code.

Does it take longer to initially develop high quality code? In the case of readable code I propose that in the worst case it takes no longer to develop readable code than non-readable code and that in most cases it takes less time. In the example of assembly code versus a high level language I propose that most modern software applications can always be developed faster in a high level language. In the case of duplicate code I propose that it takes less time to create the appropriate non-duplicate containing solution than it does to duplicate the code. Let us step back a few short years before refactoring functionality in modern IDE's. Many times I had developed code that I had "inlined" what was conceptually a function. After I had developed it and stepped through it with the debugger until I was satisfied I would then copy the code and make a function and paste it in. It was easy and didn't take any longer than it would to have duplicated it else where. I have now given two examples where quality code takes less time to develop than poor/low quality code.

Finally, where does quality code come from? Well the obvious answer is from people that understand code quality. So, where do people come from that have that understanding? I dare say they are the result of much work and effort on their part to gain experience, knowledge, techniques, and tools which allow them to excel in their profession.

I propose that the level of quality of code is directly related to the level of experience, expertise, and professionalism of the one writing the code. If you want to experience the benefits of quality code then you must first find experienced professionals or allow your developers the opportunity to become those desired professionals.

Tuesday, January 27, 2009

Birds and Stones

If you kill too many birds with one stone there will be no birds left.

Monday, January 12, 2009

Leadership, Wisdom, and Experience

A leader has enough wisdom to allow others to gain experience.

Thursday, January 01, 2009

One Year...

One year ago I canceled all of my subscriptions to software development groups. One year ago I stopped attending any local users groups. One year ago I went back to being nothing more than a programmer.

I did that for a few reasons.

One reason was that I decided the posting opinions and comments to all of those groups seemed to exhibit attributes of an addiction. It became too important to be heard on a forum where there is no human interaction and that is filled with miscommunication, misinterpretation, and seemingly endless rehashing.

I canceled my subscriptions so that I would not be able to post. I have lurked on the groups that have rights that anyone may read without being a member. Because of not being able to post I did not feel the need to read the group several times a day. I probably checked the groups twice a month and then I quickly scanned the topics to see if anything new or interesting was being discussed or if any particular posters that I like to monitor had any comments.

Wow, if you have read to this point I am amazed. I mean really, who cares what one software developer rambles on about.

I have focused on software development. At work I am just another programmer. During the last year I have written tens of thousands of lines of code. Yes, that much. I have thrown out about the same amount as well. I have developed some of the most sophisticated code that is highly optimized for the specific platform in which it runs. I have invented two new visualization techniques for specific types of data. I have invented new "widgets" for manipulating data.

All of the code has been developed using the "Design by Use" approach.

I have complex objects that have tests to exercise them. I have thousands of lines of code without a single test (in the current way of thinking of tests).

I have not encouraged any process what-so-ever, in the traditional sense of process. I don't remind anyone to have a stand-up meeting. I haven't moved a single card on the white board from one category to the next.

During this time I have became "online" friends with a few of our key customers. Yes, a lowly developer talking directly to customers! Surely the end is nigh.

During this year I have been quite satisfied with work. And for me work has been writing software. Not talking about writing large systems, but actually writing them. This system is multi-threaded and difficult to manage because it needs lots of system resources. It runs on a database and has complex data structures. Just the other day I had to refresh my memory on the shortest path problem for graphs.

Here is an interesting observation. The code seems to be just as solid, reliable, and efficient as code where I used some software process and lauded the processes' use and talked of its advantages. "Heresy! Surely he has strayed because of his absence!" cries the dogmatic process evangelist!

During this time I have been carefully observing every aspect of the team I work on and other teams in the company. What have I learned? A lot.

I have learned "selective publication of favorable results" seems to dominate discussion in the field of software development. The "causal" argument is predominant in software process.

I have learned that skill in programming is the most important aspect of all. A skilled programmer can seemingly ignore process and still produce quality code. Another thing I have observed is that software process does not seem to improve the core skills of the software developer.

For example the core skills of a software developer would be such things as understanding the order of an algorithm, when to use a hash table, etc.

I have noticed some "younger" developers have the idea that you can just find something on "Code Project" and it will do. I ask them, "Can you maintain what you download?" By that I mean do you understand how it works because you are responsible for that code and no excuses will be sufficient to relieve you have the responsibility that the code works correctly.

A programmer with a sound understanding of algorithms, data-structures (or containers), threading, and other essentials is more capable of writing solid code than one who does not have good coding skills that follows some software processes religiously.

I recommend the reading of "Unskilled and Unaware of It: How Difficulties in Recognizing One's Own Incompetence Lead to Inflated Self-Assessments".

In my opinion the greatest thing that can be done to improve software development is to improve the fundamental skills of the software developer.

This year of observation has me currently of the opinion that I would rather have a team of solid programmers that follow some informal process than a team of average programmers that adhere to every tenant of some software process.

Those that have followed my posts and ideas know that I am not talking about a bunch of cowboy programmers and empire builders. So, If you are imagining that I am justifying such behavior you are incorrect and I have not been clear and for that I apologize.

I advocate improved education, processes that promote the gaining of experience, and improved reasoning skills.

"The haphazard approach to training in reasoning from evidence in our society is, in its way, astounding — and merits a call to action. Better reasoning from evidence is substantially teachable but seldom directly taught, much less required. It should be central to curriculum requirements, at both graduate (advanced) and undergraduate (basic) levels — if not sooner."

"After all, sound reasoning from evidence is (or ought to be) fundamental for persons in each arena in which decisions should be rendered, or inferences drawn, on evidence: not just doctors and scientists, but journalists, policy makers — and indeed citizens, whose determinations affect not solely their own lives but others', each time they parent, serve on juries, and vote."
Reasoning from Evidence: A Call for Education, Beatrice Golomb, MD, PhD

This year I am going to become involved again in Software Process. Not in the way I used to be involved. Times have changed and so have I.

What have you learned in the past year? What did you do to learn it?