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

How we use Kotlin with Exposed at TouK

Why Kotlin? At TouK, we try to early adopt technologies. We don’t have a starter project skeleton that is reused in every new project, we want to try something that fits the project needs, even if it’s not that popular yet. We tried Kotlin first it mid 2016, right after reaching 1.0.2 version

Grails session timeout without XML

This article shows clean, non hacky way of configuring featureful event listeners for Grails application servlet context. Feat. HttpSessionListener as a Spring bean example with session timeout depending on whether user account is premium or not.

Common approaches

Speaking of session timeout config in Grails, a default approach is to install templates with a command. This way we got direct access to web.xml file. Also more unnecessary files are created. Despite that unnecessary files are unnecessary, we should also remember some other common knowledge: XML is not for humans.

Another, a bit more hacky, way is to create mysterious scripts/_Events.groovy file. Inside of which, by using not less enigmatic closure: eventWebXmlEnd = { filename -> ... }we can parse and hack into web.xml with a help of XmlSlurper.
Even though lot of Grails plugins do it similar way, still it’s not really straightforward, is it? Besides, where’s the IDE support? Hello!?

Examples of both above ways can be seen on StackOverflow.

Simpler and cleaner way

By adding just a single line to the already generated init closure we have it done:
class BootStrap {

def init = { servletContext ->
servletContext.addListener(OurListenerClass)
}
}

Allrighty, this is enough to avoid XML. Sweets are served after the main course though :)

Listener as a Spring bean

Let us assume we have a requirement. Set a longer session timeout for premium user account.
Users are authenticated upon session creation through SSO.

To easy meet the requirements just instantiate the CustomTimeoutSessionListener as Spring bean at resources.groovy. We also going to need some source of the user custom session timeout. Let say a ConfigService.
beans = {    
customTimeoutSessionListener(CustomTimeoutSessionListener) {
configService = ref('configService')
}
}

With such approach BootStrap.groovy has to by slightly modified. To keep control on listener instantation, instead of passing listener class type, Spring bean is injected by Grails and the instance passed:
class BootStrap {

def customTimeoutSessionListener

def init = { servletContext ->
servletContext.addListener(customTimeoutSessionListener)
}
}

An example CustomTimeoutSessionListener implementation can look like:
import javax.servlet.http.HttpSessionEvent    
import javax.servlet.http.HttpSessionListener
import your.app.ConfigService

class CustomTimeoutSessionListener implements HttpSessionListener {

ConfigService configService

@Override
void sessionCreated(HttpSessionEvent httpSessionEvent) {
httpSessionEvent.session.maxInactiveInterval = configService.sessionTimeoutSeconds
}

@Override
void sessionDestroyed(HttpSessionEvent httpSessionEvent) { /* nothing to implement */ }
}
Having at hand all power of the Spring IoC this is surely a good place to load some persisted user’s account stuff into the session or to notify any other adequate bean about user presence.

Wait, what about the user context?

Honest answer is: that depends on your case. Yet here’s an example of getSessionTimeoutMinutes() implementation using Spring Security:
import org.springframework.security.core.context.SecurityContextHolder    

class ConfigService {

static final int 3H = 3 * 60 * 60
static final int QUARTER = 15 * 60

int getSessionTimeoutSeconds() {

String username = SecurityContextHolder.context?.authentication?.principal
def account = Account.findByUsername(username)

return account?.premium ? 3H : QUARTER
}
}
This example is simplified. Does not contain much of defensive programming. Just an assumption that principal is already set and is a String - unique username. Thanks to Grails convention our ConfigService is transactional so the Account domain class can use GORM dynamic finder.
OK, config fetching implementation details are out of scope here anyway. You can get, load, fetch, obtain from wherever you like to. Domain persistence, principal object, role config, external file and so on...

Any gotchas?

There is one. When running grails test command, servletContext comes as some mocked class instance without addListener method. Thus we going to have a MissingMethodException when running tests :(

Solution is typical:
def init = { servletContext ->
if (Environment.current != Environment.TEST) {
servletContext.addListener(customTimeoutSessionListener)
}
}
An unnecessary obstacle if you ask me. Should I submit a Jira issue about that?

TL;DR

Just implement a HttpSessionListener. Create a Spring bean of the listener. Inject it into BootStrap.groovy and call servletContext.addListener(injectedListener).