Category Archives: Software Development

Pair programming with Sankalpa

One of my favorite ways to develop software is to do it together with others. Pair programming has always been a motivating and fun activity for me, but some pairings work better than others.

When our team was formed we decided to pair program and rotate partners every day. I had lots of fun programming with Milina, Asanka, Manoj and Chamath, but my favorite session was the one I had with Sankalpa. In this session, we achieved something that we would be helpless to do alone.

The task Sankalpa and I was working on was to include information from a calendar in Confluence in a date picker in a web application. As we sat down, I was dreading the integration part. Integration is often dreadful. More than anything, I wanted to hide from the problem. But with Sankalpa sitting next to me, I didn’t feel that I could give up, so I suggested we took a look at our Confluence calendar to get started. Sankalpa was at the keyboard and he found a “calendar feed” where I hadn’t thought of looking for it.

Looking at the feed, I exclaimed “Oh, I know this – this is vcalendar”. A quick Google later and we had found a library for parsing vCalendar in JavaScript. We quickly finished the code to adapt it to our desired format and moved to the date picker.

I was at the keyboard and I had used a date picker library called jQuery datePicker before. We quickly integrated it and I proudly refreshed the page to show the calendar events in the view! But it turned out that all the functionality that depended on picking a date was now broken.

I started grumbling about how I was much more comfortable with jQuery than with AngularJs. Unfazed, Sankalpa mentioned that Manoj had gotten the date picker to work with AngularJs in an earlier project. “Hey, Manoj, where did we use this date picker?”

Having much more experience with AngularJs than me, Sankalpa integrated the code into our code base and everything was working.

All in all, I had expected this to take 2-3 times as much effort. If we had been alone, we would probably wouldn’t have the courage to start with the integration right away. If he had been alone, Sankalpa probably wouldn’t had known how to parse the vCal feed. If I had been alone, I probably would have searched the Internet for hours to find out how to make AngularJs play well with jQuery date picker.

Together, we did what neither of us could have done alone. (At least not anywhere close to this quick)

Posted in English, Extreme Programming, Non-technical, Pair programming, Software Development | 1 Comment

The economics of reuse

If need the same functionality in two projects, you should reuse code between them, right? Or should you? For as long as there has been a profession of software engineering, we have tried to achieve more reuse. But reuse has both a benefit and a cost. Too often, the cost is forgotten. In this article, I examine the economics of reuse.

True story: One of the earliest projects to embrace object-oriented programming in the 1990s did so with the goal of maximizing reuse. The team responsible for creating the company wide framework used the following formula for calculating the value of their work:

[Value of reuse] = [numbers of uses of framework] * [value of the framework to reusers] – [cost of developing the framework]

This formula is obviously correct, but this is where they went horribly wrong: The organization said [value of framework to reusers] = [cost of developing framework]. In other words: The more expensive it was to create, the more valuable it was to use.

We have clearly progressed beyond this thinking. A more updated formula would say: [value of framework to reusers] = [cost of developing the feature in question]. But even this is too optimistic.

No library comes for free to its users. At the very least, you have to discover the features and learn about the details. The cost of reusing depends on many factors, such as the quality of the framework and the documentation and also upon the type of feature. A complex algorithm with a simple interface is cheap to use, while most domain-specific frameworks require relatively much work to reuse. We can express this as a reuse value factor, likely between 90% and 50%. For most cases, my guess would be at about 75%.

So we have:

[value of reuse] = [number of users] * ([cost of feature] * [reuse value factor]) – [cost of developing the reusable component]

What about the other important factor: [cost of developing the reusable component]?

It’s easy to assume that the cost of developing a feature in a framework is equal to that of developing the feature in an application, but on further analysis shows that this is far from true. A reusable component needs more documentation, it needs to handle more special cases and it has a slower feedback cycle. This cost is actually substantial and may mean that it costs between 150% to 300% or more to develop a feature for reuse. Personally, I think the reusability cost factor lies around 300%. And the lower this number, the higher the cost factor of reuse is likely to be, because that may mean we skimped on documentation etc.

A revised number would be:

[value of reuse] = [number of users] * ([cost of feature] * [reuse value factor]) – [reusability cost factor] * [cost of feature]

Or

[value of reuse] = [cost of feature] * ([number of users] * [reuse value factor] – [reusability cost factor])

The more complex formula actually lets us make a few predictions. Let’s say we assume a reuse value factor of 75 % (meaning that it requires 1/4 of the effort to reuse a library rather than creating the feature from scratch) and a reusability cost factor of 300 % (meaning that it requires three times the effort to create something that’s worth reusing). This means:

[value of reuse] = [cost of feature] * ([number of users] * 75% – 300%)

This equation breaks even when [number of users] = 4. That means that to get any value from your reused component, you better have five or more reusers or you have to find a way to substantially improve the [reuse value factor] or [reusability cost factor]. Very smart people have failed to do this.

Improving the value:

  • Increase the number of reusers: Simple enough, but when you do, you risk that the [reuse value factor] goes down as the framework doesn’t suit everybody equally well.
  • Reduce the cost of reusing the library: This means investing in documentation, improving your design, improving testing to reduce the number of bugs, handle bug reports and feature requests faster from your reusers – all of which increase your cost reusability cost factor.
  • Reduce the extra work in making the library reusable: The most important way to reduce the cost of developing for reuse is to choose the right kind of problem to solve. Problems with a small surface and big volume are best. That means: Easy to describe, hard to implement. Sadly, most of the juiciest fruit was picked years ago by the standard library in your programming language and by open source frameworks.

On a global scale, reuse has saved the software industry tremendous amounts. In an organization, it can be hard to get the same effect. Reuse comes at a cost to the reuser and to the developer of the reusable library. How do you evaluate and improve your [reuse value factor] and your [reusability cost factor]?

Posted in English, Software Development | 17 Comments

Estimation by stuffing things into boxes

I’ve started using an approach for software project estimation that so far is proving to be fairly transparent, quick and reliable. I’ve observed that within a reasonable degree of variation, most teams seems to complete about one “user-relevant task” per developer per calendar week.

There are so many theoretical holes in my argument that there’s no point trying to cover them all. The funny thing is that it seems to work fairly well in practice. And to the degree that it’s dirty, it’s at least quick and dirty. The only thing I will address is that one of these “user relevant tasks” is smaller than a typical application feature.

Most importantly: Most teams never get it right on the first try. Or they spend too long gold-plating everything. Or both.

This article shows an example of estimating a fictive project: The Temporary Staffing System.

The high-level scope

Let’s say that our organization has come up with the following vision:

For a temporary employment agent who wants to match candidates
to client needs, the Temporary Staffing System is an
interactive web application, which lets them register and
match candidates and positions. Unlike competing systems
this lets us share selective information with our clients.

We come up with the following flow through the application:

  1. A new company wants to hire a skilled worker for a temporary position
  2. Administrative user adds the client details to the system
  3. Administrative user adds client logins to the system
    (perhaps we also should let the clients log in with LinkedIn etc?)
  4. Client logs into the application and completes new position
    description, including skill requirements
  5. Temp agency adds a worker to the system
  6. Temp agency proposes the worker to a position registered by a client
    (in the future, the worker may register themselves!)
  7. Client gets notified of new proposals (via email)
  8. Client views status of all open positions in the system
  9. External to the system: Client interviews candidate, request further
    information and makes a decision whether to hire or not
  10. Client accepts or rejects the worker in the system
  11. As worker performs work, they register their time in the system
  12. At the end of a billing period, the system generates billing information
    to accounting system
  13. At the end of a salary period, the system generates salary information
    to the accounting system

Some of these steps may be one user story, some may be many.

The top of the backlog

We choose some of the most central parts of the scope to create the beginning of the backlog. In order to accommodate for the learning as we go along, the first draft of our backlog may look like this:

  1. Experimental create open position
  2. Experimental list positions
  3. Simplified create open position
  4. Simplified list positions
  5. Complete create open positions
  6. Complete list positions

An “experimental” version of a story is a functionality trivial version that touches all parts of the technology. In the case of these two stories, perhaps we have the application leave the logged in client as a hard coded variable. The story may only include writing some of the fields of the positions, maybe only title and description.

The Simplified version may add more complex properties, such as skills from a skill list or it may add filters to the list.

The complete version should be something we’re prepared to put in front of real users.

By revisiting a feature like this, we have the chance to get the feedback to create a good feature without gold-plating.

Continuing the backlog

We add enough of the other stories to the backlog to cover an interesting part of the scope:

  • Basic create client account
  • Complete create client account
  • Basic login admin user
  • Basic login client user
  • Complete login client user
  • Basic add worker
  • Complete add worker
  • Basic propose worker for position
  • Complete propose worker for position
  • Complete confirm worker for position
  • Basic enter timesheet (in this version temp agency enters on behalf of worker)
  • Experimental billing report
  • Basic billing report
  • Basic salary report

This functionality should be enough to have a pilot release where some clients and workers can be supported by the new system. Or we may complete the backlog with complete versions of all functionality, worker login and perhaps a polished version of a feature or two.

Adding the non-functional tasks

There are some tasks that we want to plan some extra time for. I generally find that many of these tasks are tasks that customers understand quite well:

  • Attend training on CSS (the team is rusty in design skills)
  • Basic layout and styling of web pages
  • Complete layout and styling of web pages
  • Polished layout and styling of web pages (they want it really nice)
  • Locate slowest pages and make some performance improvements
  • Deploy solution to target platform
  • Deploy demo version to wider set of stakeholders
  • Deploy pilot version
  • Exploratory test of complete flow

Planning the project

In this example project, we have five team members plus a coach/project manager on half-time. Since our team will be working in pairs, we want to work on three functional areas per week. This way, we can avoid huge merge conflicts. The team agrees to plan for five stories per week, but only three the first week, because things generally go slower. Here is the top of the completed backlog:

  • Week 1: Experimental create open position
  • Week 1: Experimental list positions
  • Week 1: Attend training on CSS
  • Week 2: Simplified create open position
  • Week 2: Simplified list positions
  • Week 2: Basic create client account
  • Week 2: Basic layout and styling of web pages
  • Week 3: Basic login client user
  • Week 3: Deploy solution to target platform
  • Week 3: Basic add worker
  • Week 3: Basic propose worker for position
  • Week 3: Basic enter timesheet (temp agency enters on behalf of worker)
  • Week 4: Experimental salary report
  • Week 4: Complete layout and styling of web pages
  • Week 4: Complete create open positions
  • Week 4: Complete list positions
  • Week 4: Deploy demo version to wider set of stakeholders
  • Week 6: Exploratory test of complete flow
  • Week 7: Deploy pilot version

Presenting the plan

Working through the list gives us a complete timeframe of just over 6 weeks for full feature set for the pilot release. To cover realities of life, we probably want to plan for at least one week of slack or even more, depending on the strength of our commitment and the consequences of being wrong.

This gives a plan indicating 7 weeks times 5 people at 40 hours per week plus a 50% project manager at 20 hours per week or a total of 1540 hours.

I generally find that after a pilot release (or even before it), things change a lot. So I don’t invest much time into planning this.

Tracking the development

The true strength of a plan like this appears when you start running the project. Each week, the team will report on which stories they completed. This allows us to adjust the plan to actual progress.

On the flip side, the weekly planning comes down the team and the customers agreeing on the definition of a story. The vagueness of “basic add worker” is by design! But the team should agree on what they mean by “experimental”, “simplified”, “basic”, “complete” and “polished”.

Conclusions

In this article, I have showed a quick and accurate way of coming up with a project forecast, complete with time and cost estimates. It’s easy to see and react to deviations from the forecast.

A few critical critical observations support this methodology:

  • I never believe a developer estimate other than “by the end of the day” or “by the end of the week”. (Don’t talk to me about hours!)
  • Estimating in hours is a silly way to get to project costs. Any hour-based estimate is always prodded and padded before magically turning into cost. Instead, estimate number of features, feature per week and cost by week.
  • Visiting a feature multiple times lowers total cost due to less gold-plating and investment of in poorly understood areas. It also improves the success of the final feature
  • The ambition of a feature (that is, how many times we will visit it) is a more reliable indication of cost than developer gut feeling

I’ve left many questions on the table, for example: What about architecture? What is meant by a “simplified” user story? How to deal with deviations from the forecast? Feel free to grill me for details in the comments to the article.

“So what will it cost?” Using this simple method to lay out your project forecast week by week, you can give a better answer next time someone asks.

Posted in English, Extreme Programming, Software Development | 1 Comment

C# Tricks: Slimming down your controllers

This blog post is dedicated to my colleague Seminda who has been experimenting with how to create simple and powerful web applications. Thank you for showing me your ideas and discussing improvements with me, Seminda.

I find many C# applications have much unnecessary code. This is especially true as the weight of the business logic of many applications are shifting from the backend to JavaScript code in the web pages. When the job of your application is to provide data to a front-end, it’s important to keep it slim.

In this article, I set out to simplify a standard MVC 4 API controller by generalizing the functionality, centralizing exception handling and adding extension methods to the DB set that is used to fetch my data.

If you generate an API controller based on an existing Entity and remove some of the noise, your code may look like this:

This code is a simplified version of what the API 4 Controller wizard will give you. It includes a GetPerson method that returns a person by Id, PostPerson which saves a new person, GetPeople which returns all people in the database, GetAdminsInCity, which filters people on city and type and DeletePerson which finds the person with the specified Id and deletes it.

I have replaced DbContext and IDbSet with interfaces instead of the concrete subclass of DbContext makes it easy to create tests that use a double for the database, for example MockDbSet.

Generify the controller

This is easy and safe as long as things are simple. As a general tip, rename you methods to “Get”, “Post” and “Index” rather than “GetPerson”, “PostPerson” and “GetPeople”. This will make it possible to generalize the controller thus:

The generic EntityController can be used for any class that is managed with EntityFramework.

Exception handling

I will dare to make a bold generalization: Most of the bugs that remain in production software are in error handling. Therefore I have a very simple guideline: No catch blocks that don’t rethrow another exception.

The actual handling of exceptions should be centralized. This both makes the code easier to read and it ensures that exceptions are handled consistently. In MVC 4, the place to do this is with a ExceptionFilterAttribute.

We can thus simplify the EntityController:

The HandleApplicationException looks like this:

This code code of course add special handling of other types of exceptions, logging etc.

DbSet as a repository

But one piece remains in PersonController: The rather complex use of LINQ to do a specialized query. This is where many developers would introduce a Repository with a specialized “FindAdminsByCity” and perhaps even a separate service layer with a method for “FindSummaryOfAdminsByCity”.

If you start down that path, many teams will choose to introduce the same layers (service and repository) even when these layers do nothing and create a lot of bulk in their applications. From my personal experience, this is worth fighting against! Needless layers is the cause of a huge amount of needless code in modern applications.

Instead, you can make use of C# extension methods:

The resulting controller method becomes nice and encapsulated:

The extension methods can easily be reused and can be freely combined.

Conclusions

With these tricks, most of your controllers would look something like this:

That’s pretty minimal and straightforward!

I’ve showed three tricks to reduce the complexity in your controllers: First, parts of your controllers can be generalized, especially if you avoid the name of the entity in action method names; second, exception handling can be centralized, removing noise from the main application flow and enforcing consistency; finally, using extension methods on IQueryable<Person> gives my DbSet domain specific methods without having to implement extra layers in the architecture.

I’d love to hear if you’re using these approach or if you’ve tried something like it but found it lacking.

Posted in C#, Code, English, Software Development | 4 Comments

Using pair programming to combat project waste

  • Less Overproduction (of unused functions in interface between team members)
  • Less Waiting (for the only person who knows a particular area)
  • Less Motion (as everyone gets more skilled)
  • Fewer Defects (because two pair of eyes see better than one)
  • Less Over-processing (from duplicate responsibility)
  • Less Inventory (as team works on focused set of features and tasks)
  • Less Transportation (handoffs inside a story)
  • Less Underused talent (as everyone gets to share their skills)
Posted in English, Extreme Programming, Non-technical, Pair programming, Software Development | Leave a comment

Why I stopped using Spring

My post on DZone about Humble Architects sparked somewhat of a controversy, especially around my disparaging comments regarding Spring and Dependency Injection Frameworks. In this post, I expand on why I stopped using Spring.

I was one of the earliest adopter of Spring in Norway. We developed a large system where we eventually had to start thinking about things like different mechanisms for reuse of XML configuration. Eventually, this evolved into the @Autowire and component-scan which took away the problem with huge configuration files, but in return reduced the ability to reason about the whole source code – instead isolating developers in a very small island in the application.

The applications tended to blossom in complexity as either the culture, the tool, the documentation or something else made developers build unnecessary layer upon unnecessary layer.

Later, I tried to build applications without a Dependency Injection framework, but taking with me the lessons about when to use “new”, when to have a setter or a constructor argument and which types were good to use as dependencies and which created coupling to infrastructure.

So I found that some of the instincts that the DI container had given me made me improve the design, but at the same time, I found that when I removed the container, the solution became smaller (which is good!), easier to navigate and understand and easier to test.

This leaves me with a dilemma. I found that the cost of using the container is very high – it creates a force towards increasing complexity and size and reduced coherence. But at the same time, it taught me some good design skills as well.

In the end, creating a coherent, small system is to me of much higher value than to create one that is decoupled just for the sake of decoupling. Coherence and decoupling are opposing forces and I side with coherence.

At the same time, I found that the culture around dependency injection has a very strong preference for reuse. But reuse does introduce coupling. If module A reuses module B, module A and B are coupled. A change in B might affect A for better (a bug fix) or worse (an introduced bug). If the savings from the reuse are high, this is a trade-off worth making. If the savings are low – it is not.

So reuse and decoupling are opposing forces. I find myself siding with decoupling.

When there is a conflict, I value coherence over decoupling and decoupling over reuse. The culture where Spring is in use seems to have opposite values.

Posted in English, Java, Software Development | Leave a comment

Can we learn to restrict our work to a budget?

I’ve previously talked about the idea of shifting from estimates to budgets.

The fundamental point of this article is that it’s more useful to control costs than to predict costs.

The problem of this argument is whether it’s possible to develop software in that way. How will the relationship between the developer (or supplier organization) and the customer (or the customer organization) have to change? Is this a chance we’re able to make?

In my popular style, here is a typical dialogue:

  • Customer “… So, we’re going to change the patient appointment request form to include the social security number of the user and use this field in all the relevant processes. Can it be done in two weeks?”
  • Developer “I believe so. But we probably can’t automate everything in this case.”
  • Customer “That’s all right, just do what you can within that timeframe”
  • A week passes
  • Developer “I’ve done a lot of work, but I haven’t got anything to show you yet.”
  • Customer “You’ve spend half the budget, and we’ve got nothing to show for it? That’s it, I’m pulling the plug. Throw away what you’ve done and let’s work on something else.”

Meanwhile – in another universe

  • Developer “Let me show you: I’ve got the field in the appointment request form and it’s also displayed when looking at the appointment details. I’ve tested this automatically and manually, and deployed it on the acceptance test environment.”
  • Customer “Great work so far. These are the next improvements we want (in order of importance): Make sure that non-privileged users never see the number, include the field in the invoicing process and make the input form validate the social security number. Then integrate the field in other processing as well.”
  • Developer “Sure thing. I’ll talk to the users for details.”
  • Another week passes
  • Developer “I’ve fixed the security issue by checking the user privilege before displaying the field. I’ve also included the field in the invoice process. But I didn’t have time to add the validation. Everything is tested, of course.”
  • Customer “Great! We’ve spent the budget, so we’ll stop there. The validation is actually pretty important, so I’ll considering adding a new user story to the budget for that.”

In this story the developer had to produce a minimum story before spending half the budget. This ensures that we get something when the budget runs out. The developer had to finish one expansion of the user story at a time until the budget was expended. And then stop! When the customer wanted one of these sub-features bad enough, he had to create a new user story, thus expanding the scope of the project.

Can we learn to work in this way? As a developer, can I learn to organize my work so that I have something to show for it after just half the budget? Can I learn to keep track of the time I spend so well that I know when I’m over budget? And can I have the discipline to stop once the budget has been spent? As a customer, can I learn to accept that the developer will do the best he can within my budget and accept that?

Posted in English, Extreme Programming, Software Development | Leave a comment

Lean architecture

Lean thinking describes seven classical sources of waste 無駄:

  • Overproduction: Making stuff that nobody buys
  • Over-processing: Creating stuff that is more fancy than what the customer wants
  • Transport: Moving stuff from one place to another in order to create it or give it to a customer
  • Motion: Expending unneeded effort while creating stuff
  • Defects: Having to redo work because it wasn’t done right the first time
  • Inventory: Storing stuff waiting to be worked on more
  • Waiting: The time stuff is just sitting there, waiting to be worked on

Often an eight is added: Unused talent

It’s always fun (but sometimes risky) to draw analogies with other fields. In an enterprise information application (that is: what most people are working on these days), “stuff” is the data that your application shuffles between users, databases and other systems.

Here are the seven wastes of enterprise information application architecture:

  • Overproduction: Any code that is not executed by an end user. In the extreme case, many applications contain code that is not “reachable” and so can never be executed. In other cases, it may be functionality that is available, but never used
  • Over-processing: Do you really need to scale to a million concurrent users for a company internal application? Do you really need an application that is used get data for monthly reports to have 98% uptime?
  • Transport: How many classes in the code touches a single piece of data before it’s displayed to the user (or stored in the database (or sent to another system)). How many systems does a piece of data touch before it’s done processing?
  • Motion: How many times do you transform data into another representation?
  • Defects: Do you accept data that may be in error? How do you deal with old data that contains errors?
  • Inventory: I don’t know… maybe are you deleting obsolete data?
  • Waiting: Do you have batch processes that run daily? ‘Nuff said

(As an aside about transport. Did you know: In C#, it’s requires substantially less work to save and find data with EntityFramework than it does to call a web service? If system A “helps” system B by provide a data access service, system A is actually causing more work for system B. It’s not just an investment with low ROI, it’s got negative ROI!)

Remember: Not all production is overproduction and not all transport is wasted transport. But much is.

Posted in English, Software Development | Leave a comment

Humble architects

Humility is not a very common trait with software architects. After having worked with a few awful architects and recently with a very pleasant one, I’ve compiled a few of my experiences in the way every architect loves: As a set of rules.

Rule 0: Don’t assume stupidity

It seems like some architects assume that developers, if left to their own devices, would behave like monkeys. In my experience, this is very rarely the case. The only situations where I’ve seen developers do something stupid is when silently protesting against an architect. If you follow this rule, the rest are details.

Rule 1: You may be wrong

When reviewing someone’s design idea, I prefer to try and ask questions that are honestly open. Maybe I think the developer have overlooked a critical fact, for example concurrency. There are a few different approaches to the situation:

  1. Architect: “You can’t do it that way, because it breaks the code guidelines”
  2. Architect: “You can’t do it that way, because it won’t be safe when there are several users”
  3. Architect: “Have you thought of how it will work with several users?”
  4. Architect: “How does your solution address the situation of several users?”

Dear architect: Please rate these approaches from the one least to the one most likely to get a best possible system. (Tip: This is an easy task, even though many architects fail it routinely)

Rule 2: Be careful with technology

Every technology comes with a cost. Many technologies come with an infinitesimal benefit.

Here’s a list of technologies that I’ve experienced as having consistently higher cost than benefits, and thus will never use (if you don’t know them, don’t worry. The point is the number): JavaServer Pages, Java Server Faces, JAX-WS, Hibernate, Spring, EJB, Oracle SOA Server, IBM WebSphere, Wicket, Google Web Toolkit, Adobe Flex, JBoss jBPM, JMS (all implementations), JBoss.

Here’s a list of technologies that I happily use: JUnit, Jetty, Joda-time, Java Standard Edition.

Here’s a humble exchange that you may want to try and copy:

  • Architect: You should use technology X
  • Me: I’ve looked at technology X, and I don’t see how it will help me solve the business problem
  • Architect: What do you mean?
  • Me: Well, this is what we need to do: ….. And this is what technology X assumes: …. I don’t see how they match.
  • Architect: So what do you suggest using instead?
  • Me: Um… I think we can solve this with plain Java. As a matter of fact, I made a pretty good proof-of-concept yesterday evening.
  • Awesome architect: Cool. Let’s use it.

Rule 3: Consistency isn’t as important as you think

If I’d have a penny for every time I’d hear this….

  • Architect: “Yes, I know this way may seem clumsy, but you have to do it. You see, if you don’t, the system becomes inconsistent and impossible to maintain”

Granted, I don’t often work with maintenance, but I know that when I deal with any system, the most difficult part is understanding the business logic for that system. Whether system X (which has one set of business logic) and system Y (which has another) are consistent is very low on the list of things that make me lose sleep.

The fact that system X is horribly complex because it has a dozen layer to be consistent with system Y – now this is something that does make me want to pull out my hair. Different contexts have different trade-offs.

Oh, yes: Remember Rule 0? Assume that the developers in a given context are trying to create a good solution for that context.

Oh, yes, another thing: I’ve never seen something that was incomprehensibly complex in the small become maintainable just because we grew to become big.

Oh, yes, yet another thing: If a programmer really runs screaming away from the code because some of it had one style of curly braces and some had curly braces in another style, I’m going to lose all faith in humanity.

Rule 4: Bottom-up consistency beats top-down consistency

There is one way I’ve been able to create more consistency inside a system:

  • Create a reference application with an architecture that is easier to follow than to break. If you do this well, the developers will shake their head at the very idea of deviating from the architecture. Unless they really need to. In which case it’s okay.
  • Foster a culture of cross-pollination: Developers who see each other’s code have more consistent code than developers who just see their own code. Pair programming, code reviews and tech sharing sessions all foster cross-pollination.

Rule 5: Tactical reuse in across systems is suboptimization

Reuse creates coupling. If system X and system Y reuse some functionality and system X needs that functionality to be modified, this will affect system Y. At the very least, the team working on system X must decide to make a private fork of the reused functionality, which means that it’s no longer really reused. At worst, system Y will get a bug because of a change in the reused functionality.

When you reuse across systems, what you reuse should either be stable (say: the Java SE platform, or something so stable that you definitely didn’t make it yourself) or strategic. By strategic reuse, I mean services that integrate information and not just duplicate functionality.

In other words: Reuse should either be use or integration. Duplication is your friend.

Rule 6: Separate between rules and dogma

There are three reasons to have a rule in any coding standard:

  • Unsafe: The code has a bug that will manifest under some (non-theoretical) circumstance
  • Incomprehensible: “I” don’t understand what’s going on
  • Heresy: The code is written in a style some person doesn’t like

Pop quiz: If you have a rule that says “all fields must have a JavaDoc comment”, is that a safety issue, a comprehensibility issue or a heresy issue? What if the standard uses this example:

What about the rule that says “no newline before an opening curly brace”? What about the rule: “the style used for curly braces should be consistent”? Is it addressing Unsafe code, Incomprehensible code or Heresy?

We should be more concerned with writing appropriate code for the situation and less concerned with appeasing the Gods of Consistency.

Rule Omega: Be humble

In the years I’ve worked with software development, I’ve seen more harm done by software architects than help. As a professional role, I think we’d save money if we got rid of them (us). Even if we still paid their salaries.

When you’re in a profession that causes more harm than they prevent, you have two options: You can try and improve, or you can pray that nobody notices.

Posted in English, Java, Software Development | Leave a comment

Micro-Scrum: A stamp-sized version of Scrum

“Show frequently what you’ve done to someone who cares”

Are you working in the way you are because it’s a good idea, or just because someone told you to do it? I increasingly hear experienced professionals at Agile conference bemoan the blind adherence to the techniques of Scrum without understanding the principles and values that make it work. I also encounter many software professionals who are overwhelmed by the amount of things that they are asked to do. The result is the questions “are we ‘Agile’?” and “should we be doing ‘Agile’ or not?”

I die a little bit inside when people say “should we do Agile or not”. The assumptions behind this question are all wrong: That there is one way to “be Agile”, that learning from Agile methods like Scrum requires that you use everything in those methods, and that there are good reasons to be “not Agile”. All of this is wrong.

To me, the most essential lesson that the Agile manifesto tries to communicate is that of Feedback. And frankly, if you’re ignoring feedback on your project, you’re stupid. There are different constraints around the feedback on different project, but essentially, delaying feedback is delaying critical learning.

The most essential manifestation of feedback in Scrum is the Sprint review, or demo. No matter if you’re calling what you do “Scrum”, “Kanban”, “Cowboy coding”, “Waterfall” (which is more like Cowboy coding than a real process) or just “the way we do stuff here”, you will get benefit from showing what you’ve done to someone who cares frequently. For some projects, “someone who cares” may be an end user, while for other projects it’s not feasible to involve end-users frequently. On some projects, “frequently” may mean every day, other projects may not be able to do more than once every month. You may even find that nobody cares about what you do. If that’s the case, surely you can find more relaxing ways of doing it.

When you are showing what you’ve done to someone who cares frequently, you can improve. You can think about how to show it better, how to have the show more accurately reflect what you’ve done, how to involve more people or people how care more and how you can do it even more frequently. Some of the techniques of Scrum may help you do that, but use whatever source of inspiration you like.

No matter if you’re excited about the word “Agile” or not, if you’re not getting feedback, you’re not only non-Agile, you’re non-smart.

Posted in English, Extreme Programming, Software Development, Technology | Leave a comment