Saturday, November 28, 2009

Learning Organization in Practice - Senge’s View "The Fifth Discipline"

1. Personal Mastery

Personal mastery is concerned with individuals’ desire and ability to grow through learning. Those who have the discipline of personal mastery are actually ‘masters of personal learning’; people who value learning and who act on what they learn.

This kind of mastery implies a more active form of learning, a desire to find out more and to act on what we find out, turning it into knowledge, and in the process improving our lives.

Achieving true mastery involves a constant search for priorities. Prioritizing is itself a form of learning, which requires awareness, honesty and continual questioning. We must be prepared to note changes in ourselves and our environment, and re-prioritize accordingly.

Learning organizations are built by people with personal mastery. Without people who will question and re-prioritise, any organization risks pursuing the wrong goals and constantly playing catch-up with the opposition. In return, organizations need to value those who value learning. Companies need to provide opportunities to learn and act, and they need to seek ways to align the individual’s goals and objectives with those of the firm.

According to Senge, not only will those who possess mastery learn faster, but they will be more committed and more prepared to take the initiative. Enlightened companies will seize upon these attributes and harness them to the firm’s goals. This can only be a win–win situation: individuals are given opportunities to learn and are happier in their work. Meanwhile, the firm reaps the returns from new ideas, commitment and improved operations.

2. Shared Vision

Sharing a common goal is what distinguishes a team from a group of people. Simply putting people in a room and telling them that they are a team doesn’t make them a team. Similarly, hiring six developers who have worked well in six different teams before and calling them a team doesn’t make them a team. Each team is different, because each team contains a different mix of people and each team needs to find its own way of working together, its own strengths and weaknesses.

Participating in the shared vision means that individuals accept that they won’t create the whole themselves. Instead, individuals are offered the opportunity to create something bigger than they could create alone, and something that will be bigger than the sum of its parts.

For this to happen, each individual must hold a personal stake in the vision. In order to build a personal stake, it helps if each person is allowed to take part in the vision formation. This will help them internalize the vision and make it part of their identity, thus creating a sense of belonging and focus for actions.

Simply handing a team a ready-made vision and asking them to adopt it as theirownis the antithesis of true shared vision. People who are handed a ready made vision won’t feel the same attachment, and consequently they will be less motivated to bring the vision to reality.

For a shared vision or mission statement to really motivate individuals and teams, they must be able to associate closely with the idea. It is not enough for a manager or planner to explain how vision affects an individual. In order to create a close personal relationship with the vision, individuals need to hold a stake in it.

3. Team Learning

In any development team, many members will have specialist skills and knowledge. For the team to work well together, the members need to respect one another and maximize individual’s specialities, but also support the needs of those with less experience or knowledge.

For Senge, there’s more to team learning than just ensuring that a team works well together. Team learning goes beyond good teamwork. Team learning builds personal mastery and shared vision, to create highly effective motivated units.

Team action and learning are guided by the shared vision that helps the team to direct its thinking. The shared vision helps the team to know what to investigate and what to pass over.

When a team works well together, guided by a shared vision that all members believe in and work towards, then a phenomenon of alignment is seen. This occurs when all team members are pulling in exactly the same direction, without diversion. Unfortunately, there’s a danger that effective individuals working with the best intention but not working in alignment can pull in different directions. This makes management more difficult.

Team members need personal mastery to keep their individual learning moving, but for team learning there needs to be more. There needs to be sharing of learning amongst team members and between teams. Individuals can be great learners themselves, but if they don’t share their learning then team learning won’t occur.

Effective teams are open to learning as a group. The team needs to be able to engage shared reflection and what Senge calls dialogue and discussion. Senge differentiates between dialogue – which he considers a creative exploration and discussion, which he describes as the presentation and defence of different views.

The team should inquire into opportunities and problems, and recognize potential conflicts rather than avoiding them. These mechanisms help the team learn, build team knowledge and identify improvements to workpractices.

4. Mental Models

Mental models are the ideas, preconceptions and assumptions that we all carry around in our heads.We need these models to help us function every day, and they are valuable short cuts that enable us to skip over first principles and get things done.

When we’re aware of these models, there’s little problem. If our assumptions are out in the open, are explicit and we’re aware of them, then we can selectively switch them off when dealing with new problems or seeking new solutions. Problems set in when we’re unaware that the models are governing our actions, or when we fail to recognize that our models don’t apply.

Senge goes further than just pointing out that mental models exist. He advocates a discipline that seeks to expose the models and open them to questioning. Recognizing that these assumptions exist allows them to be questioned and rethought.

Mental models exist throughout the software development process. They exist in specification documents, in manager’s models of how development works, in the code that developers write and in the tests run against the system. Some inaccurate assumptions lead directly to bugs found by customers.

At every stage in the development process, we use our mental models to make assumptions. Advocates of voluminous documentation and strict methodological processes can claim that documentation will help overcome the problem. But as we write longer documents, and add extra rigour to our processes, we encourage individuals to take short cuts and rely on their mental models all the more.

5. Systems Thinking

Systems are not just computer systems. They are any kind of device or process where a number of different pieces need to work together to produce an end result or product. Computer systems are just one type of system, namely the type relating to computers. Modern society and business are full of systems.

Traditional Western science emphasizes breaking things down into small parts and understanding the operation of each small piece. We consider substances made up of atoms, and atoms made up of electrons, protons and neutrons; protons in turn are made up of quarks and so on. Systems thinking takes the opposite approach. It seeks to understand how larger entities interact and inter-operate. Rather than looking at individual actions and explaining how each one came to occur we look at the overall system and try to understand the drivers for whole systems.

Issues arise because although all the individual pieces may be working faultlessly, when they work together in the system unintended results occur. Identifying the problems can be difficult because our training, as engineers and scientists, leads us to decompose the problem and examine individual pieces. To overcome this, we need to engage in systems thinking.

Diagnosing problems is only half the story. Once identified, these problems need to be addressed. Again, the complex interaction between multiple pieces makes solutions harder. Fixing a problem may require several coordinated changes. What may appear to be a retrograde step in one piece may actually resolve a far larger problem.

And Reflection

‘‘Skills of reflection concern slowing down our own thinking processes so that we can become aware of how we form our mental models and the ways they influence our actions. Inquiry skills concern how we operate in face-toface interactions with others, especially in dealing with complex and conflicting issues.’’ Peter Senge (1990)

In practice, reflection simply means ‘taking time to think about things’. It is very easy in a hectic environment to be so concerned with getting stuff done that we never stop to think about what we’re doing, why we’re doing it and whether we may actually be making everything worse with the fixes we apply.

Reflection is key to personal growth and development. Actively practising reflection can substantially improve our own learning process and help us achieve our aims and objectives. Team reflection can also help with enhancing team learning.

Thursday, November 26, 2009

What is The Open Source Business Model?

It is often confusing to people to learn that an open source company may give its products away for free or for a minimal cost.

How do open source companies make money?

While it is true that an open source business may not make money directly from its products, it is untrue that open source companies do not generate stable and scalable revenue streams.

In actuality, in the 21st century web technology market, it is the open source company that has the greatest long-term strategic advantage. This is demonstrated by companies such as LINUX, Apache, and Netscape, a host of web-specific technologies such as Java, Perl, TCL, and a host of web-specific technology companies such as Sendmail.

The open source business model relies on shifting the commercial value away from the actual products and generating revenue from the 'Product Halo,' or ancillary services like systems integration, support, tutorials and documentation.)

This focus on the product halo is rooted in the firm understanding that in the real-world, the value of software lies in the value-added services of the product halo and not in the product or any intellectual property that the product represents.

In actuality, the value of software products approaches zero in the fast-paced, highly-customized, ever-changing world of information technology.

But it is not simply an acknowledgement of the revenue streams generated by the product halo that makes open source a compelling business strategy.

Open source also cuts down on essential research and development costs while at the same time speeding up delivery of new products.

This paradoxical situation arises from the fact that within an open source project, the community members themselves provide free research and development by contributing new solutions, features, and ideas back to the community as a whole. The company that sits at the center of any successful open source project may reap the rewards of the work of thousands of highly-skilled developers without paying them a cent.

A final strength of the open source business model lies in its ability to market itself.

Because open source products are typically released for free, open source companies that can produce quality products and generate a good reputation can almost immediately grab huge shares of any market based on the complex and far-reaching global referral networks generated by users.

In fact, in the web technology space, almost every global standard has been based upon open source technology.

By using the open source technology model, we can create a superior product, which immediately has a competitive advantage, and which generates multiple scalable revenue streams while being freely available throughout the community.

Sunday, November 15, 2009

Another Perspective – Tests as a shared language

One of the biggest problems of developing software for someone else is the prevalent ambiguity in requirements. It is far from child’s play to express and communicate requirements in such a way that no information is lost and that the original idea is transmitted fully intact. Some would go as far as saying it’s impossible to do so. After all, we can’t read minds.

This problem is highlighted when the medium used for this communication is written documentation—a requirements specification, for example—which is far from being a perfect way to transfer information and understanding. If we were able to transform the requirements into executable tests that verify whether the system conforms to each particular aspect of the specification, there would be many fewer problems with ambiguity and less room for interpretation on behalf of developers. This is the wonderful premise of tests as specification.

Tests as specification
Tests as specification provides a way to look at tests as something that’s essentially derived from requirements; therefore—in theory at least—a system that passes the tests should by definition conform to the specification. This, however, assumes perfect test coverage, which is rarely—if ever—the case in the so-called “real world” software projects.

Defects get through testing every now and then. That is hardly news to anyone who’s lived through a couple of commercial software projects. In part, this is due to our having missed a test that we should’ve considered. In part, this is due to our human nature and our deceptive intuition, which manages to talk us out of running some of the tests to “save time.”

This begs the question, are we really better off using tests as specification if the tests we have tend to leak in one way or another? Is it really feasible to use tests as specification, effectively redefining the meaning of these concepts? Using tests as specification is not a silver bullet either, but it does have a number of clear advantages that makes it worth considering:
■ Faster feedback through automation
■ More reliable test execution
■ One less translation step

First of all, there’s no denying that having automated, executable tests would get rid of a lot of grunt work and would accelerate our feedback loop enormously compared to manually executed test cases.

Second, executable tests would effectively prevent our inherent laziness from getting us into trouble, because we would be able to exploit the fact that the computer doesn’t suffer from the same problems of character that we humans are born with. Finally, we are already making the same errors in translating the true requirements into writing with our current practice, so would it really be any worse if we’d just change the format and medium we’re using to document our test cases?

There are still plenty of opportunities to err while transforming the requirements into tests, of course, but the less knowledge transfer and human interpretation is involved in running the tests, the less chance there is that something falls into the gaps after the test has been crafted.

Specification by example
Furthermore, one of the most striking benefits of using tests as the specification driving development is that tests typically employ specification by example instead of abstraction or prose (although there should almost invariably be some amount of prose involved—things are not black and white in this respect either).

In other words, instead of the traditional “the system shall calculate tax” pattern familiar in requirements documents, specification by example promotes expressing the requirement through examples such as “for a $20 subscription with a tax rate of 10%, the system charges a total of $22 from the user’s account.”

For this simple requirement, the difference between the traditional “system shall” and an example-based version might not be that significant—after all, we all know how to calculate tax in such a trivial case. However, the requirements we meet at work are typically not as trivial, and the risk of misunderstanding is much higher. For instance, applying multiple taxes for a given transaction might need to employ different calculation rules in different locales, which can be clarified enormously through concrete examples.

Specification by example is a natural fit for our intuition and makes it easier to relate the requirements to the concrete world and our software. Specification by example can also be seen in TDD. Whereas acceptance tests specify by example the desired behavior of the system, the examples and the desired behavior specified with unit tests are specifications about the desired implementation rather than about the functionality delivered.

Higher quality inside and out, better confidence in our work, and the customer loving us for giving them software that meets their needs—who wouldn’t like these improvements, especially if it’s not just talk? After all, in theory, anything and everything is possible.


Software Development with Close collaboration


Close collaboration is essential for any complex endeavors involving people, and software development with acceptance TDD is no exception. In practice, we want to have an integrated project team instead of separate development, business analysis, and testing teams, let alone a distant QA department.

The fundamental idea is that the way to achieve the best possible level of productivity for the whole team is to nurture rapid feedback and effective, face-to-face communication around concrete, working software instead of passing around test plans, requirements specifications, and bug reports between customers, testers, business analysts, and developers. With acceptance TDD, we are able to collaborate effectively by bringing together the knowledge, skills, and abilities required for doing a good job.

Let’s see how this close collaboration helps us deliver the right product by improving our interactions and reducing the likelihood of misunderstood requirements and costly rework.

Seeing concrete, working software Very few customers have been completely satisfied with what the contractor delivers to them after several months of silence. By feeding the customer with completed functionality as a continuous stream, we’re making sure that, if there’s something wrong or missing, we’ll know about it right away.

This early feedback reduces our risks and costs. Furthermore, by not keeping an inventory of supposedly “completed” items that the customer hasn’t seen yet, we’re avoiding the usual illusion of progress that is built on assumptions and that is supported by document-driven methods and meaningless statements such as “development is 90% complete.”

Building trust and confidence
Another significant benefit of delivering working software early and often is that we’re building trust and confidence both between the team and the customer and within the team itself. By showing the customer (and ourselves) that we can deliver, we’re making life a lot easier for our whole team.

Customer in control
There’s one key difference in the role and power of the customer between incremental development and the traditional waterfall, big design, up-front style of development. With incremental development, the customer gets to choose which features they get first. Similarly, they also get to choose which features are dropped if the team is not able to implement all of them within the project’s allocated time or budget.

The customer’s decisions are, of course, influenced by the cost of the features, which the developers estimate including the cost of delaying, the cost of building things in a different order, and so forth.

The ability of the customer to decide what their money is spent on can really change the way they look at software projects. Finally, the customer is in control of what their money is spent on. Talk about motivating the customer!

Evolving a shared language By encouraging close collaboration between testers, developers, and customers, we are effectively facilitating a situation where the information needed is obtained as quickly as possible—in all directions. Furthermore, this continuous exposure within the team is likely to increase the efficiency of communication as people get to know each other better and begin to evolve a shared language. Software development is a people business, after all, and we shouldn’t neglect that fact.



Keeping code healthy with refactoring


Proceeding in small increments means that we’re constantly extending the system to do something that its current design might not support. Consequently, we’re constantly extending the system’s design in ways that might break existing concepts as well as introduce new ones.

This, in turn, means that we’re bound to end up with a broken design that’s inconsistent, unbalanced, difficult to understand, difficult to extend, or otherwise having a bad hair day. If we’re out of luck, all of them. And that would seriously hamper our ability to keep delivering software to our customers. Not to worry, though. There is a way to practice evolutionary design without letting the design rot—that way is called refactoring.

Quoting Martin Fowler, the author of Refactoring: Improving the Design of Existing Code (Addison-Wesley, 1999), refactoring is “a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.” That description manages to pack a lot of information into such a short sentence. Let’s spell it out and see what it’s actually telling us about refactoring, shall we?


Refactoring is disciplined
When refactoring (verb), we are not just altering the code’s structure but improving the design by altering it in a controlled manner—by applying small behavior preserving transformations that are called refactorings (noun). 


In other words, refactoring is about applying refactorings on code in a controlled manner. This restructuring can be a significant change to the existing design, but it is always performed in small steps, verifying at each stage that the little transformations we’ve made have not changed existing behavior.

We don’t just change code. We first identify specific problems in the design, and then we select appropriate refactorings and apply them carefully and thoughtfully. We wait until a problem begins to present itself, and only then do we solve it. We don’t predict design problems beforehand and prepare for them—that would increase the possibility of creating more problems with our system’s design than solving them.



Refactorings are transformations
A refactoring can also be thought of as a transformation between two states. The starting state has some characteristic you’d like to get rid of or otherwise improve on, and the target state represents a design that would incorporate that improvement. Below picture shows an example of a refactoring called Replace Inheritance with Delegation (also documented in Fowler’s book) that, as its name implies, moves our design from an inheritance-based solution to a delegation based solution.

The reason for doing this refactoring might be, for instance, that the subclass is only extending the superclass in order to reuse a small part of its functionality and, as an unwanted side effect, inherits a whole bunch of data and functionality we don’t care for.







Some of these refactorings are so well defined that modern development tools have automated them. This automation has made refactoring evolutionary designs&feasible for applications and systems of pretty much any size and complexity.


Refactorings alter internal structure
So these transformations are applied to the system’s internal structure—the code—which means that many of the refactorings are very low-level. For example, one of the most common refactorings is called rename method. Renaming a method or a local variable might not seem like too significant a change in the system’s design, but renaming a method from something ambiguous to something clear and concise can make a world of difference to someone new to the code and needing to understand the existing code.

Also, such low-level refactorings are the fundamental building blocks to achieving larger refactorings. These “larger” refactorings are typically those that deal with moving the responsibilities around in your code, introducing or removing an inheritance hierarchy, or making other similar changes that (usually) involve more than one class. In the end, all refactorings can be reduced into a series of smaller steps, such as renaming a variable; adding a new, empty class; changing the return type of a method; and so forth.

Although technically the most common refactorings are things like renaming a method, the number-one reason for refactoring is duplication. It might be duplication in terms of having two similar pieces of code in two methods or classes— something that could be extracted into a single method invoked in both places— but the duplication could also be in terms of responsibilities.


Duplication, of course, is bad for a code base because it makes the system more difficult to
change. Having logic and responsibility duplicated in multiple places is a guaranteed way to introduce defects due to us forgetting to make the change in all necessary corners of the code base.

In addition to not introducing defects with our changes to the code’s internal structure, we also don’t want our refactorings to add functionality. That is, refactorings should preserve behavior.


Refactorings preserve behavior
The latter part of the earlier quote by Martin Fowler says, “without changing [code’s] external behavior.” What does that mean? It means that whatever transformations you apply to the existing code, those transformations should only affect the code’s design and structure—not its externally visible behavior or functionality. In other words, client code that uses the code you’re refactoring should not notice any difference in how the refactored code behaves.

Renaming a method that’s part of a class’s public interface will obviously have to ripple through to client code as well, but the behavior of that method should not change in any way. Similarly, restructuring the code behind the public interface should not in any way change the behavior visible through the public interface.

So we think we’ve been successful at altering internal structure without changing external behavior. Cool. But how can we be sure that our refactorings haven’t changed the code’s external behavior? By running tests against our code, of course! We want to keep our software working, and tests are the tool for ensuring that.


Only ever write code to fix a failing test


Test Driven Development, is a programming technique based on a very simple rule:
Only ever write code to fix a failing test


In other words, write the test first, and only then write the code that makes it pass.This rule is controversial to many of us who have been schooled to first produce a thorough design, then implement the design, and finally test our software in order to find all those bugs we’ve injected during implementation. TDD turns this cycle around Test first, then code, and design afterward.

Does the thought of “designing afterward” feels awkward? That’s only natural. It’s not the same kind of design we’re used to in the traditional design-code-test process. In fact, it’s such a different beast that we’ve given it a different name, too. We call it refactoring to better communicate that the last step is about transforming the current design toward a better design.

 


 

Red-green-refactor is an alternative mnemonic for the TDD cycle of writing a test, making it pass, and making it pretty. What’s with the colors?


When we begin the TDD cycle by writing a test, it fails. It fails because our system is broken right now; it doesn’t have all the functionality we want it to have. In some development environments, it fails by displaying a red bar—thus the red in the mnemonic.

In the second step, making it pass, we implement the missing functionality so that all tests pass—both the one we just added and all the ones we had already.

At this time, the red bar turns to green, which takes us to green in the mnemonic. The last part of the cycle, refactor, is just that—refactoring. As we improve the design of the code without altering its external behavior, all tests should pass and, thus, we should remain green.

Red, green, green. Red, green, refactor. Quite catchy, isn’t it?


In its deceptive simplicity, this little cycle, test-code-refactor, encompasses a significant power to improve the overall quality of our personal software process and, subsequently, that of the whole team, project, and organization.



Reference: Test Driven PRACTICAL TDD AND ACCEPTANCE TDD FOR JAVA DEVELOPERS by LASSE KOSKELA - Manning 2008