Mentoring in Software Craftsmanship

Maria Diaconu and  Alexandru Bolboaca are both strong supporters of Software Craftsmanship and Agile movements in Romania, with years of experience as developers, leaders, architects, managers and instructors. On their lecture at Agile Central Eur…Maria Diaconu and  Alexandru Bolboaca are both strong supporters of Software Craftsmanship and Agile movements in Romania, with years of experience as developers, leaders, architects, managers and instructors. On their lecture at Agile Central Eur…

Maria Diaconu and  Alexandru Bolboaca are both strong supporters of Software Craftsmanship and Agile movements in Romania, with years of experience as developers, leaders, architects, managers and instructors. On their lecture at Agile Central Europe Conference they were talking about Software  Craftsmanship movement. While Sobótka at 4Developers was showing what Craftsmanship from the code point of view is, our guests from Romania gave us a brief introduction into the process of becoming a Craftsman.

The fact, that university education for programmers doesn’t give us skills suitable for professional environment is old news (at least in Poland and Romania). While steps are being taken in the right direction, it’s going to take a while to get there, and that’s where  Software Craftsmanship movement comes in handy.

The core concept of the presentation, was that if you want to go pro, you should understand the way you need to follow. In other crafts, there are practices recognized as the core of a profession. Programming is so vast, that you may get lost on the way, and certifications like SCP do not help much, as they are too technology oriented, looking more like a “technological masturbation” (technology for itself) rather than a way to really learn something useful. Software craftsmanship has a concept of mentoring, which is based on one of Agile  principles: “individuals and interactions over processes and tools”.

How does it work in practice? To become a craftsman you start as an apprentice at some master of your choice. If you’re lucky, you’ll find someone to work for and learn from. If not (you have to work in a bad environment to get by, or everyone around doesn’t have more experience than you do), you can choose a well known writer, such as Martin Fowler or Robert C. Marting (Clean Code is a great start) and learn from him (all of them, even better). But that’s not enough. Next step would be to participate in the community (local language user groups, etc.) and finally, to get your ass to other places and learn from people out there. That means conferences, but also a week-out pair programming in another company, far, far away, an idea more and more popular in US, as you can see at software_craftsmanship google group. After all a journeyman has a “journey” part in it, doesn’t it?

So easy so far, right? Nothing new and mind-shaking?

The thing is to understand, that while official certifications are a great magnet for potential employers, skills of a good programmer don’t come from certification books. Skills come from work experience with other good programmers. That’s why Pair Programming is so important. That’s why you should start going for local language/craftsmanship group meetings even if you do not understand everything they are talking about. That’s why it’s more important to work WITH a great programmer than to work FOR a well known company.

I’ve seen so many people understating the technology to the ground, yet failing to create a good software solution,  because they’ve never ever seen, how a good solution is build. I’ve heard opinions that “no software is maintainable” from people with 10+ years of experience in Java.

All you really need is a mentor. A master, that can show you, what a great software is written like.

Sławomir Sobótka, answering the question “How to start with Java” on Jacek Laskowski’s blog, wrote lately: “I’d leave SCJP and similar sadomasochisms for later, maybe in a few years time, or even better, I’d boycott it all together”. He is damn right.

Robert C. Martin has a very interesting entry on his blog “Developer Certification WTF?”, where he is explaining why  official certification programs are so much bullshit these days. Beware of big companies as well, remember that “big and successful company” doesn’t mean “a good place to get better”. On the contrary, it sometimes means: “a place where an apprentice is treated like shit and a code monkey”. Check the company for people and methods that you’re going to be involved with on daily basis, before you send your CV. Ask a lot of questions, talk to the guys working there, if you can, ask to spend some time with the team, do some pair programming, and see what they are up to.

While chances are, in most companies your CV is going to be processed forward basing on buzzwords and certificates, the most important thing is to check whether the people you are going to work with can inspire you, bring you to the next level. And vice-versa. This is exactly what Thoughtworks is doing. Don’t be afraid to risk you stability and position to get more knowledge and experience. If you’ve been playing Heroes of Might and Magic, you probably know damn well, that to choose experience is better than to choose money in the long run. Always.

If you want more tips what to look for when searching for a good employer, have a look here.

Mentoring should not to be underestimated. When Piotr Jagielski began his speech about refactoring test code, at Agile Central Europe Conference, he started with saying that he was very lucky to get a great mentor at the very beginning of his work. I’m sharing similar experience: while I’ve started my carrier as an analyst in a long waterfallish kind of a project, when I’ve moved into programming I was extremely lucky to work with Piotr Szarwas, the guy who in one year taught me more than 5 years of university and two years of former software experience all together.

And if you already are a good programmer, remember that learning never stops. When you are a master, you are a student as well.

“Even today, I dare not say that I have reached a state of achievement. I’m still learning, for learning is boundless.“ [Bruce Lee, Tao of Jeet Kune Do]

You May Also Like

JDay 2014 in Lviv sponsored by TouK

We're glad to announce that our company supports as a gold sponsor the JDay conference taking place in Ukraine on the 6th of September. Maciek Próchniak and Bartek Zdanowski from TouK will give thair presentations during the event.

Log4j and MDC in Grails

Log4j provides very useful feature: MDC - mapped diagnostic context. It can be used to store data in context of current thread. It may sound scary a bit but idea is simple.

My post is based on post http://burtbeckwith.com/blog/?p=521 from Burt Beckwith's excellent blog, it's definitely worth checking if you are interested in Grails.

Short background story...


Suppose we want to do logging our brand new shopping system and we want to have in each log customer's shopping basket number. And our system can be used at once by many users who can perform many transactions, actions like adding items and so on. How can we achieve that? Of course we can add basket number in every place where we do some logging but this task would be boring and error-prone. 

Instead of this we can use MDC to store variable with basket number in map. 

In fact MDC can be treated as map of custom values for current thread that can be used by logger. 


How to do that with Grails?


Using MDC with Grails is quite simple. All we need to do is to create our own custom filter which works for given urls and puts our data in MDC.

Filters in Grails are classes in directory grails-app/conf/* which names end with *Filters.groovy postfix. We can create this class manually or use Grails command: 
grails create-filters info.rnowak.App.Basket

In result class named BasketFilters will be created in grails-app/conf/info/rnowak/UberApp.

Initially filter class looks a little bit empty:
class BasketFilters {
def filters = {
all(controller:'*', action:'*') {
before = {

}
after = { Map model ->

}
afterView = { Exception e ->

}
}
}
}
All we need to do is fill empty closures, modify filter properties and put some data into MDC.

all is the general name of our filter, as class BasketFilters (plural!) can contain many various filters. You can name it whatever you want, for this post let assume it will be named basketFilter

Another thing is change of filter parameters. According to official documentation (link) we can customize our filter in many ways. You can specify controller to be filtered, its actions, filtered urls and so on. In our example you can stay with default option where filter is applied to every action of every controller. If you are interested in filtering only some urls, use uri parameter with expression describing desired urls to be filtered.

Three closures that are already defined in template have their function and they are started in these conditions:

  • before - as name says, it is executed before filtered action takes place
  • after - similarly, it is called after the action
  • afterView - called after rendering of the actions view
Ok, so now we know what are these mysterious methods and when they are called. But what can be done within them? In official Grails docs (link again) under section 7.6.3 there is a list of properties that are available to use in filter.

With that knowledge, we can proceed to implementing filter.

Putting something into MDC in filter


What we want to do is quite easy: we want to retrieve basket number from parameters and put it into MDC in our filter:
class BasketFilters {
def filters = {
basketFilter(controller:'*', action:'*') {
before = {
MDC.put("basketNumber", params.basketNumber ?: "")
}
after = { Map model ->
MDC.remove("basketNumber")
}
}
}
}

We retrieve basket number from Grails params map and then we put in map under specified key ("basketNumber" in this case), which will be later used in logger conversion pattern. It is important to remove custom value after processing of action to avoid leaks.

So we are putting something into MDC. But how make use of it in logs?


We can refer to custom data in MDC in conversion patter using syntax: %X{key}, where key is our key we used in filter to put data, like:
def conversionPattern = "%d{yyyy-MM-dd HH:mm:ss} %-5p %t [%c{1}] %X{basketNumber} - %m%n"


And that's it :) We've put custom data in log4j MDC and successfully used it in logs to display interesting values.