Sunday, September 21, 2014

Terry Pratchett, the Long Earth and IT projects

No comments:
I’ve just finished reading the “The Long Earth” novel by Terry Pratchett and Steven Baxter. While I expected the book to be more Pratchett’ish in the sense of humour (it’s not) I found it a very inspiring read anyway.

Parallel worlds

“Long Earth” is based on the idea of parallel worlds. While reading it, I couldn’t resist the temptation of imagining what would happen if we had the same idea applied to IT projects.

Remember the last time you started a project? I’m sure you’ve had some ideas on which architecture to choose or more likely, which language/framework to base it on.

Should we go with Rails? Isn’t node.js the better thing nowadays? Is it a good idea to go with CQRS here? Scala will save us? This time it will be better?

Now, imagine that all the decisions were made and all the alternative realities are happening.

Let’s say, that in the Primary World you went with Rails, Angular, without CQRS.

3 months in, you have the typical Rails problems, the models are overloaded with responsibilities, the controllers are not really that thin. The build now takes 5 minutes while most of the frontend code is untested. The team members start complaining - “We wouldn’t have such problems with Node.js”, “Can you see it now - we should have gone with CQRS in the first place”, “Scala, we need Scala, because of reasons (monads)”.

Given the idea of parallel worlds (or rather parallel IT projects), you could jump into the world where Scala was chosen, just to notice, that the project is even in a worse shape, because some people didn’t get the idea of non-mutating state and it’s all not pure enough, while the frontend is not done at all, because all the time was spent discussing why Scala is actually worse than Haskell.

Then you jump into the node.js alternative world. A quick look at the codebase - yes, callbacks everywhere. How did it go with code reuse on server/frontend? Oh yes, they don’t really share that much. Also, part of the codebase is in JS, while the other parts are in CoffeeScript, because you hired those new JavaScript developers, who hate Coffee, while the Rubyists in the team can’t parse JS at all.

Wouldn’t that be great?

It’s all science-fiction obviously. I wonder, though, how much would it change our decision making process, if we knew that we could always look at how it goes in the alternative worlds.

Would it make our decisions better?

Would we learn that all projects have problems at some point, despite the technologies and architecture choices?

Would we learn that no matter what we do, we may end up with another legacy codebase?

Now, back to reality. We have only one, the Primary World. We can’t jump into other worlds. What tools do we have to measure our decisions? Is it actually worth to measure at such a high level?

Maybe it’s better to just learn how to get out of any mess that we (and others) create?



Wednesday, July 2, 2014

The secret to change your team habits

No comments:
Over the last few weeks, we've been sending several lessons to our Arkency Newsletter  (not there yet?) on how to become more Async with your programming team. They included techniques like:

Async, textual, standups
Async knowledge sharing and gathering documentation before synchronous online meetings
Using and building tools which can greatly support you with your async and/or remote environment
Splitting bigger stories into smaller ones on the fly
And more...


By applying those lessons, you can make your team more effective. It doesn't matter if you do Rails, Python or Java. The team techniques and problems remain the same.

I'm sure, you've noticed that it's not as easy to switch the team habits to the new ones.


Why do the people forget to work on small stories only?
Why it's so hard to introduce async standups instead of the sync, voice-based ones, that everyone loves?
Why are people not reviewing each other code changes?

The thing is, it's hard to eliminate habits (ask any smoker!).

There are two rules for introducing new habits:
  1. Know what's your goal, what are the new habits to introduce. Luckily, you know the techniques we suggested in our email course and in our book.
  2. It's easier to change existing habits than to eliminate them

The second point is crucial (and that's the secret!):

Habits are based on hooks (think Aspect Oriented Programming, but in real life).

What are the current habits in your team? Is it that everyone prepares at 9.50am, because at 10am the standup starts? Don't try to eliminate it (yet), just turn it into something different. Do the text-based standup instead, even if it's at the same time with everybody. Just share your statuses in the communication tools or in the Google Doc or Hackpad. That's a smaller step and probably more likely to be adopted. Heck, you can even do it, while all are on Skype, if you prefer even smaller steps.

There's a cool concept of Tiny Habits, that can help your team change more easily. This concept is directed towards single people and their habits, but the mechanisms stay the same for the team - try it and apply it for your team (it's free!):http://tinyhabits.com/

A good experiment is to identify your team "hooks". Some example ones may include:
  • a new commit pushed to the repo
  • new build failure
  • standup time
  • weekly meeting time
  • start of the day of work
  • end of the day of work
  • lunch time
  • new deployment
Once you identify your hooks, try to replace the actions that happen before/after the hook happens. Make it as simple as possible!

Let's say, that one of your goals is to increase the knowledge transfer in your team and you decided that the 'foreman' technique is the way to go. The simplest form of 'foreman' is to review someone's else code. You can gradually introduce it as a technique in your team, that whenever anyone finishes a ticker ("after finish ticket" - hook), they look at some of the recent commits (action!) in the repo and comment on them (even if it's a simple "+1"). At the beginning, you can make it just 10 minutes. It's enough to at least look at some code.

Hook: You finished a ticket
Action: Review someone's else code for 10 minutes

You can't do much in 10 minutes, but if you know the Kronos/Chairos time management technique, that we were promoting, you know how to use the time best.

Good luck!

If you feel, like there's still more you can learn about the new async team techniques, just grab our recent book - it's designed to safely refactor your team towards being more effective!

Tuesday, June 10, 2014

Custom exceptions or domain events?

7 comments:
The topic of custom exceptions is surprisingly controversial. Some argue that exceptions shouldn't be used for anything related to "business", while others (me included) say that exceptions like InsufficientFunds are fine - I even wrote a whole chapter about using custom exceptions to simplify controllers in my Rails Refactoring book.

I've read an interesting blog post today about custom exceptions (here - unfortunately it's in Polish), where the author advocates for using "business exceptions".

The example comes from a dialling application, so there are the following exceptions:

  • CallAlreadyInProgressException, 
  • IncorrectNumberException, 
  • NumberAlreadyDialedException

When I first looked at the code, I nodded in agreement. Given such domain, those exceptions make total sense to me. I'd implement it the same way.

When I linked to this post in our team chat, Mirek (who has more knowledge about DDD and CQRS than I do) said that it'd be better to implement with domain events. This surprised me a bit, as when the topic of custom exceptions is brought up, domain events are rarely shown as an alternative.

What's the difference between custom exceptions and domain events?

Look at this code:

Domain events decouple the call to the method from returning the result. This is at the core of the CQRS approach - one of the most inspiring architectures I've ever read about. In short - any system operation is either a Command (a change to the system) or a Query (a read from the system). This rule drives the whole architecture.

In the code, it means that when you call dialler.call(number), you're not directly interested in the result, even to the point, that the method can fail (raise an exception). You made a command and that's it.

Now, obviously, you do need to know about the failure. That's why you publish an event, using whatever mechanism under the hood. It can be a simple singleton EventBus class, which just keeps a map of objects interested in certain events and notifies them if any such event happens. In our case, we could have a UINotifier class listening to the CallAlreadyInProgress event and sending a special UI message to the user of the system (the technical details are not important here - it can be via polling or Web Sockets).

There is another difference - with events we need to "publish" the fact that all went fine. What was implicit with exceptions (no exception is raised - success), here needs to be explicit. We publish the "ConnectionEstablished" event.

This creates a nice simplification of the whole code around it. It may make it a bit more indirect, but it's actually very simple. All of the pieces of code involved do just one thing.



Wednesday, May 28, 2014

Remote team - mobile tools

2 comments:
When working remotely and/or asynchronously you may be often in situations where a mobile access to the team/project data is very useful. See my previous blog post on desktop tools for remote teams.

Here is a list of tools I often use in the context of the Arkency team. I use all of them from my iPhone 5s. I think most of them have their Android versions.


  • Team/project
    • Slack
      • our IM tool of choice, good UX, easy to use, even with a 20+ team
      • the nice thing is that it caches all the history of our channels, so I can sync with them whenever I want
    • Hackpad
      • accessing offline and creating hackpads offline is the killer feature
    • Trello
    • iOctocat
      • This app pushes me a notification whenever any new commit appears in any of my github repos. I can easily review the diff, comment on the changes or just browse through the code - highly recommended!
      • basic version is free. it's worth upgrading to receive notifications ($12.99)
    • Mumble
      • the voice communication tool of our choice, push to talk, multiple rooms
  • Social
    • Twitter
    • Facebook
    • AlienBlue
      • a Reddit client - useful if you often post your blog posts to Reddits
      • free, but worth upgrading for $1.99
  • Getting Things Done
    • MindNode
      • $9.99
      • it's the mind mapping tool, that I was looking for a long time
      • it has a Mac version (paid separately) and integrates/syncs via iCloud
    • Evernote
      • Quick to find important information, even from a mobile.
  • Geo
    • Foursquare
      • Even though, we are a remote team, many of us live in the Wroclaw area. When people are in the habit of checking in, you can easily see if anyone is close to you right now. I'm a strong believer of async/remote work but when there's a chance to meet face to face, that's always a good idea!



This blogpost is a work-in-progress chapter from the "Developer Oriented Project Management" book. The book is just weeks before the final release. Grab it now, before the price goes up!



Monday, May 26, 2014

Async standups

No comments:
When you work remotely, you want to have some kind of a standup meeting regularly. In our team, after experimenting with many different approaches, we settled with text-based, asynchronous standups every day. Additionally, every project has a weekly 'sync' meeting.

Whatever tool we currently use for remote communication (irc in the past, now Slack), we create a channel that is dedicated to #standup. We don't have a specific time to post there, usually we do it, when we begin our work session - so, in the spirit of async - different people at different times.

I consider #standup to be a very good opportunity to communicate cross-project, to educate, to learn, to help. Short standup messages are not bad, but they miss this opportunity.

When writing the standup message, think more about the others, than about yourself - what can they get from it by reading your status?

Example 

Yesterday I finished the "fix the price calculator" feature, which was mostly about removing the Coffee code and rely on the value retrieved from the backend, via ajax. The nice thing was that the backend code was already covered with tests, while the Coffee one wasn't. After that I helped Jack with the "allow logging in with email" feature (we need it now because we have a batch import of users from system X soon). After that I did a small ticket, where I block buying licences for special periods of time. This was nicely TDD'ed, thanks to the concept of aggregate, introduced by Robert recently - all the tests pass < 1s. Here is a commit worth looking at: .
Today I'm going to start with foreman'ing the recent commits and after that I want to work the XYZ system to allow a better editing of entries. I'm not sure how to start it, so all help is welcome.

What's good?


  • many details, 
  • letting other people jump in and help me,
  • some opinions about the code that I saw, 
  • some details about practices I applied (TDD, foreman'ing) 
  • reminds about some business information - import of users from the X system, happening soon 
  • links to the commit (potential education) 


Format 

1. yesterday
2. today
3. good thing
4. bad things
5. challenges
6. call for help
7. reminder about good practices (tdd, foreman, help colleagues) 
8. code examples (link)
9. business-related info


(this blog post is a work-in-progress chapter in the Developer-oriented Project Management book.)

Tuesday, April 29, 2014

Remote team tools

2 comments:
I've been speaking today at a local IT entrepreneur meetup about remote work and about the ways a company can transition towards being more remote.

The part of the talk that seemed to be most interesting was the toolset that we're using at the moment. I thought I'd share this list here, as well.

Remember, that tools should just support your process and not replace it. If your goals are clear to you and your team, then the tools are just implementation details.

  • Internal (written) Communication - IRC
  • Requirements/Tickets - Trello
  • Documentation - Hackpad
  • Voice communication - Mumble
  • Code reviews - Github
  • Continuous Integration - Jenkins
  • Remote pairing - tmux
  • Video calls - Google Hangouts


Internal (written) Communication - IRC

For most of the internal communication in the team, we've been using IRC. It's a kind of a old-school tool. It served us well for about 7 years now, but meanwhile we've been experimenting with alternatives, like Slack (just recently).

The tool itself is not that important, it's the goal it serves that is interesting.

We have one channel per project and several generic channels, like #lol, #arkency, #links, #coffee, #products, #blog.

The project channels are often integrated with other tools and receive notifications from Trello, Github, Jenkins. This is like the headquarters.

In some projects we also use Slack or Flowdock for the same goal.

Requirements/Tickets - Trello

This is our default project management tool. It works as a backlog. It contains many tickets/stories, prioritised and described. It helps detailing the requirements and seeing what's the status.

The tickets are also refactored - we extract new tickets, rename them, group them - whatever is needed.

In some projects we use Pivotal, Redmine or Asana for the same goal.

Documentation  - Hackpad

Hackpad - this is my favourite one. If you're not familiar with it already, it works similarly to Google Docs. In my opinion, it's a bit more interactive.

It's basically a wiki on steroids. It has support for collections, it notifies about changes via email. You clearly see who wrote what. You can comment sections of code and checkboxes.

Whatever interesting happens in our company, it gets an URL on Hackpad. Do I have an idea for a bigger refactoring in one project? I create a hackpad, paste some code and describe the plan. Others can join whenever they want (async!) and add their comments.

Voice communication - Mumble

Mumble is probably unknown to you. It's a tool very popular among gamers. They use it to communicate in a team, during a game. We started using it, as it was much more reliable than Skype. It's a very minimalistic tool. It has the concept of channels, so we designed it similarly to our communication tool (IRC). It also allows recording the conversations, so that people who were not able to attend (async!) can later listen to the most important fragments.

Code reviews - Github

We use Github for hosting code and for making the micro-code reviews. I call it micro, as they only let us comment the deltas - commits or pull request. They don't let us comment the existing code base, which is a limitation many similar tools share.
If there's one place, I'd like to see improvement for remote teams it would be a proper code review tool.

Continuous Integration - Jenkins

We host the Jenkins instances to build our projects. I'm very far from liking it - it has many quirks, but overall we didn't find a good alternative to switch, yet.

Remote pairing - tmux

I blogged about remote pair programming 6 years ago. At that time, I was using screen + vim and I still think it's a good combo (together with Skype or Mumble). Nowadays, we don't pair program too often, but when people in my team do that, they often use tmux to connect to each other (terminal-based). Another tool is tmate.io, which is also tmux-based.

On a good connection you can also use Google Hangouts and their Desktop Sharing feature.

Video calls - Google Hangouts

We use video calls very rarely and mostly, when external teams are involved who prefer it. In that case, we use Google Hangouts.

Summary

It's important to understand that those are only tools. They can change. I'm pretty sure, next year, we'll use a different toolset. What's important is the process around it - how you collaborate on projects, how you split stories, how you discuss, how you collaborate on the code.


If you'd like to learn more about the techniques that we use in our remote and async collaboration (not only about the tools), then let me recommend the Robert Pankowecki book about it (I also wrote one chapter): Developer Oriented Project Management.

What tools are you using? What would you recommend?

Sunday, April 27, 2014

TDD and Rails - what makes a good Unit?

No comments:
There is an ongoing discussion about TDD and Rails. It was recently heated by some some of the DHH statements in his RailsConf keynote and in the blog post: http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html

One aspect of this discussion is the confusion about - What makes a good Unit?

In the Rails community, I've seen people overusing mocks and stubs - you can detect it by looking at all the "should_receive" calls in the codebase. They're not always bad, but they might be potential code smells.

The reason we use should_receive is in a way to draw the boundary between what's important to test right now and what's outside of the test scope.

Unit example

Let's take an example - you've got an Order, which can have many OrderLines, a ShippingAddress and a Customer.

Do we have 4 units here, representing each class? It depends, but most likely it may be easier to treat the whole thing as a Unit. You can write a test which test the whole thing through the Order object. The test is never aware of the existence of the ShippingAddress. It's an internal implementation detail of the Order unit.

A class doesn't usually make a good Unit, it's usually a collection of classes that is interesting.

This way of defining a Unit gives you tests, that don't need to change whenever the internals change - that's a good thing. You don't want to change tests on every refactoring - in fact it's a smell.

Unit-based architectures

Some time ago, I wrote a surprisingly popular post: The four architectures that will inspire your programming in which I listed:


  • Hexagonal Architecture
  • Clean Architecture
  • DDD
  • DCI

In a way, all of them are focused on defining what a good Unit is and how to separate it from other Units. 

DDD has the concept of an aggregate, quote: "A DDD aggregate is a cluster of domain objects that can be treated as a single unit."

Clean Architecture has the concept of use-cases which touch the topic slightly differently (by operations, not units), but overall it's very similar: http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

Hexagonal Architecture is all about a Unit surrounded by adapters, in my interpretation. They often call it the Middle Hex. http://alistair.cockburn.us/Hexagonal+architecture

Last, but not least - DCI. This architecture deserves a special mention here. DHH quoted James Coplien in his TDD talk. James has been famous not only from his strong opinions on TDD, but more from his activity in the DCI world. He's one of the fathers of this movement. DCI is the most inspiring architecture here. Ruby and DCI makes a fantastic combination, however not all can work as in the DCI theory. DCI gives good tools for defining what a Unit can be. In short, their approach to what a Context is, may be used to defining Units. A Unit is this paradigm is a collaboration of objects. Read more here: http://fulloo.info/

Have fun in researching more!

If you want to follow more of my work - I'm writing a book on Refactoring Rails apps, which is already available. At the moment, I'm writing new chapters on how to write tests that support refactoring of Rails apps.