Agile FAQs
  About   Past Conferences   Training   Home  

 
Managed Chaos
Naresh Jain’s Random Thoughts on Software Development and Adventure Sports
     
`
 
Microblog Feed
    Previous Feeds...
    Recent Thoughts
    Comments
    Tags
    Blogroll
    Categories
    Archives
    July 2009
    M T W T F S S
    « Jun    
     12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
    RSS Feed
    Add to Technorati Favorites

    Interested in Agile Training/Consulting for your Organization?

    June 29th, 2009

    Recently I’ve been getting a lot of request for Agile Training and Consulting. Unfortunately the expectations from the training are not clear for me. Most people approach me saying, “we want a TDD training” or “we want a Project Management training“. Once I start talking to them & their team (or even worse sometime during the training), I realize the topic we’re discussing is not their biggest issue. I get a feeling that most organizations have not done their homework to figure out what they really need and how they should go about it. They might have heard somewhere that ‘blah’ will help them and they want to jump on it.

    Few months ago I started doing readiness assessments before my trainings. (I’ve also started doing assessments after my training so see if the training was effective.) But I have realized the assessment is not enough. So I’ve started asking the following questions even before the assessments:

    • What kind of issues your organization is facing currently and do you think Agile will help you? If yes, why so?
    • What is the current strength of your development team? How experienced is the team with software development? Does your team understand all aspects of software development?
    • What is the current process you follow? In other words, from the inception of an idea to the delivery of the same, what are the various steps and people involved?
    • What is a day in life of a team member (one per role please)?
    • How do your stakeholders (including customers) perceive your team/organization? Currently how do you gather feedback from them?
    • How would you rate the technical know-how of your team? Are they able to quickly resolve technical challenges and respond to changing priority of the business?
    • Is your team/organization open to trying out things that might seem non-intuitive/illogical? For Ex: Letting the requirements evolve during the project, not freezing them? Letting tests drive your design?
    • And so on …

    Luckily a lot of organizations don’t get back to me with answers for these questions. This is really good for me, because this acts as a filtering criteria. I feel I would have wasted my time training/coaching this team. There are others who are in much more need and are more receptive to what I’ve to contribute.

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    Killing Speculative Generality Code Smell

    June 26th, 2009

    I’m just reviewing a project’s code. I found a common pattern used in their code base. Every class implements an Interface. Each interface is only implemented by one class. Even more interesting, this interface is not exposed outside. In other words, its not exposed as part of the API.

    Then my question is

    Why do we need the interface? Why can’t we just use the class directly?

    Apparently there is no valid answer. Some told me,

    • Spring forces you to have interfaces.
      • That’s not true.
    • Some told me their mocking framework does not support mocking a class.
      • This is also not true. Most mocking frameworks come with a class extension. Some new frameworks, don’t even distinguish between an interface and a class.

    Anyway, we don’t need one stupid interface for every class we create. YAGNI. When we need it, we’ll create it. This is one form of speculative generality code smell.

    Go ahead, kill it!

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    Communication in Code #1 Priority

    June 26th, 2009

    Here is a sample of code (happens to be from a test) which I think is not communicative.


    public class ContactNumberTest {
      final String exampleCountryCode1 = "91";
      final String exampleCountryCode2 = "1";
      final String exampleNumber1 = "8012345678";
      final String exampleNumber2 = "2028569635";
      
      ContactNumber phoneNumberA = new ContactNumber(exampleCountryCode1,exampleNumber1);
      ContactNumber phoneNumberB = new ContactNumber(exampleCountryCode1,exampleNumber1);
      ContactNumber phoneNumberC = new ContactNumber(exampleCountryCode2,exampleNumber2);
      
      @Test
      public void testEquals() {
        //Symmetry
        assertTrue(phoneNumberA.equals(phoneNumberB));
        assertTrue(phoneNumberB.equals(phoneNumberA));
        
        //Reflexivity
        assertTrue(phoneNumberA.equals(phoneNumberA));
        
        //Not equals
        assertFalse(phoneNumberA.equals(phoneNumberC));
      }
      
      @Test
      public void testHashcode() {
        assertTrue(phoneNumberA.hashCode() == phoneNumberB.hashCode());
      }
    }

    I know you must be wondering why in the first place someone is writing tests for equals and hashCode. I agree. Its not required. But lets say someone really needs to.

    This is how I would refactor the code to make it more communicative.


    public class ContactNumberTest {
      private final String indiaCountryCode = "+91";
      private final String usCountryCode = "+1";
      private final String cellNumber = "8012345678";
      private final String mobileNumber = "2028569635";
      
      private final ContactNumber indianNumber = new ContactNumber(indiaCountryCode, cellNumber);
      private final ContactNumber sameIndianNumber = new ContactNumber(indiaCountryCode, cellNumber);
      private final ContactNumber usNumber = new ContactNumber(usCountryCode, mobileNumber);
      private final Map users = new HashMap();
      private String userName;
      
      @Test
      public void isSymmetrical() {
        assertNotSame(indianNumber, sameIndianNumber);
        assertEquals(indianNumber, sameIndianNumber);
        assertEquals(sameIndianNumber, indianNumber);
      }
      
      @Test
      public void isReflexive() {
        assertEquals(indianNumber, indianNumber);
      }
      
      @Test
      public void isTransitive() {
        ContactNumber newIndianNumber = new ContactNumber(indiaCountryCode, cellNumber);
        assertEquals(indianNumber, sameIndianNumber);
        assertEquals(sameIndianNumber, newIndianNumber);
        assertEquals(newIndianNumber, indianNumber);
      }
      
      @Test
      public void areNotAlwaysEqual() {
        assertFalse(indianNumber.equals(usNumber));
      }
      
      @Test
      public void equalsIsExceptionFree() {
        assertFalse(indianNumber.equals(null));
      }
      
      @Test
      public void isHashFriendly() {
        addUser(”Foo”).usingKey(indianNumber);
        assertEquals(”Foo”, users.get(indianNumber));
        addUser(”Bar”).usingKey(sameIndianNumber);
        assertEquals(1, users.size());
      }
      
      private void usingKey(final ContactNumber number) {
        users.put(number, userName);
      }
      
      private ContactNumberTest addUser(final String userName) {
        this.userName = userName;
        return this;
      }
    }

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    DesignChef: New Community Launched by Directi

    June 23rd, 2009

    @Directi we are committed to improve the technical community in India. We started off with TechCamp. Next we launched CodeChef. And now we proudly present DesignChef.

    Unlike CodeChef, which was targted at Developers, DesignChef is targeted at Design Professionals like Usability Experts, UX Specialists, Interaction Designers, Front-end developers, etc.

    We welcome you to join this non-profit, community initiative and help us grow it.

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    Misinterpretation of Command and Control

    June 21st, 2009

    Till a year ago, I used to think of command & control as micro-management. Last year I heard Mary Poppendieck give a different perspective about it in her keynote(pdf). That’s when I realized that Command & Control means quite opposite of micro-management.

    We all know Command and Control comes from US Army. During wars, the Commanders would direct (command) the troops on ground about the next move (goal/mission). And then the staff (troops) on ground would figure out the best strategy to achieve the mission. This is very different from micro-management.

    Once the Commanders gives the commands, there is no way s/he can control the situation on ground. Tactical decisions are made by the staff on the war field and strategic decisions are made by Commanders and others outside the war fields, based on their knowledge about situation on the ground.

    (no plan survives contact with the real enemy).

    The heart of mission command:
    Commanders should issue only the most essential orders. These provide general instructions outlining the principal objective and specific missions. Tactical details are left to subordinates.

    “The advantage which a commander thinks he can attain through continued personal intervention is largely illusory.”

    http://www.dtic.mil/dticasd/sbir/sbir043/a30a.pdf

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    Behavior (verbs) as Test Class Names

    June 15th, 2009

    For the last 3 odd years, I’ve been exploring the use of behavior (verbs, instead of Nouns, Test) as my test class names. The verb describes what behavior you expect from your system (program).

    For example for a Veterinarian Information System (system responsible for billing and patient history), I would have tests called:

    ChargeAccountForServices with the following test methods:

    • makePaymentsAgainstAnAccount()
    • completePaymentsResultInZeroAmountDueOnReceipt()
    • incompletePaymentsDisplaysDueAmountOnTheReceipt()

    Another test class: GenerateBillsForClientAccount with

    • notifyIfAccountIsNotDueForPayment()
    • billContainsTotalCostOfAllServicesTaken()

    And another test class: ManageClientVisits with

    • trackAllServicesTakenByThePatient()
    • skipVisitIfPatientDidNotTakeAnyService()

    These tests helped us flush out Objects like Account, Procedure, Visit and so on…. When we started we had no idea we’ll need these objects.

    This style is mostly influenced from a pairing session with Corey Haines post our discussion about “There is no Spoon” @ the SDTConf 2006.

    For more about this approach…read my last post…There is No Spoon (Objects)

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    There is No Spoon (Objects)

    June 15th, 2009

    In OO, frequently, we get caught up in modeling our objects based on our perspective of the real world. Since everyone’s perspective is different we end up with a lot of thrashing and confusion. We end up arguing about these models in the air, baselessly. For example in a Veterinarian Information System (system responsible for billing and patient history), we end up arguing whether the Patient class should have a getShot(Vaccination) or should the Doctor class have a giveShot(Vaccination) method. In the end (when we finally start implementing the system) we realize that it really does not matter who gives the shot or takes the shot. What really matters is that we have recorded what shot was given to which patient. So we end up creating a Visit class with a method called add(Procedure).

    Long story short, there are no real-world objects, its all how we perceive things. If we try to model our software based on our understanding of the real world, the software would also be as complex as our understanding of the real world. Since in software we are dealing with creating abstractions, we really want to focus on behavior rather than Objects. TDD is a great way to do this.

    We start off with a test which expects that our system will exhibit some Behavior. At this point, we don’t know or care about which Object/s will provide this behavior. To make the tests work, we start creating methods that we need from our objects on the test for the time being. Once we have our test working, then we ask yourself, where does this behavior really belong? Sometimes real world objects pop-up. Sometimes we create Objects that don’t exist in real world. This is important because it helps us make our design simpler and more expressive. Slowly we expect more behavior from our system (by writing new tests) which starts flushing out our objects.

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    My Test Naming Conventions: More Examples

    June 14th, 2009
    Other’s Naming Convention My Naming Convention
    itShouldSetAccountToLoggedInWhen-
    PasswordMatches
    matchingPasswordLogsYouIn
    itShouldSetAccountToRevokedAfterThree-
    FailedLoginAttempts
    threeFailedLoginAttemptsRevokesYourAccount
    itShouldNotSetAccountLoggedInIf-
    PasswordDoesNotMatch
    nonMatchingPasswordDoesNotLogYouIn
    itShouldNotRevokeSecondAccountAfterTwo-
    FailedAttemptsFirstAccount
    failedLoginAttemptsOnOtherAccountsDoes-
    NotImpactMyAccount
    itShouldNowAllowConcurrentLogins sameUserCannotLoginConcurrently
    itShouldThrowExceptionIfAccountNotFound onlyUserWithExistingAccountCanLogin
    ItShouldNotBePossibleToLogIntoRevokedAccount userWithRevokedAccountCannotLogin
    itShouldResetBackToInitialStateAfter-
    SuccessfulLogin
    successfulLoginResetsFailedAttemptCount

    So why do I prefer calling my test as nonMatchingPasswordDoesNotLogYouIn instead of itShouldSetAccountToLoggedInWhenPasswordMatches?

    • I think the latter is focusing on implementation details versus focusing on the intent.
    • One should write descriptive names, but the longer the name is, that much more difficult it is to read. I want to write my test names such that they are short and concise. Hence I think the whole itShould<> thing seems repetitive without adding much value.

    More about my test naming convention here…

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    The I Naming Convention

    June 13th, 2009

    I don’t like the I<something> naming convention for interfaces for various reasons.

    Let me explain with an example. Lets say we have IAccount interface. Why is this bad?

    • All I care is, I’m talking to an Account, it really does not matter whether its an interface, abstract class or a concrete class. So the I in the name is noise for me.
    • It might turn out that, I might only ever have one type of Account. Why do I need to create an interface then? Its the speculative generality code smell and violating the YAGNI principle. If someday I’ll need multiple types of Accounts, I’ll create it then. Its probably going to be as much effort to create it then v/s doing it now. Minus all the maintenance overhead.
    • Let’s say we’ve multiple types of Accounts. Instead of calling it IAccount and the child classes as AccountImpl1 or SavingAccountImpl, I would rather refer to it as Account and the different types of account as SavingAccount or CreditAccount. It might also turn out that, there is common behavior between the two types of Account. At that point instead of having IAccount and creating another Abstract class called AbstractAccount I would just change the Account interface to be an abstract class. I don’t want to lock myself into an Interface.

    Personally I think the whole I<something> is a hang-over from C++ and its precursors.

    Some people also argue that using the I<something> convention is easy for them to know whether its an interface or not (esp. coz they don’t want to spend time typing new Account() and then realizing that its an interface).

    The way I look at it is good IDEs will show the appropriate icon and that can help you avoid this issue to some extent. But even if it did not, to me its not a big deal. The number of times the code is read is far more than its written. Maintaining one extra poorly named Interface is far more expensive than the minuscule time saved in typing.

    P.S: I’m certainly not discouraging people from creating interfaces. What I don’t like is having only one class inheriting from an interface. May be if you are exposing an API, you might still be able to convenience me. But in most cases people use this convention through out their code base and not just at the boundaries of their system.

    In lot of cases I find myself starting off with an Interface, because when I’m developing some class, I don’t want to start building its collaborator. But then when I start TDDing that class, I’ll change the interface to a concrete class. Later my tests might drive different types of subclass and I might introduce an Interface or an Abstract class as suitable. And may be sometime in the future I might break the hierarchy and use composition instead. Guess what, we are dealing with evolutionary design.

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark

    Brett’s Refactoring Exercise Solution Take 1

    June 13th, 2009

    Recently Brett Schuchert from Object Mentor has started posting code snippets on his blog and inviting people to refactor it. Similar to the Daily Refactoring Teaser that I’m conducting at Directi. (I’m planning to make it public soon).

    Following is my refactored solution (take 1) to the poorly written code.

    Wrote some Acceptance Test to understand how the RpnCalculator works:

    Then I updated the perform method to


    @Deprecated
    public void perform(final String operatorName) {
      perform(operators.get(operatorName));
    }
     
    public void perform(final Operator operator) {
      operator.eval(stack);
      currentMode = Mode.inserting;
    }

    Notice I’ve deprecated the old method which takes String. I want to kill primitive obsession at its root.

    Had to temporarily add the following map (this should go away once our deprecated method is knocked off).


    private static Map operators = new HashMap() {
      {
        put(”+”, Operator.ADD);
        put(”-”, Operator.SUBTRACT);
        put(”!”, Operator.FACTORIAL);
      }
     
      @Override
      public Operator get(final Object key) {
        if (!super.containsKey(key)) {
          throw new MathOperatorNotFoundException();
        }
        return super.get(key);
      }
    };

    Defined various Operators


    private static abstract class Operator {
      private static final Operator ADD = new BinaryOperator() {
        @Override
        protected int eval(final int op1, final int op2) {
          return op1 + op2;
        }
      };
     
      private static final Operator SUBTRACT = new BinaryOperator() {
        @Override
        protected int eval(final int op1, final int op2) {
          return op2 - op1;
        }
      };
     
      private static final Operator FACTORIAL = new UnaryOperator() {
        @Override
        protected int eval(final int op1) {
          int result = 1;
          int currentOperandValue = op1;
          while (currentOperandValue > 1) {
            result *= currentOperandValue;
            --currentOperandValue;
          }
          return result;
        }
      };
     
      public abstract void eval(final OperandStack stack);
    }

    Declared two types of Operators (BinaryOperator and UnaryOperator) to avoid duplication and to make it easy for adding new operators.


    public static abstract class BinaryOperator extends Operator {
      @Override
      public void eval(final OperandStack s) {
        s.push(eval(s.pop(), s.pop()));
      }
     
      protected abstract int eval(int op1, int op2);
    }

    and


    public static abstract class UnaryOperator extends Operator {
      @Override
      public void eval(final OperandStack s) {
        s.push(eval(s.pop()));
      }
     
      protected abstract int eval(int op1);
    }

    [Post to Twitter] Tweet This Post  [Post to Plurk] Plurk This Post  [Post to Yahoo Buzz] Buzz This Post  [Post to Delicious] Delicious This Post  [Post to Digg] Digg This Post  [Post to Ping.fm] Ping This Post  [Post to Reddit] Reddit This Post  [Post to StumbleUpon] Stumble This Post 

    • Share/Save/Bookmark
        Licensed under
    Creative Commons License
    Design by vikivix