Wednesday, November 30, 2011

Denial won't help you learning

While preparing my talk (video) for the last Italian Agile Day conference, I spent some time retrospecting on my past projects. As people who attended know, this retrospective step ended up completely thwarting the original purpose of the speech: looking back in the past I discovered more than I expected.

To be completely honest, some of the inspiration for the talk came from Alistair Cockburn closing keynote at JAOO 2007 , I rarely invent anything. Connecting the dots is my job.

My key factors for successful learning

(OMG, I wrote this title like I know this stuff... and I actually don’t) While retrospecting on my past projects, I didn’t focus on normal success conditions. I focused on the amount of relevant knowledge learnt during the project. This allowed me to look at the past with a different perspective, seeing things that I probably overlooked in the past. From the perspective of learning, the key factors that most influenced the outcome were:

  1. Team attitude
  2. Motivation
  3. Context.

Team attitude is a tricky definition. Because it states 2 different things: that the attitude is relevant, and that I actually need a team. Of course I’ve learnt a lot also in projects where I was a lone consultant: I did some stuff, I solved some problems, I spent some time thinking about what I actually did. But the real massive amount of learning happened in projects where I had the chance to solve complex problems as a team.

Interestingly I couldn’t find any connection to the role I was playing at that time. Didn’t really made a difference if I was a junior developer or a project manager, or a senior architect. Didn’t really made a difference if I was supposed to be managed or managing (I hate this definition, but that used to be the past). Didn’t really made a difference if I was supposed to learn from the colleagues or to teach them something.

The one single thing that made a lot of difference was the attitude me and my colleagues shared in those difficult projects.

Learning attitude patterns

People made a lot of difference also in the business outcome of the project (yes, that boring on-time and on-budget part) but could give me from the very beginning a grasp about what I was going to expect. Let’s make some examples with somewhat stereotypical approaches.

“I know what I am talking about” that the kind of sentence often heard in organizations. To me, it means “I don’t feel any need to improve”. I’ve met some person like this, but luckily they were not in my team. Sometimes they were part of the organization we were supposed to work for, almost always they were part of the problem. I don’t want hem in my team. Plain and simple.

“That’s all clear to me” ... No. It isn’t. People that for some reasons pretend they’ve understood everything needed to solve the problem, are part of the problem as well. Quite often, under the surface they look for hints about what the boss said, and keep pretending that everything is fine. Walking timebombs.

“I have no clue about what we’re going to do” Now we’re talking! The most effective colleagues I’ve worked with always started the project with fear. They called me out for a one on one talk, and with fearful eyes told me “I know absolutely nothing about the topic of this project”, and - believe me - their faces were even better when I answered honestly “I have no idea about it either”. But that conversation was honest, we defined a common ground, and we started learning collaboratively assuming that we didn’t know all the things and that we needed to share information to solve a common problem.

Confront this profile with the previous two. Would you share information with those colleagues also? A lot less, ...they won’t need it anyway: they (pretended/assumed) that they already know the stuff. They basically shut themselves out from any possibility of collaborative learning. Ok, that’s basically Socrates statement: “The real wise man is the one that knows that he doesn’t know”. ...But not only.

Focusing efforts in the right direction

What’s striking me more and more, is that the attitude we had sometime towards learning new things as a team, was incredibly effective also because it was efficient. We din’t waste any time in pretending that we were better than we really were. We did have a massive amount of work to do, but we didn’t have any knowledge debt, and we didn’t spend a second studying things that people around me expect me to know but I don’t.

Don’t you smell something familiar here? It smells like your dirty little secret to me. Make me think about movies where one of the characters did something wrong in the past and lives in the fear of being blackmailed... Ignoring a key skill, it’s not as bad as committing a crime, but the mechanics in our mind are not that different. Our brain start working in “I can’t let them discover my secret" mode, which is a dangerous slope: it makes you feel like “I am not the person they expect”.

It doesn’t matter how bad is our secret, the mechanics are similar: shame and fear of humiliation (even if only at the coffee machine level) are powerful triggers, and would lead to the wrong behavior, and also to learn less in the long run. Because stress is preventing from effective learning, because one can’t enjoy collaborative learning, and because a lot of time won’t be dedicated to learning but just to cover-my-ass activities which are brain draining (how many brain cycles are you spending deleting compromising SMS from your phone or wondering if your girlfriend can actually see what you posted on that other girl's wall on Facebook?).

To be honest, in a software project, your fault (if we want to call it like that) is really little. Telling that you’ve actually never understood OOP, or that you’ve never actually shipped anything to production isn’t a fault, it’s just a honest starting point. Stating where you are exactly and honestly right now would save you and your team a lot of troubles in the future.

When is the moment of staffing the team for a new project. Now I know exactly what I want. I want people with the right learning attitude.

Only knowledge gap?

Not really. The more I look into the problem, the more I realize that the mechanics are the same whether it is knowledge or learning debt, technical debt or motivational debt. Failing to acknowledge where we really are only exacerbates the problem. But that’s a topic for a whole new post. I also didn’t say much about motivation and context... Stay tuned.

 

Monday, March 07, 2011

See the Forest and the trees with Kanban

I uploaded the slides of my presentation about Kanban that I gave at last UGI Alt.Net Conf in Milan.

Sunday, October 17, 2010

Tuesday, October 12, 2010

DDD Reference Links

Further references

Books

Domain Driven Design - Eric Evans (Addison Wesley)

The official starting point for Domain Driven Design, covering the topic form tactical to strategical.

Applying Domain-Driven Design and Patterns (Addison Wesley)

A more implementation related approach focusing on the mechanics of the implementation of tactical DDD with C# and .Net.

DDD Quickly

A free dowloadable smaller reference for Tactical DDD from InfoQ

http://www.infoq.com/minibooks/domain-driven-design-quickly

Domain Driven Design website

New official website for Domain Driven Design. Aggregator for further resources, informations, discussion and events

http://domaindrivendesign.org/

Domain Driven Design User Group

This is the place where the most interesting discussions are hosted

http://tech.groups.yahoo.com/group/domaindrivendesign/

Italian Domain Driven Design group

http://it.groups.yahoo.com/group/DDD-IT/

Eric Evans interviews and talks on InfoQ

http://www.infoq.com/interviews/domain-driven-design-eric-evans

http://www.infoq.com/presentations/model-to-work-evans

http://www.infoq.com/articles/eric-evans-ddd-matters-today

http://www.infoq.com/presentations/strategic-design-evans

http://www.infoq.com/presentations/ddd-dsl-evans

DDD sample Application

A working implementation of DDD principles in SpringMVC plus Hibernate, maintained by Swedish company Citerus.

http://dddsample.sourceforge.net/

CQRS & Event Sourcing

I needed a separate page for that:

http://ziobrando.blogspot.com/2010/10/cqrs-event-sourcing-reference-links.html

DDD, TDD & BDD

The three amigos: DDD, TDD & BDD Presentation by Gojko Adzic

http://skillsmatter.com/podcast/design-architecture/ddd-tdd-bdd

Gojko Adzic’s Blog: http://gojko.net/

Context mapping

Strategic Domain Driven Design with Context mapping (My article on InfoQ)

http://www.infoq.com/articles/ddd-contextmapping

Context Mapping in Action - Presentation by Alberto Brandolini

http://skillsmatter.com/podcast/design-architecture/context-mapping-in-action

Articles

About entities, aggregates and data duplication - Alberto Brandolini’s blog

http://ziobrando.blogspot.com/2010/06/about-entities-aggregates-and-data.html

Random Links

Kent Beck blog entry on why writing maintainable software matters.

http://www.threeriversinstitute.org/blog/?p=104

Some more related or interesting books

Patterns of Enterprise Application Architecture - Martin Fowler

Analysis Patterns - Martin Fowler

Growing Object Oriented Software, guided by tests - Steve Freeman & Nat Pryce

The Pragmatic Programmer - Dave Thomas and Andy Hunt

Clean Code - Robert C. Martin

Agile Software Development, Pattern Principles and Patterns

 

Lean Software Development - Mary and Tom Poppendieck

Test Driven Development by Example - Kent Beck

Collaboration Explained - Jean Tabaka


CQRS & Event Sourcing Reference Links

CQRS & Event Sourcing

DDD/CQRS Mailing list

The official CQRS Website

Interviews

Eric’s interview to Greg Younghttp://www.infoq.com/interviews/Architecture-Eric-Evans-Interviews-Greg-Young

Clarified CQRS - Article by Udi Dahan

Presentations

Command Query Responsibility Segregation - Presentation by Udi Dahan
http://www.infoq.com/presentations/Command-Query-Responsibility-SegregationAvoid a failed SOA - Presentation by Udi Dahan

http://www.infoq.com/presentations/SOA-Business-Autonomous-Components

Event Sourcing

Event Sourcing definition by Martin Fowler

http://martinfowler.com/eaaDev/EventSourcing.html

Innovation and Event Sourcing - Greg Young presentation

http://skillsmatter.com/podcast/design-architecture/architectural-innovation-eventing-event-sourcing

Code References

Super Simple CQRS Example

http://codebetter.com/blogs/gregyoung/archive/2010/08/31/super-simple-cqrs-example.aspx

Wednesday, June 16, 2010

Agile Testing UK meetup

While in England for DDD Exchange, I caught the opportunity to participate in a meetup of the UK Agile Testing community. Gojko Adzic led a very interesting workshop about how to write acceptance tests.

Neil McLaughlin, who happened to be in my team in the hands-on simulation wrote a nice report on the evening, and then Gojko himself posted about what he showed us. I'll try add something, from the participant perspective.

The developer mindset

Given we had quite a few people in the room, around 60, it was really interesting to note all different behaviors, but there were also some striking similarities. Most of the discussion we had were focused on

  • Formal correctness of the test
  • Splitting tests to be testing one concern at that time
  • avoiding duplication in test fixture setup

When discussing the outcome, Gojko pointed out that the main concern for acceptance tests was readability, instead. Readability is a subjective evaluation criteria, and might lead to a not-so-precise definition about how to make it right. But that's the only way to write a useful acceptance test. But the developer's mindset really had a strong influence on us, it was really hard to give up.

Constrained by the tools

Despite Skills Matter (that was hosting the evening) doing a fantastic job in providing an impressive amount of whiteboards for all the team, some of the discussions were constrained by the amount of space available on the whiteboard, so we ended up pruning some concerns, thinking they were of little value to the discussion. It turned out we were wrong.

But, as I said, we had an amount of writable space that was a lot larger than what I normally found in a typical workplace... and still this was constraining us. Buying one more whiteboard is cheap, making wrong assumptions because of writable space constraints is a lot more costly.

We're problem solvers, after all

During the exercise, Gojko was wandering around from one team to another one, playing the role of the Domain Expert. However, most of the teams seemed more interested in his Teacher role and asked some questions about how to solve the exercise, but barely none about ambiguities in the domain. We preferred to use assumptions instead.

Even if I knew the trick, it worked on me as well. But it's scary to note that even when writing acceptance tests, which are a lot more translation than design, our built-in problem solving brain leads us so easily on the road of guessing instead of asking.

Tuesday, June 15, 2010

About Entities, Aggregates and Data Duplication.

There's been an interesting discussion about Aggregates on the Italian DDD mailing lists. When things become complex, a simple example might just turn too simple. So I came up with this medium-sized one. Hope it won't be too long. Ok, so let's start from our first User Story

User Story #1: Placing an order
As a Customer
I Want to place an order
In order to purchase some goods

The simplest implementation of the story is essentially stateless: every time a customer wants to order something, needs to re-enter the data. In the DDD perspective, the resulting model is based on a single aggregate (we're deliberately ignoring the catalog for now) whose root is the Order class.

DDD order story 1.1.jpg


The stateless nature of the service makes it really easy to implement: a Customer is just a Value Object, created and eventually dropped at needs. Also we took some shortcut: we've chosen to implement Address as a String. Item is sort of natural value object, while LineItem is somewhat in the middle: we can change quantities, while the order is in open state, but we can implement this also using droppable Value Objects, easing the integrity burden for the aggregate root.

Some businesses (like buying train tickets) might just work like this, but our marketing is more inclined to manage customers in a more long-term way, so here are two more user stories.

User Story #2: Returning customer
As a Customer
I Want to retrieve my profile
In order to place more orders

Story #2 breaks our assumption about the aggregate boundaries. If we stick to the aggregate rule-of-thumb, if we want to delete an Order, we probably don't want to delete also the corresponding Customer. So we need a separate aggregate for that. What would happen if we decide to delete a Customer? Should we delete all orders? We don't have enough information to answer that, yet, we'll mark it as an outstanding question for our next meeting with the domain expert. Let's try the model with two aggregates and see how does it perform.





We now have a relationship crossing the aggregate boundary. We have promoted Customer to become the root of the newly created aggregate, so there is no potential integrity violation. Still we have to watch it closely, because this is where problems related to lazy/eager loading will arise. We also added username and password to Customer.

User Story #3: Different shipping address
As a Customer
I Want to specify a valid shipping address
In order to ship to a different destination

Multiple addresses are a call for a separate type to manage Address. We don't have so many responsibilities so far, for this class, except validation (which as Udi Dahan would say, doesn't necessarily belong to the domain layer) but the smell of duplication is probably enough to go for a separate class. We try to keep the model as simple as possible, so we treat Address like a value object.

DDD order story 3.jpg

User Story #4: Editable customer profile
As a Customer
I Want to edit my profile
In order to update it if needed

Story #4 makes explicit what we've been suspecting: Customer needs to be an entity, because it has a nontrivial lifecycle. No revolutions at Domain Model level, but this triggers a question: "What happens if I have an outstanding order and the customer changes its data before the order is dispatched?" This is the type of questions you don't want to answer as software developer. So we walk up the stairs to have a talk with the Domain Expert. We come back with two fresh user stories:

User Story #5: Specify Billing and Shipping address
As a Customer
I Want to specify independent billing and shipping addresses
In order to deliver goods to different locations

This one is relatively easy: just reinforcing our design. We'll now have two references from Order to Address, which are managed by the Customer. We just store a default Address in the Customer aggregate (we could do better) but's ok for now.

DDD order story 5.jpg

Story #6 is a little trickier, it comes from the legal department and tell us what we probably expected.

User Story #6: Track past orders
As a Legal Department
I Want to track orders
In order to in order to manage litigations

The domain expert state it clear: once an order is placed, it can't be changed in any of its parts, be it the content or the Customer. In case of litigation, it must behave exactly like printed paper. But Customer does not, its lifecycle is different from our needs, we'd need a separate class for that. We're lacking fantasy and call it CustomerData.

DDD order story 6.jpg


Everything is looking a lot different from the beginning. The two aggregates are now largely decoupled: we can change or delete an order without affecting the customer or deleting or unregistering a customer without losing tracks of its past orders. On the other hand we have explicit duplication here. Customer and CustomerData look so similar we're feeling guilty. Did we violate DRY principle? At first look the data is the same, but if we think about behavior, or class lifecycle, Customer and CustomerData are clearly two different beasts. But more often than not, when the starting point is the data model, instead of the domain model we end up thinking that's the same data, hence the same class. I bet experienced data modelers do not fall into these pitfalls as well, but I've seen these problems recurring quite often.

Once we accept that little bit of data duplication we have a system which is a lot easier to evolve and maintain, with aggregate roots as integrity enforcers within their boundaries, and agnostic about the rest.

To add some salt, don't forget aggregates are also building blocks of distributed systems: suppose we'll need to send orders to a remote system. Sending just the single aggregate and the referenced value objects is probably the cleanest way.