|A||Acceptance Criteria/Test, Automation, A/B Testing, Adaptive Planning, Appreciative inquiry|
|B||Backlog, Business Value, Burndown, Big Visible Charts, Behavior Driven Development, Bugs, Build Monkey, Big Design Up Front (BDUF)|
|C||Continuous Integration, Continuous Deployment, Continuous Improvement, Celebration, Capacity Planning, Code Smells, Customer Development, Customer Collaboration, Code Coverage, Cyclomatic Complexity, Cycle Time, Collective Ownership, Cross functional Team, C3 (Complexity, Coverage and Churn), Critical Chain|
|D||Definition of Done (DoD)/Doneness Criteria, Done Done, Daily Scrum, Deliverables, Dojos, Drum Buffer Rope|
|E||Epic, Evolutionary Design, Energized Work, Exploratory Testing|
|F||Flow, Fail-Fast, Feature Teams, Five Whys|
|G||Grooming (Backlog) Meeting, Gemba|
|I||Impediment, Iteration, Inspect and Adapt, Informative Workspace, Information radiator, Immunization test, IKIWISI (I’ll Know It When I See It)|
|K||Kanban, Kaizen, Knowledge Workers|
|L||Last responsible moment, Lead time, Lean Thinking|
|M||Minimum Viable Product (MVP), Minimum Marketable Features, Mock Objects, Mistake Proofing, MOSCOW Priority, Mindfulness, Muda|
|N||Non-functional Requirements, Non-value add|
|O||Onsite customer, Opportunity Backlog, Organizational Transformation, Osmotic Communication|
|P||Pivot, Product Discovery, Product Owner, Pair Programming, Planning Game, Potentially shippable product, Pull-based-planning, Predictability Paradox|
|Q||Quality First, Queuing theory|
|R||Refactoring, Retrospective, Reviews, Release Roadmap, Risk log, Root cause analysis|
|S||Simplicity, Sprint, Story Points, Standup Meeting, Scrum Master, Sprint Backlog, Self-Organized Teams, Story Map, Sashimi, Sustainable pace, Set-based development, Service time, Spike, Stakeholder, Stop-the-line, Sprint Termination, Single Click Deploy, Systems Thinking, Single Minute Setup, Safe Fail Experimentation|
|T||Technical Debt, Test Driven Development, Ten minute build, Theme, Tracer bullet, Task Board, Theory of Constraints, Throughput, Timeboxing, Testing Pyramid, Three-Sixty Review|
|U||User Story, Unit Tests, Ubiquitous Language, User Centered Design|
|V||Velocity, Value Stream Mapping, Vision Statement, Vanity metrics, Voice of the Customer, Visual controls|
|W||Work in Progress (WIP), Whole Team, Working Software, War Room, Waste Elimination|
|Y||YAGNI (You Aren’t Gonna Need It)|
|Z||Zero Downtime Deployment, Zen Mind|
Often people tell you that “You should think about the long-term.”
Sometimes people tell you, “Forget long-term, its too vague, but you should at least think beyond the near-term.”
Unfortunately, part of my brain (prefrontal cortex), which can see and analyze the future, has failed to develop compared to the other smart beings.
At times, I try to fool myself saying I can anticipate the future, but usually when I get there (future) its quite different. I realize that the way I think about the future is fundamentally flawed. I take the present and fill it with random guesses about something that might happen. But I always miss things that I’m not aware of or not exposed to.
In today’s world, when there are a lot of new ideas/stuff going around us, I’m amazed how others can project themselves into the future and plan their long-terms?
Imagine a tech-company planning their long-term plan, 5-years ago, when there were no iPads/tablets. They all must have guessed a tablet revolution and accounted that in their long-term plans. Or even if they did not, it would have been easy for them to embrace it right?
You could argue that the tablet revolution is a one-off phenomenon or an outlier. Generally things around here are very predictable and we can plan our long-term without an issue. Global economics, stability of government, rules and regulations, emergence of new technologies, new markets, movement of people, changes in their aspirations, environmental issues, none of these impact us in any way.
Good for you! Unfortunately I don’t live in a world like that (or at least don’t fool myself thinking about the world that way.)
By now, you must be aware that we live in a complex adaptive world and we humans ourselves are complex adaptive system. In complex adaptive system, the causality is retrospectively coherent. .i.e. hindsight does not lead to foresight.
10 years ago, when I first read about YAGNI and DTSTTCPW, I thought that was profound. It was against the common wisdom of how people designed software. Software development has come a long way since then. But is XP the best way to build software? Don’t know. Question is, people who used these principles did they build great systems? Answer is: Yes, quite a few of them.
In essence, I think one should certainly think about the future, make reasonable (quick) guesses and move on. Key is to always keep an open mind and listen to subtle changes around us.
One cannot solely rely on their “intuition” about long term. Arguing on things you’ve all only guessed seems like a huge waste of time and effort. Remember there is a point of diminishing returns and more time you spend thinking long-term, less your chances are of getting it right.
I’m a strong believer of “Action Precedes Clarity!”
Update: In response to many comments: When the Future is Uncertain, How Important is A Long-Term Plan?
I regularly practice Test Driven Development. I truly believe in its benefits and also have been able to influence a huge number of develops to practice it.
However, there are situations in which I ask myself questions like:
- Is it important to automate this particular check (test) ?
- Will it be worth the effort/investment or is it YAGNI?
- What is the possibility of this particular scenario breaking (risk)?
- And so on…
Yesterday I was faced with a similar situation where I decided to skip the automated test.
Context: I was working on a website where users can use their credit card while shopping online. Basically the website had a simple text input box to accept the credit card number. It turns out that most browsers (except Safari) caches the input data and stores it in plain text somewhere on the computer.
So we wanted to turn off the auto-complete and caching feature on this specific input field. There is a very easy way to do this. Just need to set autocomplete=”off” in the input tag. For example:
<input type=”TEXT” name=”creditcard” autocomplete=”off” />
Its an easy fix and quite widely used. So that’s great. But how do I write an automated test for this?
If we think a little hard, there are ways to write automated test. But then you ask yourself is it worth it?
This site had lived without this feature for so long, so I did not think it was that crucial to its users. Even if this feature stops works, it won’t bring the site down. (They certainly had a good battery of automated tests which tests the core functionality if the product.) So I choose to skip the automated test. I manually tested it with different browsers made sure it was working as expected.
If this comes back and bites me, I’ll certainly invest in some form of safety net, but for now, time to hack some more code.
What would you choose to do?
Following is a list of random topics (most of them are Agile/XP practices) about this project:
- Project Inception: We started off with a couple of meetings with folks from Freeset to understand their needs. David quickly created an initial vision document with User Personas and their use cases (about 2 page long on Google Docs). Naomi and John from Freeset, quickly created some screen mock-ups in Photoshop to show user interaction. I don’t think we spent more than a week on all of this. This helped us get started.
- Technology Choice: When we started we had to decide what platform are we going to use to build the site. We had to choose between customer site using Rails v/s using CMS. I think David was leaning towards RoR. I talked to folks at Directi (Sandeep, Jinesh, Latesh, etc) and we thought instead of building a custom website from scratch, we should use a CMS. After a bit of research, we settled on CMS Made Simple, for the following reasons
- We needed different templates for different pages on the site.
- PHP: Easiest to set up a PHP site with MySQL on any Shared Host Service Provider
- Planning: We started off with an hour long, bi-weekly planning meetings (conf calls on Skype) on every Saturday morning (India time). We had a massively distributed team. John was in New Zealand. David and Deborah (from BestBuy) were in US. Kerry was in UK for a short while. Naomi, Kelsea and other were in Kolkatta and I was based out of Mumbai. Because of the time zone difference and because we’re all working on this part time, the whole bi-weekly planning meeting felt awkward and heavy weight. So after about 3 such meetings we abandoned it. We created a spreadsheet on Google Docs, added all the items that had high priority and started signing up for tasks. Whenever anyone updated an item on the sheet, everyone would be notified about the change.
- User Stories: We started off with User Persona and Stories, but soon we just fell back to simple tasks on a shared spreadsheet. We had quite a few user related tasks, but just one liner in the spread sheet was more than sufficient. We used this spreadsheet as a sudo-backlog. (by no means we had the rigor to try and build a proper backlog).
- Short Releases: We (were) only working on production environment. Every change made by a developer was immediately live. Only recently we created a development environment (replica of production), on which we do all our development. (I asked John from Freeset, if this change helped him, he had mixed feelings. Recently he did a large website restructuring (added some new section and moved some pages around), and he found the development environment useful for that. But for other things, when he wants to make some small changes, he finds it an over kill to make changes to dev and then sync it up with production. There are also things like news, which makes sense to do on the production server. Now he has to do in both places). So I’m thinking may be, we move back to just production environment and then create a prod on demand if we are plan to make big changes.
- Testing: Original we had plans of at least recording or scripting some Selenium tests to make sure the site is behaving the way we expected it to. This kind of took a back seat and never really became an issue. Recently we had a slight set back when we moved a whole bunch of pages around and their link from other parts of the site were broken. Other than that, so far, its just been fine.
- Usability: We still have lots of usability and optimization issues on our site. Since we don’t have an expert with us and we can’t afford one, we are doing the best we can with what we have on hand. We are hoping we’ll find a volunteer some day soon to help us on this front.
- Versioning: We explored various options for versioning, but as of today we don’t have any repository under which we version our site (content and code). This is a drawback of using an online CMS. Having said that so far (been over a year), we did not really find the need for versioning. As of now we have 4 people working on this site and it just seems to work fine. Reminds me of YAGNI. (May be in future when we have more collaborators, we might need this).
- Continuous Integration: With out Versioning and Testing, CI is out of question.
- Automated Deployment: Until recently we only had one server (production) so there was no need for deployment. Since now we have a dev and a prod environment, Devdas and I quickly hacked a simple shell scrip (with mysqldump & rsync) that does automated deployment. It can’t get simpler than this.
- Hosting: We talked about hosting the site on its own slice v/s using an existing shared host account. We could always move the site to another location when our existing, cheap hosting option will not suit our needs. So as of today, I’m hosting the site under one of my shared host account.
- Rich Media Content: We questioned serving & hosting rich media content like videos from our site or using YouTube to host them. We went with YouTube for the following reasons
- We wanted to redirect any possible traffic to other sites which are more tuned to catering high bandwidth content
- We wanted to use YouTube’s existing customer base to attract traffic to our site
- Since we knew we’ll be moving to another hosting service, we did not want to keep all those videos on the server which then will have to be moved to the new server
- Customer Feedback: So far we have received great feedback from users of this site. We’ve also seen a huge growth in traffic to our site. Currently hovering around 1500 hits per day. Other than getting feedback from users. We also look at Google Analytics to see how users are responding to changes we’ve made and so on.
- We don’t really have/need a System Metaphor and we are not paying as much attention to refactoring. We have some light conventions but we don’t really have any coding standards. Nor do we have the luxury to pair program.
- Distributed/Virtual Team: Since all of us are distributed and traveling, we don’t really have the concept of site. Forget on-site customer or product owner.
- Since all of this is voluntary work, Sustainable pace takes a very different meaning. Sometimes what we do is not sustainable, but that’s the need of the hour. However all of us really like and want to work on this project. We have a sense of ownership. (collective ownership)
- We’ve never really sat down and done a retrospective. May be once in a while we ask a couple of questions regarding how something were going.
Overall, I’ve been extremely happy with the choices we’ve made. I’m not suggesting every project should be run this way. I’m trying to highlight an example of what being agile really means.
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.
Go ahead, kill it!
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.