Wednesday, December 30, 2009

Book Review: Apprenticeship Patterns

I finally finished the book “Apprenticeship Patterns – Guidance for the aspiring Software Craftsman”. It took me about 2 months to finish it, because I don’t have enough time to read it, usually I read it at waiting time for the Go train.

This book changes my strategy of my career path. If you want to become a master of software craftsman, then you should focus on improving your craft, not on promotion, not on money. This is a long road.

“sustainable motivations”
You need to keep motivate yourself, nurture your passion, beware don’t let yourself trapped into Golden Lock:" I'd like to learn something new ,but what I already know pays too well."

You need to find a better company, better job, team and co-worker. Love your job, do what your love, then money will follow. Money itself is not the goal, it is just the byproduct along the road to master. It gives me an insight that you should focus on finding the job that you truly love and passionate, even if it is low pay, because once you have the passion, you will generate creativity and energy, then it will generate the money for you. Another great example is Steve Jobs, in his commencement address to Standford’s class of 2005, he said: “You've got to find what you love “..., “Don't let the noise of others' opinions drown out your own inner voice. And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.”

This book helps me reinforce the understanding of the patterns, the author draws quite a few maps, connecting different patterns, then I realize the importance of the map, because it reveals the connections and relationship of each pattern. It inspire me that pattern itself is important, but also the connections. We should not only focus on each pattern itself, but also their relationship to other patterns.
Those patterns seems simple, it give ms an insight that yourself can find your own pattern if you think deliberately.

My favorite patterns in the book are:
  • Be the worst
  • The white belt
  • Nurture your passion
My personal goal is finding the Tao of programming, which is the right way of software developing, so go from apprentice to master is a must path for me.

I have another blog about this book: My personal practice map.

Tuesday, December 22, 2009

The Evil of Java ME preprocess

Developing Java ME application is painful, because of Java ME's own fragmentation in nature. Java Mobile developers have to deal with different devices, and each device or platform has different implementation. Writing a portable application to support different devices is really hard, and some time it is really a torture.

To solve the fragment issue, NetBeans IDE provides a solution - Preprocess, it is similar to pre-compile in C and C++. Actually preprocess in NetBeans is quite perfect, quite powerful. When I first use it, I feel it is so powerful, so easy to use.  Several years later, when I look at our code, which have #if, #else every where, I just feel the code are so ugly, seems to return to the c code era. I really feel preprocess is an evil! Following are my reasons.

Violate OO Principles
Since preprocess is so easy to use, just add something like comments, it gives developer a backdoor to break OO principles easily and brutally. It is so easy to hack the program, so there is no need to care about abstraction, no need to care about design patterns. And the problem is my colleagues like to overuse preprocess, mostly even use preprocess for constants!  I saw so many code full of magic numbers, and so many preprocess directive scattered every where to change those values.

It also violates OCP principle, OCP means "Open for extension, closed for modification". But preprocess is modifying the existing source code when you add new preprocess configuration. It is quite common that the change works for the new configuration, but will break the old ones.

I found if we use more design patterns deliberately, like strategy pattern, abstract factory pattern etc, and use constant class instead of magic number directly, we can minimize the preprocess greatly.

Hard to Refactor
Refactoring the preprocessed code is really difficult, for example when you rename a method name or variable name, you can only refactor the current active preprocessed code, because others are commented out. Right now in my current project I have 4 different devices type, so every time when I refactor, I have to test 4 times to make sure my change is working. It is really painful!

Hard to Reuse
If you want to reuse a class or a component to another project, but when you see so many preprocess scattered in the code, probably you will not use it.  Either you have to add all those preprocess into your new project which might does not make any sense, or you have to manually remove them, which is even harder to test.

Hard to understand
When you read the code has so many #if #else statement, it is ugly to read, more difficult to understand, code is not clean.

Hard to maintain
When you want to port the current application to a new device, you have to understand how the previous preprocess work; when you want to fix a bug for specific device, you have to make sure it won¡¯t break the others. Manage so many preprocess configuration is really painful. So preprocess is good for short-term, but really painful for long term.

IDE Lock-in
Because of widely use of preprocess, our projects are locked in NetBeans IDE, we can not use other IDE, like Eclipse.  For my experience, NetBeans IDE has some problems for example:
  • you can't use different source code folder for different configuration, you can easily do that in Eclipse MTJ;
  • Build automation is difficult, I don't understand the NetBeans generated build xml, I have to build inside the IDE, I never tried to run build file outside the IDE, and I don't know how create a customized ant build file, I think it is really hard;
  • Difficult for team work. NetBeans project use absolute path, and private project properties. Which means it works in your computer, but might not work in your co-workers environment, or you have to take a while to set up the environment correctly.

Conclusions
Java ME preprocess is easy for short-term, but painful for long term, it solves one issue by generating more issues in future; it delay your pain in a short term, but you will be more painful for long term.

Suggestions for anti-preprocess
  • Try to minimize the use of preprocess, we can't 100% percent remove the preprocess, but be ware to use it, only use it when no other options.
  • Have the discipline of writing clean code, readable code and maintainable code, before you use preprocess, think it carefully, if there is better solution;
  • Use OO design patterns, for example strategy pattern and abstract factory can remove lots of preprocess;
  • Try to use configuration file instead of preprocess, if we put the constant value into resource property file instead of hardcoded using preprocess, we can also make the code cleaner;
  • Centralize the preprocess, if you have to use preprocess, don't allow them scattering every where in the code, try to put those preprocess specific logic together, even better to put them into one class, it would be easier to read, understand and maintain;
  • DSL/Meta programming, if fragmentation is unavoidable, why not use code generation technology to generate source code for each specific platform for us? This needs compiler skills and Domain Specific Language knowledge, it is really an interesting topic.

Saturday, December 12, 2009

My Personal Practices Map

Currently I am reading the book called Apprenticeship Patterns – Guidance for the Aspring Software Craftsman. In page 85, the pattern “Reflect As You Work”, it mentions a technology called “Personal Practices Map”. You can use this technology to analyze and reflect your idea and what you did.
This idea originally comes from London’s Extreme Tuesday Club. The page "Maps of People’s Personal Practices".

This is my Personal Practices Map.



Using map to reflect ideas reminds me the book of GoF design patterns.  In that book, the authors draw a map of all 23 patterns and their relationships.  The book Apprenticeship patterns draw lots of map to connect each pattern.
This is a great technology. In future I will draw more maps:
  • “Draw your own map” (Page 47), draw a map of your career path.
  • Draw the map of reading list

    Saturday, December 5, 2009

    Agile meeting notes at Toronto JUG Dec 1, 2009


    I attended the Toronto JUG meeting on December 1. This time it is about Agile, the presentato is Jack Milunsky from agilebuddy.com. His topic covered agile, SCURM and lean. 
     I put my notes here:

    Adopting agile is hard
      Agile requires both bottom up and top down.
      Applying agile practices is easy, but the hard part is new mindset and new philosophy, which is quite different with traditional waterfall methodology
      Agile/Scrum is pervasive; it involves all different teams to change

    Lean software technology
    Jack spent lots of time on Lean.

    Lean’s two pillars:
    1.      Just-In-Time Flow
    Eliminate inventory,
    Do things in batches, which is similar with SCRUM
    2.      Autonomation:
             Stop the line,
             Built-in reflex

    Just In Time Flow
    -          inventory is waste  => partial done software
    -          Moving in Just in time
    Uncover waste
           Focus on overall concept
           Focus on value

    7 principles of lean software development
    1.      Eliminate waste
    Any partial done software is waste
    2.      Build Quality in
                don’t test it in, prevent defect in the first place
                avoid creating defects
                stop the line, automation, unit test
     3.      create knowledge
               knowledge create process
               don’t lock down
     4.      Defer commitment
                “Planning is good, plans are bad”
     5.      Deliver fast
    Lean focus on time
    Don’t equate fast with hacking
    Expose issues
    Build quality in
    Quality is the first priority
     6.      Respect people
    Self organizing team
    Trust over command and control
     7.      Optimize the whole
    Mindset is important, not just practice
    Transfer ownership
    Focus on the whole value stream, the big picture
    Focus on value, eliminate waste

    Waste

    ·         Extra features
                   Justify every feature, limit features
                   Extra features are waste, > 60% are extra features.
    ·         Relearning
                 Task switching drops the productivity
                  Undocumented code
                  No wiki
    ·         Handoff
             Transition point are waste point, knowledge degrades
              Delays

    ·         Defects

    Increasing speed helps the absence of waste

            Cycle Time =  things in process / average completion rate
    How to reduce the cycle time:
    -          minimize the number of things in process
    -          minimize the size of the things
    -          Recommend small batches, which is similar as sprint in SCRUM

    80% rule: if the task load is over 80%, the cost, defect rate increase dramatically


    Agile in AgileBuddy
    Agile buddy spends 20% time for refactoring, (which is very good, they know how important refactoring is, they do it deliberately, very nice!)
    Discipline:  set the dial to 11( 80% rule)
    Sprint length: 2 weeks

    My thoughts
    After the meeting, I talked to Jack, and we exchanged the idea, I believe that SCRUM mainly focuses on management side, it only focuses on what to do, but does not cover how to do, if you look at the SCRUM, there is no TDD, refactoring, pair programming, etc. I always have the question: do they need to be added in the SCRUM sprint practices? How? So I think SCRUM only is not enough, SCRUM should work with XP. So I asked Jack his idea about SCRUM vs. XP. He replied me that SCRUM only definitely not enough, it has to work with XP, because some of the XP practices are really fundamental, like TDD, refactoring. That what they are doing in agilebuddy.

    I also told him my experience that how difficult to persuade my manager to apply agile in my company, how difficult to apply refactoring. He suggest me to organize a lunch and learn meeting, just watch this video by Ken Schwaber about SCRUM.
    I don’t know if it is working. This meeting let think more about agile.Thanks Jack.
     You can visit Jack's blog at here.

    Thursday, November 26, 2009

    Code Kata: SuDoKu Solver

    This week I am interested in the Sudoku puzzle, I am thinking how to use program to solve the SuDoKu. I almost spent a week for it. At first I was inspired the a book called “Wicked Cool Ruby Scripts”in chapter 5, it provides a ruby source code for the SuDoKu solver. I spent two days to understand the code. The problem is the book does not describe the algorithm in details, and I don’t know how to debug the ruby code in TextMate. So it took me a longer time to finally understand the whole logic.

    Actually it uses the brutal backtrack method. Try fill a number in one cell, then recursively call itself, if it works, continue, then return, try another, until it fills all the 81 cells. I made some changes based on the original code, the major changes once the solver find the solution then exit the loop, while in the original code the program will continue loop until the end, I compare my changes with the original code, the total times executed and execution time both drops about 50%.

    Here is my modified code:

    class SudokuSolver

    def initialize(puzzle)
    @@p = puzzle.split(//)
    end

    #Algorithm to solve the sudoku puzzle
    def solver

    #81 times for each block in the puzzle
    81.times do |j|
    next if @@p[j].to_i!=0

    candidatesArray = getCandidates(j)

    candidatesArray.each do |v|
    @@p[j]=v.to_s
    foundAll = solver
    if(foundAll == true)
    return true
    end
    end

    # finished trying all the candidates, backtrack
    @@p[j]=0
    return false
    end

    return true
    end

    def getCandidates(j)

    Array array = [1,2,3,4,5,6,7,8,9]

    row = j/9 *9
    col = j%9

    #find the cells with the same row
    9.times do |k|
    m = @@p[row+k].to_i
    if(m)
    array.delete(m)
    end
    end

    #find the cells in the same column
    9.times do |k|
    m = @@p[k*9 + col].to_i
    if(m)
    array.delete(m)
    end
    end

    #find the cells in the same sub cube
    start_row = j/27 * 3
    start_col = j%9/3 * 3
    3.times do |t|
    3.times do |l|
    m = @@p[(start_row + t)*9 + start_col + l].to_i
    if(m)
    array.delete(m)
    end
    end
    end

    return array

    end

    def printResult
    puts "\n\nThe Solution is:\n"
    print "+-----------------------------+\n|"
    1.upto(81) do |x|
    print " #{@@p[x-1]} "
    if x%3==0 and x%9 !=0
    print "|"
    end
    if x%9==0 and x%81 !=0
    print"|\n|-----------------------------|\n|"
    end
    if x%81==0
    puts "|"
    end
    end
    puts "+-----------------------------+"

    end
    end


    question = "000700390090500000300240800700900200000000000003007008004026007000005060026001000"
    answer = SudokuSolver.new(question)
    puts "\n\n\nSolving puzzle, wait one moment..."
    answer.solver
    answer.printResult

    The logic is really simple: first reads the puzzle, construct the one dimension array.
    The key is in Solver method:
    From 81 cells, pick one empty cell, calculate the candidate numbers of this cell,
    Pick one number, fill the cell,
    Recusively call itself, continue try to fill another empty cell.
    If the program could not find the candidate for the cell, or the program iterate all the cell’s candidate number, then erase the number, backtrack;
    If the program fills all the 81 cells, return true

    The algorithm of getCanidates(j) is easy:
    Build an array of 1-9
    Find each cell with the same row, erase the number in the cell from the array;
    Find each cell with the same column, erase the number in the cell from the array;
    Find each cell with the same sub block, erase the number in the cell from the array.
    The left in the array are candidates


    From this code, I understand more about the backtrack and recursive method. This code belongs to the depth-first backtrack search.

    Donald Knuth’s Dancing Link algorithm is quite interesting, there are lots of articles and blog about using it solving the SuDoKu. But right now for me it is really hard to understand.

    For SuDoKu, there are following thins to do in future:
    1. Implement the SuDoKu solver using Dancing Link algorithm
    2. Find out the algorithm of SuDoKu Generator, like how to generate a puzzle based on difficulty, and how to find out there is only one solution.
    3. How to implement an algorithm that simulate human's solving logic?

    Here are several link about dancing link and SoDuKu:
    Dancing Link C implementation
    Dancing link for Java
    Donald Knuth Home page
    Donald Knuth's Dancing links paper(pdf)

    Friday, November 13, 2009

    code Kata 3, How many n-digit binary numbers are there that don't have two adjacent 1 bits?

    Today I read a new Kata from Dave's CodeKataCodeKata fifteen: A diversion

    The Question:
    Think of binary numbers: sequences of 0's and 1's. How many n-digit binary numbers are there that don't have two adjacent 1 bits? For example, for three-digit numbers, five of the possible eight combinations meet the criteria: 000, 001, 010, 011, 100, 101, 110, 111. What is the number for sequences of length 4, 5, 10, n?

    Having worked out the pattern, there's a second part to the question: can you prove why that relationship exists?

    The answer is in the replied comments, it is a fibonacci series:
    f(1) = 2 => 0,1
    f(2) = 3 => 00, 01, 10
    f(n) = f(n-1) + f(n-2)

    Now I will try to explain why it is like this using my own thoughts:
    f(3) can be thought of 2 groups, one is begin with 0, and the other is begin with 1
    begin with 0 group: 0 + xx, => f(2)
    begin with 1 group: since it begins with 1, it must be followed by 0, so it becomes 10 + x , =>f(1)

    so f(3) = f(2) + f(1)

    same thing with f(n)
    begins with 0: 0 + xxx...x ( n-1 digit) => f(n-1)
    begins with 1: 10 + xxx..x ( n-2 digit) => f(n-2)

    so f(n) = f(n-1) + f(n-2)

    Now I will give the solution in Ruby:

    def non_adjacent_one_array(n)
    if(n == 1)
    ["0", "1"]
    elsif (n== 2)
    ["00", "01", "10"]
    else
    array1 = non_adjacent_one_array(n-1).collect { |i| "0"+i}
    array2 = non_adjacent_one_array(n-2).collect { |i| "10"+i}
    array1+array2
    end
    end

    s=non_adjacent_one_array(5)
    puts "n=5, number is #{s.length}\n"
    puts s
    puts "\n"

    1.upto(10) do |i|
    s = non_adjacent_one_array(i)
    puts "n=#{i} number=#{s.length}\n"
    end


    And the results are:

    n=5, number is 13
    00000
    00001
    00010
    00100
    00101
    01000
    01001
    01010
    10000
    10001
    10010
    10100
    10101

    n=1 number=2
    n=2 number=3
    n=3 number=5
    n=4 number=8
    n=5 number=13
    n=6 number=21
    n=7 number=34
    n=8 number=55
    n=9 number=89
    n=10 number=144

    Thursday, November 12, 2009

    Build an iPhone application without Interface Builder

    I am still a beginner of iPhone developer. I finished a tutorial book. Right now I am trying to read another one. But I found my problem: I only know how to build the application using the Interface Builder, but I don’t know the underlying mechanism of the application, for example; what is the life cycle of the application, how does the application delegate, ViewController and View interact each other?

    Using Interface Builder makes the application developing very easy, it separate out the presentation logic with the application logic. I like this idea, but for beginner only know the Interface Builder is not enough:
    - It makes your job easier, but also hides the application information, and blocks you to understand the underlying mechanism. For example, When I investigate the sample code LocateMe, it uses UITabBarController and NavigationgController for each tab, when I read the source code, I don’t know the where the variable navigationController come from, I don’t know how it created. It is set in the nib file, and you have to read the reference document to see how it works.

    - Sometime you need to customize your app, Interface Builder will not help you, you have to do it programmatically. For example, I tried to add a UIScrollView using the interface builder, but I found it does not scroll as I expected.

    I google the solution and found this video is helpful:

    Building iPhone Applications without Interface Builder from Troy Mcilvena on Vimeo.



    And this blog:Why would you use Interface Builder for iPhone Development?

    I just summarize the detailed steps:

    1. In Xcode wizard, choose Window-based Application, then delete the MainWindow.xib, remove the property with the key ‘Main nib file base name’ (the raw key name is ‘NSMainNibFile’) from your Info.plist file.

    2. In main.m, add your AppDelegate class name in the last argument of the UIApplicationMain method.

    int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"NoNibAppDelegate");
    [pool release];
    return retVal;
    }


    3. In AppDelegate class, initialize and configure the window and Controller object.

    For example: NoNibAppDelegate.m
    - (void)applicationDidFinishLaunching:(UIApplication *)application {

    // Override point for customization after application launch
    window = [[UIWindow alloc] initWithFrame:[ [UIScreen mainScreen] bounds]];

    RootViewController *root = [[RootViewController alloc] init];
    [window addSubview:root.view];
    [window makeKeyAndVisible];
    }


    4. In your ViewController class, implement the loadView() method
    From UIViewController Reference document: If you create your views manually, you must override this method and use it to create your views
    - (void)loadView
    {

    UIView *contentView = [[ButtonView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

    self.view = contentView;
    [contentView release];


    }


    5. In View class, implement the initWithFrame: method
    “If you create a view object programmatically, this method is the designated initializer for the UIView class.” - From UIView reference document.
    - (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {

    self.backgroundColor = [UIColor lightGrayColor];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 30.0f)];
    label.text = @"Hello World";
    label.center = self.center;
    label.backgroundColor = [UIColor clearColor];
    label.textAlignment = UITextAlignmentCenter;

    [self addSubview:label];
    }
    return self;
    }


    6. You might want to register an UIControl event listener:
    - Intitialize the UIControl object, for example a UIButton:
    [buttonPress addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];


    - implement the event call back method:
    -(void)buttonClicked:(id)sender
    {
    UIButton *button = (UIButton *)sender;
    NSString *text = button.currentTitle;


    NSString *string = [ [NSString alloc] initWithFormat:@"Button %@ pressed.",text];

    NSLog(@"button clicked. button title:%@", text);

    self.label.text = string;
    [string release];

    }


    You can download my sample code from here.


    From this investigation, I understand the iPhone application life cycle and event flow; know the underlying mechanism and get the confidence to customize application in future.

    For learning iPhone, I am trying to follow the Shu-Ha-Ri learning model: at the Shu level, which is called following and copying, so I just follow one book: Beginning iPhone 3 Development: Exploring the iPhone SDK. I just follow step by step, copy every line of the code from the book. This is a very good book for the beginner who never touch the apple development environment like me, but it does not cover the deeper information, which I am really want to understand now.

    So I think it is time for me to go to Ha level: which is breaking, it means trying to collecting different information and trying to read different article and books, Now I learned that it is time for me and I am ready to read Apple reference document, read advanced iPhone books, investigate the sample code, joining the forum, and practice.


    Tutorial gives you a starting point, Interface Builder is a crutch, it is time for you to remove them if you want to get improved.

    Here is my reading list for iPhone in fufure:
    - Apple iPhone reference documents and API documents
    - Apple iPhone sample codes
    - The iPhone Developer's Cookbook: Building Applications with the iPhone SDK
    This is a really good book, but not for beginner, it tells your more detailed information which is not covered in other books. I am waiting for the 2nd edtion.


    References:
    - iPhone Application Programming Guide

    - The iPhone Developer's Cookbook: Building Applications with the iPhone SDK

    Sunday, November 8, 2009

    Code Kata 2 - Reverse words in a string using Ruby

    Last time I posted the blog Code Kata - Reverse words in a string, in that blog I provided the java solution. Today I will try to solve this problem using Ruby.

    Question: How to reverse words in a string?
    For example, given a string "The quick brown fox jumped over the lazy dog", reversed string needs to be “dog lazy the over jumped fox brown quick The”.
    And this time there is no memory constraint, we just focus on providing an elegant and concise code.

    The algorithm has two steps:
    1. First reverse the entire string by character
    For example: "The quick brown fox jumped over the lazy dog" becomes
    “god yzal eht revo depmuj xof nworb kciuq ehT”
    2. Then reverse each word by character
    For example: “god yzal eht revo depmuj xof nworb kciuq ehT” becomes
    “dog lazy the over jumped fox brown quick The”

    The ruby code would be:

    def reverse_string(s)
    s.reverse().scan(/[\w]+/).collect { |w| w.reverse()}
    end

    r = reverse_string("The quick brown fox jumped over the lazy dog")
    puts r

    The method reverse_string() will return an array instead of a string, but it does not matter here. You can see how easy to implement using Ruby compare to Java!

    Wednesday, November 4, 2009

    My Presentation: The OO design principles


    This is my presentation about OO software design principles: http://www.slideshare.net/intellizhang/the-oo-design-principles
    I created this presentation at least 4 months ago in July this summer. I realized the problem in our team: there is no software design, no refactoring, so many duplicated code ... etc, the code is just messy and hard to maintain. The worse is that most of my colleagues does not realize the problem, it seems they are quite comfortable with the messy code, seems that messy code is reasonable; or they feel the problem but don't know how to solve it, and my manager think that we are so busy now, we don't have time to think about the design, and refactoring is just some extra stuff. WHICH IS TOTALLY WRONG!
    That is the reason I made this presentation, try to inspire my colleagues and my manager that there are better ways to coding, we should follow the right way, then we can deliver faster and better product.

    So far there are not many feedback in my team for this slide, I don't know when I can make this presentation in my team, so I decide to put it in public, hope this can be useful for other people.

    The whole slide is copied from the following two books:
    1. Agile Software Development: Principles, Patterns, and Practices, by Uncle Bob

    2. The Pragmatic Programmer: From Journeyman to Master, by Dave Thomas and Andy Hunt

    Monday, October 26, 2009

    Code Kata – Reverse words in a string

    Dave Thomas creates a website called Code Kata, Who encourage developers improve their skills by keep practicing coding, trying to find better solutions for some questions.

    Today I met an interesting question: How to reverse words in a string?
    For example, given a string "The quick brown fox jumped over the lazy dog", reversed string needs to be “dog lazy the over jumped fox brown quick The”. The thing is you can not use extra memory to do it, you had better manipulate the reverse logic in the original text string.

    To solve this question, I remembered I read a good book several years ago, it is called Programming Pearls ,written by John Bentley.

    In chapter 2, section “The power of Primitive”, the author gives the solution of transform an array vector, which is clean, elegant and efficient. I used this solution to solve this problem.
    The algorithm has two steps:
    1. First reverse the entire string by character
    For example: "The quick brown fox jumped over the lazy dog" becomes
    “god yzal eht revo depmuj xof nworb kciuq ehT”
    2. Then reverse each word by character
    For example: “god yzal eht revo depmuj xof nworb kciuq ehT” becomes
    “dog lazy the over jumped fox brown quick The”

    You see it is pretty easy, right? No need extra memeory, no need substring.This is the power of the algorithm.

    Here I post the java version of the solution, you can easily implement this algorithm in C or other language.

    public class StringRerverse {

    private int wordStartIndex;
    private int wordEndIndex;
    private StringBuffer sBuffer;

    String reverse(String string)
    {

    this.sBuffer = new StringBuffer(string);

    sBuffer.reverse();

    int size = sBuffer.length();
    int pos = 0;

    while(pos < size)
    {
    if(findNextWord(pos) == true)
    {
    reverseWord(sBuffer,wordStartIndex,wordEndIndex);
    pos = wordEndIndex+1;
    }
    else
    {
    break;
    }
    }


    return sBuffer.toString();

    }
    boolean findNextWord(int startFrom)
    {
    int start = startFrom;

    while (start< sBuffer.length()-1 && sBuffer.charAt(start) == ' ')
    {
    start++;
    }
    if(start == sBuffer.length() -1 )
    {
    return false;
    }

    wordStartIndex = start;

    int end = start+1;
    while(end < sBuffer.length()-1 && sBuffer.charAt(end) != ' ' )
    {
    end++;
    }
    if(end == sBuffer.length() -1 )
    {
    wordEndIndex = end;
    }
    else
    {
    wordEndIndex= end-1;
    }
    return true;
    }

    void reverseWord(StringBuffer sBuffer,int wordStartIndex, int wordEndIndex)
    {
    int length = wordEndIndex - wordStartIndex + 1;
    for(int j = 0; j<length/2; j++)
    {

    int startIndex = wordStartIndex + j;
    int endIndex = wordEndIndex - j;
    char c = sBuffer.charAt(startIndex);
    sBuffer.setCharAt(startIndex, sBuffer.charAt(endIndex));
    sBuffer.setCharAt(endIndex, c);
    }
    }



    public static void main(String[] args)
    {
    StringRerverse reverse = new StringRerverse();

    String string = new String("The quick brown fox jumped over the lazy dog");
    String reverseString = reverse.reverse(string);
    System.out.println("reversed String: "+reverseString);

    }
    }

    Sunday, October 25, 2009

    From Good to Great Developer

    Last week I watch a presentation called “From good to great developer“ from www.infoq.com.
    Here is the link : http://www.infoq.com/presentations/Good-to-Great-Developer-Chris-Hedgate

    Chris Hedgate made a really great presentation. He pointed out that good developer writes code quickly but hard to maintain; but great developer has long term goal and try to write clean code and make it easier to maintain.

    He also gave the advices how to become a great developer. I really like the 4-stage learning model he introduced: unconscious incompetence, conscious incompetence, conscious competence and unconscious competence. The learner in different stage will take different actions: inspiration, training, practice and reflection.
    I am an agile believer; I’ve been trying my best to write clean code and trying to improve the design. But I am really frustrated by my colleagues and my manager. They don’t think keep code clean and refactoring is necessary, just something extra features make it looks beautiful. Now I know the reason: they are at the first state - unconscious incompetence, the best solution is inspiring them first. You need to be a good coach. You need to be lead by example. You have to become great first.

    Talking about becoming a great developer, which is the same idea coming from Agile. It means craftsmanship, professionalism, discipline, and mastery. I think every serious developer should have a goal to become a great developer or master programmer, just like kong-fu master or samurai. It is a whole life’s practice.

    Being a great developer is not an easy job. You need to understand the agile principles, understand design patterns, have disciplines and patience to write clean codes and keep refactoring; you have to constantly reflect yourself; you need to keep learning new technologies. And you need to help other people and try to motivate and inspire them. This is raising the bar, it is hard, but this is the only way to create a remarkable career for you, the only way to give you a passion, and the only way to transcend yourself.

    Here I add some other videos which share the same philosophy:

    1. Craftsmanship and Ethics, by Robert Martin:
    http://www.infoq.com/presentations/craftmanship-ethics

    2. Developing Expertise: Herding Racehorses, Racing Sheep, by Dave Thomas
    http://www.infoq.com/presentations/Developing-Expertise-Dave-Thomas

    Dave Thomas is the author of “Pragmatic Programmer, from journeyman to master”. This video talks about the Dreyfus model, which is 5-stage learning model. The details about it is in the Book “Pragmatic learning and thinking” by Andy Hunt.

    3. I Come to Bury Agile, Not to Praise It, by Alistar CockBurn
    http://www.infoq.com/presentations/cockburn-bury-not-praise-agile
    This video talks about a Shu-Ha-Ri, a 3-stage learning model, I first learned Shu-Ha-Ri from his book “Agile Software Development”

    4. Deliberate Practice in Software Development, by Marry Poppendieck,
    http://www.infoq.com/presentations/poppendieck-deliberate-practice-in-software-development
    Marry Poppendieck is regarded the first person who apply Toyota’s Lean technology into software development, this video she provide the 10-year rule theory, emphasizes the craftsmanship and clean code.

    5. Productive Programmer: On the Lam from the Furniture Police, by Neal Ford
    http://library.theserverside.com/detail/RES/1242309506_447.html?asrc=vcatssc_sitepost_05_14_09
    The author of “Productive programmer”, he talked about the principles in his book, the book of “Peopleware” and “pragmatic learning and thinking”

    6. Transcendence and Passing Through the Gate, by Dave West
    http://www.infoq.com/presentations/transcendence-gate-dave-west

    This video is really interesting, it talks about agile, but he use the concept of Zen. He mentioned the famous 10 Bulls pictures which describe 10 different stages of a human being to describe the agile development.

    Monday, October 12, 2009

    Learning from the Book Of Five Rings


    Miamoto Musashi was a very famous Japanese saumari, who wrote a book called The book of Five Rings. I first heard of him by Alistir CockBurn’s book – Agile Software Devleopment.

    The good thing is Alistair pointed out what we can learn from his book into our software development. Here is what Alistair pointed out:

    • Do not develop an attachment to any one weapon or anyone school of fighting.
    Use the rang of them without getting stuck in anyone.
    • Practice and observe reflectively.
    Practice hard, win big (pointed out by Jeff Sutherland, the SCRUM creator)
    • Win
    Pay more attention to winning than to looking good,
    “Do not do anything useless”

    Here I also would like to copy what his rules for learning the art ( from page 41):
    1. Think of what is right and true.
    2. Practice and cultivate the science.
    3. Become acquainted with the arts.
    4. Know the principles of the crafts.
    5. Understand the harm and benefit in everything.
    6. Learn to see everything accurately.
    7. Become aware of what is not obvious.
    8. Be careful even in small matters.
    9. Do not do anything useless.

    The interesting thing is that in the book, Mushasi use carpentry as a metaphor for mastering his science of martial art. (from page 9, Likening the Science of Martial Arts to Carpentry). It seems every word can be used to software development, used as principles of mastering programmer's skills.

    In future I will post more about this book.

    My vision of a good software developing team

    I found the major problem is that our current software development can not fully meet the customer’s needs: Almost every project is delayed, every one is busy and has a tight schedule; the product quality needs to be improved; the application software is hard to maintain.

    I realize that the reason might be something that our management does not cover: our manager only care about what needs to be done and when can be finished, but does not care how to do it. So where there is something is not covered under management, and then there will be problems: no design, no developing strategy, messy code, hard to maintain, too many bugs.

    I realize there is a gap between the project manager and the developer:
    The project manager just want to get the work gets done, but does not care how to do it;
    The project manager cares more about schedule over the quality, and project manager care more about short term benefit over the long term benefit, like maintainability, flexibility, clarity.
    The project manager treats the developers as “pluggable compatible component”, based on an assumption that each developer is interchangeable, and can be transferred to another developer to do the same job, does not notice that each developer is unique, and have different skillset and mindset.

    And currently our only strategy to get thing done by either adding more resources or by sacrificing the quality, no other strategy; which means we have to work over time, hire more people, spending more money. Can we do that in a smarter way? Can we do that in nice, clean and faster? I think the answer is YES.

    We need to do things in the right way. In Chinese, “way” means “TAO”. If we follow the TAO of the software development, then we can deliver the great product in a short time.

    Following are my vision for a good software developing team, and what the TAO should be:

    - Follow good design
    We need follow good OO design principles, and good design patterns. A good design is a foundation of a software product, and a good design is the DNA of a good product.

    - Build Quality in
    We need to balance between long-term benefits with short term benefits
    Our software should be: flexibility, maintainability, and readability.

    - Write clean code, constantly keep refactoring, continuously improving design
    I like Uncle Bob’s saying” If code is messy, so does the product”.
    Bad code slows down the productivity
    Only one way to go fast is going well, writing clean code.

    - Design for maintenance
    The only way to develop maintainable code is to design the maintainability at design phase

    - Deliver DRY project
    DRY means “Don’t Repeat Yourself”.
    Here I would like to mention the definition of what does mean a project is Done:
    1. Deliver the product to our customer
    2. Developers improve their skills;
    3. Team gain knowledge;
    4. The design and code is easier for future project
    I think all these 4 things together means a project is done, but currently we only focus on No. 1, which cause on the problem in future: since the code is not reusable, we have to rebuild the entire app, or we have to duplicate all the old code, which either by fixing duplicating bugs or by spending long time to fix the issues by adding new codes. Finally we spend more time and money by reinventing the wheels.

    - Test Driven Development
    We need are not only use JUnit, but also to make sure our design is easier for unit test, our framework is easier to using unit test.

    - Build automation
    Our build automation should support everywhere, server side code, client side code, and test code.
    Everything we need should be checked in the repository, including dependent libraries, config files, property files, database script, build tools, etc.

    - Use static analysis tools
    Currently there a lots of open source static analysis tools. For example they can find the potential bugs; tell you how complex of your code, how messy your code is, and tell you the coverage of your test code, etc. which will help us improving our code quality greatly

    - Foster knowledge sharing and internal training
    We need to build an environment which can foster knowledge management in our company, which is called ‘ba’ in “Lean technology”. We need to use Wiki, internal forum, internal training to share the knowledge for all the developers.
    Knowledge management is very important

    - Following the Agile
    We need not only do the agile practices, but need also fully understand the agile principles and its values.
    And each team needs to use different agile methods.
    Developer needs to follow XP;
    Manager team needs to follow Scrum
    The whole company needs to follow Lean technology

    - Training developer to be professionalism
    We need our developers have the concept of:
    Professionalism, craftsmanship, discipline, ethics, etc.

    Next I want to discuss more about the gap between the manager and developer. I think there is a role we are missing – “coach”. I think a good coach will be a bridge connecting developers and managers, his role is filling the gap.
    I would like to make a metaphor: thinking our software team as a sports team- whether basketball team or a hokey team. In a sports team a coach plays a very important role:
    - Design the wining strategy for the team
    - Instruct each player not only what to do but also how to do;
    - start timeout when he found the issue during the game, either by substituting a new player or set up a new strategy;
    - Training players and improve their skills;
    - Motivate players and find their potentials;

    In summary, the job of a coach is to make sure how win a game and how to make a team better, he focus on HOW. In contrast so far I did not find a role in our team that can fit as a coach, either our manager, or architect, or team lead. I think the reason is our management model is "command and control", which is from top to bottom, each manager’s job is dispatching the job from his upper layer to his under layer, then his job is done; the same is for architect or team lead. But if we also have another management channel - from bottom to top, the role of coach is very important. I believe the coach's role is more on the developer side, The coach’s job will focus on how to make our software better, make our developer better. And I believe only the coach can do all the items I mentioned above, because coach himself is a developer, he understand our product’s detailed problem, knows the solution, he knows each developer’s different strength and their skills, once he knows the vision, understand the whole picture, he will play a very important role in our team.

    So my suggestion is we need a coach or several coaches in our development team.

    Friday, October 2, 2009

    Be prepared to leave

    I was totally motivated by the book -The passionate programmer. Now I am trying to copy the author’s idea and write an essay using his style, the name is called “Be prepared to leave”.

    Usually people start to update their resume when they want to find a new job, then they realize their problems: they found it is hard to review what they did in the past few years; they realize their skills might be outdated; they don’t know where to go, just randomly submit their resumes. Every thing seems to be by accident, not deliberately.

    So how can we plan our career deliberately? My answer is be prepared to leave. If you have this mind set, you have a positive attitude of doing your daily jobs. Suppose you are going to leave or be fired, then it force you to update your resume regularly, to update your resume, it forces you to review yourself constantly:

    • For every project you finished, you ask yourself: how did I finish it, what kind of skills I used, how can I add a good achievement in my resume? How can I improve it? How can I use the current new technology into my project, so that I can improve my work and also I can add it into my resume? If you summarize and review your work constantly, you will find you have many good points to put into your resume.

    • Find your blind spots. Since you are going to leave, you need to take chance trying to learn what you don’t know. Think it proactively, when you find your blind spot, then try to fix it as soon as possible. When you find you have a challenge to do some job, then it is probably a blind spot for you, and it is a good opportunity for you to get improved. For example you found it is very painful for you to deploy or build a project, because it needs you manually do many different steps and easy to make error. So why not improve the build script and improve the build automation process? If you have this attitude, you will find every job is interesting, even it is a maintain job.

    • Research the market regularly, try to find the skills the market need and what skills you need to improve and learn; try to find the company you want to go and find out what kind of technologies they are using, then try to learn it, try to use them into your current project.

    In summary when you have a “be prepared to leave” attitude, you will not find your daily job is boring any more, you will find many opportunities to improve yourself. Sooner or later your skills and thoughts will go to next level, and you will be easily got a good new job when chances come.

    IPhone development: memory management rules

    Right now I am learning the IPhone development using objective-C, I have to admit that I am a new beginner of objective-C, even if I have lots of experience of C/C++ development, the syntax of object-C confuse me a lot.

    Right now I run into a problem: when should we release the object? Here is the example:

    YellowViewController *yellowController =
    [ [YellowViewController alloc] initWithNibName:@"YellowView"
    bundle:nil];
    self.yellowViewController = yellowController;
    [yellowController release];


    It seems an idiom for objective-c memory management, since I’ve seen lots of source code did in the similar way. I was really confused, since I treated the objective-c object as a c++ pointer. In the above example, yellowController and self.yellowViewController are pointers, they are pointing to the same memory address, if we release yellowController, then how about self.yellowViewController? Will it become an invalid object because it is pointing to the memory address which was released already?


    Through me research, then I understand the memory management rule of objective-c. It uses reference counting method to manage the memory:
    - When create an object using alloc, the reference count will be 1;
    - When release method is called, decreases reference counter by 1;
    - When copy or retain method is called, increases the reference counter by 1;

    Then I have a question: how about the assignment operation? What does it exactly do? Will it increase the reference counter or will it copy the whole object data to the variable self.yellowViewController?

    Finally I realize that the key is in the definition of the instance variable self.yellowViewController:
    It’s definition is like this:
    @property (retain, nonatomic) YellowViewController *yellowViewController;

    Which means we do the assignment operation to the class variable self.yellowViewController, the retain method will be called, which means the reference counter will be increased by 1.

    We can use the following methods to check the reference counter:
    NSLog([NSString stringWithFormat:@"%u", [yellowController retainCount]]);
    self. yellowViewController = yellowController;
    NSLog([NSString stringWithFormat:@"%u", [yellowController retainCount]]);

    In summary, here is the simple rules for object-c memory management:

    Retention Count rules: (copy from here)
    1. Within a given block, the use of -copy, -alloc and -retain should equal the use of -release and -autorelease.
    2. Objects created using convenience constructors (e.g. NSString's stringWithString) are considered autoreleased.
    3. Implement a -dealloc method to release the instance variables you own

    Some good references:
    1. Very simple rules for memory management in Cocoa
    2. Learn Objective-C
    3. Forum thread: newbie memory management question ("release")

    Sunday, September 20, 2009

    Using ANT to build BlackBerry J2ME application - source code build

    Source code build using rapc compiler

    We have to use BlackBerry JDE rapc compiler to build the J2ME application for BlackBerry. But the problem is that JDE only generate the make file, which is awkward. I did some research and found a solution using ANT. I would like to share this experience with the BlackBerry Developer who wants to build the application easily.

    Here is the sample of ant build script for midlet:

    <target name="build" >

    <apply executable="${rim.blackberry.home}/bin/rapc.exe" parallel="true">

    <arg value="-quiet"/>

    <arg value="import=${rim.blackberry.home}/lib/net_rim_api.jar" />

    <arg value="codename=${cod.name}" />

    <arg value="-midlet"/>

    <arg value="jad=${cod.name}.jad"/>

    <fileset file="${cod.name}.jad"/>

    <fileset file="resources.jar" />

    <fileset dir="${src.dir}" />

    </apply>

    </target>

    The above script is equivalent to the following command:

    rapc.exe -quiet import=net_rim_api.jar codename=MIDletDemo -midlet jad=MIDletDemo.jad resource.jar file1.java file2.java … filen.java



    Note:

    1. Here I use Ant apply task, http://ant.apache.org/manual/CoreTasks/apply.html

    Apply task allow us to pass a fileset, and it will pass each file one by one to the rapc.exe. Please note that here we choose parallel="true" attribute, it means the command execute only once, which is just what we want rapc.exe do that for us.

    2. jad file issue, we know that rapc will add several blackberry customized attributes into the jad file. If we don’t pass the jad file into rapc, the rapc will generate a fresh new jad file for you; if you provide the jad file each time, the rapc will keep the jad file and only update some RIM specific attributes in the jad file. So I will suggest it is better pass your jad file into the build process.

    3. resource file issues. Rapc.exe is strange, when you pass the resource file (image, text file, etc) outside of the project folder, it will lost the path information for each resource file, every file will be copied in the root directory of the jar file, only exception is resource file is in the subfolder of the project. The solution for this is first archive all your resource file into a jar file, resources.jar for example, and then pass this resources.jar into rapc. This time it will work, all the path information for each file will be kept. Please remember that please remove the Thumb.db file under the your image folders. Because I found some time my build jar file is much bigger than the jar file generated by JDE, when I expand the jar file, I realize that the thumb.db file was included.

    Here is the ant example for zip resource:

    <target name="zip_resources">

    <jar destfile="resources.jar">

    <fileset dir="../res" >

    <exclude name="**/Thumbs.db"/>

    </fileset>

    </jar>

    </target>



    Building CLDC RIMlet is similar with the midlet, you don’t need pass the “-midlet” argument to the rapc.exe, here is the example:

    <target name="build" depends="clean">

    <apply executable="${rim.blackberry.home}/bin/rapc.exe" parallel="true">

    <arg value="-quiet"/>

    <arg value="import=${rim.blackberry.home}/lib/net_rim_api.jar" />

    <arg value="codename=${cod.name}" />

    <fileset dir="." includes="*.java" />

    <fileset dir="." includes="*.rapc" />

    <fileset dir="./img" includes="*.png" />

    </apply>

    </target>



    Note for RIMlet build:

    1. You need to pass the rapc file( generated by JDE) to build the RIMlet, or you will find your app can not be launched when you load the cod file on the phone; but I also found that you can also pass jad file to the rapc.exe, it also work.

    Further thinking

    1. Passing jar file instead of java file, what if we first archive the source code into a jar file, then pass it to rapc.exe, will it work? If this works, then we don’t need the ant apply task, the ant task will become more easier.

    2. Use rapc.jar instead of rapc.exe, I noticed that in the \bin folder of BlackBerry JDE home directory, there is a rapc.jar file, can we use it. I checked several different J2ME build open source code, I found bb-ant uses rapc.jar, and J2ME Polish also uses rapc.jar file. I will test it later, if it works, which means the ant build script can be run at unix platform as well!

    3. Check bb-ant tools

    4. Check ANTENNA tool

    Useful References

    1. Ant apply Task

    http://ant.apache.org/manual/CoreTasks/apply.html

    2. Article: BlackBerry Development: using Apache Ant

    http://www.ddj.com/mobile/48800167

    3. bb-ant open source project

    http://bb-ant-tools.sourceforge.net/

    4. ANTENA open source project

    http://antenna.sourceforge.net/