有一个敏捷推行人,给她的团队设立了一个规则:每个函数不要超过30行。一开始,领导们都说,很好,很有道理。可是真的做起来,就发现遗留代码里有这样那样的特殊情况。紧跟着,开发人员也有了抱怨:我这里写32行又有什么损害呢?为什么一定要那么死板呢?于是,一个又一个的口子被打开。当然,你可以想象,有了越来越多的口子以后,“改善代码质量”也就成了纯理念──跟没有规则之前没什么区别。
我打算怎么做这件事呢?
先讲道理,再定规则,然后帮所有人提升能力以遵守规则,随着能力的提升逐渐拉高规则。30行的规则落实不下去?我就不信了。
把持续集成作为团队规则的自动、可视执行者,于是敏捷推行人就不必扮演那个凶恶的执法者,只需专心帮人排疑解难。持续集成把违规行为变成一个人与整个团队的对立,而不是一个人与另一个人的对立。
Nowadays, I tend to use a typed link leading to a form, rather than a heavily typed link alone (I’ll explain what I mean by heavily typed link shortly), to advertise unsafe operations and/or requests that require an entity body. Here’s an example of a typed link:
//Request
GET /shop HTTP/1.1
Host: restbucks.com
Accept: application/vnd.restbucks+xml
//Response
HTTP/1.1 200 OK
Date: Mon, 26 Jul 2010 10:00:00 GMT
Cache-Control: public, max-age=86400
Content-Type: application/vnd.restbucks+xml
Content-Length: ...
<shop xmlns="http://schemas.restbucks.com/shop">
<link rel="http://relations.restbucks.com/rfq"
href="http://restbucks.com/request-for-quote"
type="application/vnd.restbucks+xml"/>
</shop>
The link here is typed with the link relation value http://relations.restbucks.com/rfq, which indicates that the link points to a resource where a request for a quote can be submitted. Following the link, the client retrieves a form:
//Request
GET /request-for-quote HTTP/1.1
Host: restbucks.com
Accept: application/vnd.restbucks+xml
//Response
HTTP/1.1 200 OK
Date: Mon, 26 Jul 2010 10:00:05 GMT
Cache-Control: public, max-age=86400
Content-Type: application/vnd.restbucks+xml
Content-Length: ...
<model xmlns="http://www.w3.org/2002/xforms"
schema="http://schemas.restbucks.com/rfq.xsd">
<submission
resource="http://restbucks.com/quotes"
method="post"
mediatype="application/vnd.restbucks+xml"/>
</model>
The response entity body comprises an XForms form model. (Our custom media type definition for application/vnd.restbucks+xml says that one of the things a client can expect to receive in a response is an XForms form model.) The form’s <submission> element includes several pieces of control data: it indicates which verb to use when submitting the form (POST), where to submit the form (http://restbucks.com/quotes), and which content or media type to use when submitting the form (application/vnd.restbucks+xml). Because the definition of our custom media type includes more than one XML schema (much as the Atom specification defines two schemas, one for feeds and one for entries), the form’s control data needs to further clarify what /quotes expects to receive in a POST request. To clarify which schema the POST request body should adhere to, the <model> element’s schema attribute references the rfq.xsd schema.
Here, then, we have all the information a client needs to construct and submit a valid request to the /quotes resource. And all without any fields for the client to fill out.
A heavily typed link is one where the link relation describes not only the relationship to the linked resource, but also the HTTP idioms – the control data – necessary to manipulate that resource.
Using a heavily typed link our shop could link directly to the /quotes resource, instead of to a form:
<shop xmlns="http://schemas.restbucks.com/shop">
<link rel="http://relations.restbucks.com/quotes"
href="http://restbucks.com/quotes"
type="application/vnd.restbucks+xml"/>
</shop>
Here, the definition of the link relation http://relations.restbucks.com/quotes might be something like: “Indicates a collection of quotes. To request a quote, POST a <request-for-quote> with a Content-Type header of application/vnd.restbucks+xml to the linked resource.”
That’s a perfectly respectable way of using links and link relations; in fact, it’s the strategy we employ in REST in Practice. But it can have its downsides. Most importantly, it can increase the coupling between the client and any resources that employ link relations.
Make no mistake: link relation semantics comprise out-of-band knowledge. There’s no magic here: link relations introduce a degree of coupling between a client and any server-governed resources that adopt them. The trick is to keep this coupling as low as possible. By putting control data in the link relation definition, we perhaps introduce more coupling than is strictly necessary.
Out-of-band data is less visible, and more difficult and more costly to change, than data that is inlined in the message. Whilst the control data may not change all that often, changes can and do sometimes happen; inlining the data allows these changes to be propagated to clients sooner rather than later. Control data produced at the time the response is generated is generally more recent than control data defined through some out-of-band mechanism.
Using lightly typed links helps separate semantics from control data. A “light” link relation indicates what the linked resource means in the context of the current representation – that’s all. This helps mitigate against a second, somewhat more subtle, downside of adding control data to link relations: the tendency to introduce action semantics. It’s no great step to shorten the link relation value above to http://relations.restbucks.com/quote, and to rewrite its semantic to read “Indicates an opportunity to request a quote by POSTing a <request-for-quote> with a Content-Type header of application/vnd.restbucks+xml to the linked resource.” At this point, our link has effectively become an operation. The typed-link-to-form strategy helps us concentrate on describing what a linked resource is, rather than what a link does. Link relations do not necessarily imply action semantics, but they can very easily be made to do so.
(Note: when adding links to representations, I still prefer to use a <link rel="..." href="..."> construct, or something similar, rather than <order-form href="...">. The reason for this is that elements such as <link> separate link syntax from semantic context, as explained here; and this is a good thing, because what a link ought look like – its syntax – changes far less than what a link might mean in a particular context. By separating these concerns, we make it easier to evolve a distributed application.)
Interestingly, on the wire, the result of submitting an XForm form looks exactly the same as if we’d simply POSTed a <request-for-quote> directly to /quotes:
//Request
POST /quotes HTTP/1.1
Host: restbucks.com
Content-Type: application/vnd.restbucks+xml
Content-Length: ...
<request-for-quote xmlns="http://schemas.restbucks.com/rfq">
<items>
<item>
<description>Costa Rica Tarrazu</description>
<amount>250g</amount>
</item>
<item>
<description>Guatemala Elephant Beans</description>
<amount>250g</amount>
</item>
</items>
</request-for-quote>
Knowing this, we could always add both a lightly typed link to a form and a heavily typed link to our shop representation:
<shop xmlns="http://schemas.restbucks.com/shop">
<link rel="http://relations.restbucks.com/rfq"
href="http://restbucks.com/request-for-quote"
type="application/vnd.restbucks+xml"/>
<link rel="http://relations.restbucks.com/quotes"
href="http://restbucks.com/quotes"
type="application/vnd.restbucks+xml"/>
</shop>
Two paths to the same result. I don’t recommend doing this: I include simply to highlight how a linked form achieves the exact same result, but with the added beenfit of having inlined control data.
Here’s another example of using a typed link to a form:
//Request
GET /quotes/1234
Host: restbucks.com
Accept: application/vnd.restbucks+xml
//Response
HTTP/1.1 200 OK
Cache-Control: public
Date: Mon, 26 Jul 2010 10:01:00 GMT
Expires: Mon, 02 Aug 2010 10:01:00 GMT
Content-Type: application/vnd.restbucks+xml
Content-Length: ...
<quote xmlns="http://schemas.restbucks.com/quote">
<items>
<item>
<description>Costa Rica Tarrazu</description>
<amount>250g</amount>
<price currency="GBP">4.40</price>
</item>
<item>
<description>Guatemala Elephant Beans</description>
<amount>250g</amount>
<price currency="GBP">5.30</price>
</item>
</items>
<link rel="http://relations.restbucks.com/order-form"
href="http://restbucks.com/order-forms/1234"
type="application/vnd.restbucks+xml"/>
</quote>
The link relation http://relations.restbucks.com/order-form indicates that the linked resource is something that allows an order to be submitted. Following this link, the client retrieves an order form:
//Request
GET /order-forms/1234
Host: restbucks.com
Accept: application/vnd.restbucks+xml
//Response
HTTP/1.1 200 OK
Cache-Control: public
Date: Mon, 26 Jul 2010 10:01:05 GMT
Expires: Mon, 02 Aug 2010 10:01:00 GMT
Content-Type: application/vnd.restbucks+xml
Content-Length: ...
Content-Location: http://restbucks.com/quotes/1234
<model xmlns="http://www.w3.org/2002/xforms">
<instance>
<quote xmlns="http://schemas.restbucks.com/quote">
<items>
<item>
<description>Costa Rica Tarrazu</description>
<amount>250g</amount>
<price currency="GBP">4.40</price>
</item>
<item>
<description>Guatemala Elephant Beans</description>
<amount>250g</amount>
<price currency="GBP">5.30</price>
</item>
</items>
<link rel="self"
href="http://restbucks.com/quotes/1234"
type="application/vnd.restbucks+xml"/>
</quote>
</instance>
<submission
resource="http://restbucks.com/orders"
method="post"
mediatype="application/vnd.restbucks+xml"/>
</model>
Once again, I’ve used an XForms form model, but this time I’ve pre-filled it with an <instance> element. Even so, there are no form fields to fill in; all the client needs to do is operate the form according to the inlined control data.
The interesting thing here is that /order-forms/1234 simply returns a different representation of the quote resource identified by /quotes/1234 (the response indicates as much in its Content-Location header). By supplying a forms-based representation of the quote, we inline all the information necessary to submit an order to an order processing engine. The client doesn’t need to compose an entity body; it simply needs to operate the form according to its control data. This results in a self-describing message being sent to /orders.
(In a real-world application I’d likely include a signature in the form body. This signature would guarantee that the client hasn’t tampered with the form contents prior to submitting the form to the order processing engine. The effectiveness of the signature depends on an out-of-band trust relationship having been established between the quoting engine and the order processing engine.)
The result of first following the link to the form, and then submitting the form, is to transition the overall state of the distributed application from Quote Requested to Order Placed, as illustrated in the following diagram:

Every request-response pair transforms application state. Retrieving the form enriches the client’s understanding of the current application state; that is, it opens up new opportunities for interacting with other resources. POSTing the form causes the application state to transition from Quote Requested to Order Placed.
The fact that the overall state of the application has changed is of no consequence to the server resources involved; the application state model is nowhere baked into the server resources. As far as the quote resource is concerned, it has simply been asked to surface a forms-based representation of itself. As far as the orders resource is concerned, it has simply created a new, subordinate order resource. This change in application state is, however, important to the client.
Understand the tradeoffs between inlining and putting control data in an out-of-band mechanism. Use the right controls for the job; understand the many different hypermedia capabilities at your disposal. The best resource for this is Mike Amundsen’s in-depth study of the hypermedia capabilities of many different kinds of hypermedia control. Recently, Andrew Wahbe started examining the need for machine-to-machine hypermedia, and the differences between controls for machines and controls for humans. Watch his blog for further discussion.
My understanding of hypermedia controls has been heavily influenced by my experience of the human web, where links and forms predominate. But when we talk about forms in a machine-to-machine context, it’s not the form field elements that are of interest, it’s the control data elements. These control data elements help program the client on the fly. The term “form” as it applies in a machine-to-machine context is likely an inappropriate metaphor; nonetheless, it does emphasize the fact that unsafe requests – and requests that have an entity body – require different hypermedia capabilities from simple GETs.
Because in the past I’ve tended to think form fields are redundant in machine-to-machine scenarios, I’ve avoided using forms at all, and have instead overloaded link relations with control data. But link relations are not a “get out of jail free” card. In overloading link relations, we add unnecessary coupling.
Coupling, of course, is not an all-or-nothing affair. There are degrees of coupling. We choose to accept some coupling because of the benefits it brings. But that doesn’t mean we should accept more coupling than is necessary; doing so can only inhibit our ability to evolve a distributed application.
As vezes vejo pessoas falando em empreender, nos riscos, e tudo mais… e pergunto! O que impede você de tentar aplicar algumas horas do seu dia em alguma ideia que você entende que pode dar certo?
Li recentemente o livro Rework da 37Signals, empresa de sucesso no desenvolvimento de softwares que não fazem uma série de coisas. E o fato destes softwares não serem capazes de uma série de coisas é que faz esta empresa tão diferente e com tanto sucesso no mercado.
Eles tem foco, eles tem objetivo e eles tem a certeza de que o produto que eles fazem possui um nicho de usuários. E eles trabalham este nicho.
Você já escolheu o nicho que deseja trabalhar?
Para quem é do mercado de TI, você precisa de no máximo R$50 reais para investir em uma primeira idéia. Isto se você quiser investir em um domínio. De resto, você encontra soluções gratuitas e/ou open source, e nas nuvens para ajudar você em tudo o que precisar!
Precisa de um CRM para cuidar do seu negócio? Highrise!
Precisa de um software para gerenciar seu projeto e acompanhar seus planos? Basecamp ou PivotalTracker podem te ajudar!
Precisa publicar sua aplicação? Google App Engine! Heroku!
E você precisa contratar? Para que? Você já tentou fazer sozinho? E você tem pessoas com a mesma identidade que você? Você tem uma empresa que ouve suas ideias e permite que você crie produtos internamente? Pense nisto também.
Eu sempre falo aos meus alunos: nunca deixem de programar. Nunca deixem de treinar. Um diretor que tive me falou, as empresas precisam de poucas pessoas nas suas diretorias, mas as empresas sempre vão precisar de bons programadores, no melhor estilo pragmatic programmers, desenvolvedores atentos no que é importante no desenvolvimento de software. Falo mais sobre “o que é importante” em outro post.
E é no sentimento de “do it yourself” (DIY) que eu acho que as pessoas precisam investir seu tempo. E pensando no início de uma idéia, meu entendimento fecha com o modelo do Getting Real, ou quase… eu entendo que podemos usar um time de até três pessoas para lançar um produto novo. Você não precisa de mais pessoas que isto para fazer as coisas acontecerem. E olhando 37Signals que citei anteriormente, é o modelo dos três mosqueteiros.
E não é procurando soluções mirabolantes, mas procurando as soluções mais simples possíveis (que por acaso são as mais difíceis). Exemplo, converso com colegas de trabalho sobre alguns produtos a serem lançados, mas nenhum produto pode ter mais que 08 horas de desenvolvimento. Como você alcança isto?
A criação de restrições são interessantes para alcançar estas questões. E são 08 horas conscientes de desenvolvimento, nada de eXtreme Go Horse ou algo do tipo.
Com foco, uma bela metáfora, e muita simplicidade! Simplicidade é a arte de maximizar o trabalho que não fazemos. E é isto que precisamos trabalhar em nós mesmos e com os nossos times. O que eu posso fazer, que é muito simples, e pode me ajudar a colocar a cara no mundo e mostrar minha idéia?
O quanto de tempo preciso investir para garantir um produto possível de ser colocado em produção?
Vou precisar virar noites? Não. Tempo é vida. Cuide dela.
Durma bem. Use 1 hora do seu dia para investir no seu projeto. Use técnicas para gerenciar seu tempo e dar o foco necessário, para que o mínimo de tempo que você tenha seja útil para alguma coisa no seu projeto. Faça coisas mais simples.
Capital de investimento? Será que você precisa? Crie uma restrição! Quem sabe isto ajuda você a lançar uma solução mais rápida?
Trabalhe o mínimo para entregar o máximo. Outra questão interessante é de repente você ler este texto e pensar: mas eu quero criar uma empresa de treinamento. Não posso gastar apenas 1 hora por dia.
Pode sim.
Você pode criar vídeo aulas, iniciar vendendo elas para sites que compram este material. Ou fazer vocês mesmo sua forma de distribuição! Pode virar um parceiro no itunes e vender seus vídeos pela loja da apple. Você pode. Pode usar uma plataforma como e-genial / treinatom. Pode.
Você não precisa de uma sala e um lugar físico para dar treinamento. Não hoje, não agora.
Você pode tentar e atingir um mercado muito maior do que você poderia atingir.
Pense nisto.
It is amazing, you can talk to someone, use words that make perfect sense to both parties and still, they don’t communicate at all. I had this experience last week. The Scrum Teams I have been coaching for some time now were scheduled for a meeting with a manager. It was about certain company standards in the area of reporting. The different Scrum Teams were doing the same thing in slightly different ways, no big differences but enough to be visible. Those differences had a good reason: Different preferences how each team wanted to work. Since the teams are self organizing, there is nothing wrong with this approach and either solution makes perfect sense in their given context.
However, in that meeting the POs and SMs of the two teams were told that having different reports was not acceptable – that they could be confusing; which they weren’t because we had already moved people around – and that the company would mandate a specific tool enabling anyone to work anywhere without having to get any introduction. This might work if all the teams would do the same kind of work, however, in this setting the different teams do a different kind of work using different technologies.
I knew that that specific meeting was scheduled to address that very topic. So, on purpose I did not mention this beforehand to neither of the SMs and POs. I was curious to see how they would react and how they would argue. I wanted to see if I was doing a good job as a coach. It was a textbook show. They simply said: ‘No way! We have delivered working software on time since we started with Scrum, this is how we agreed to work in our Scrum Team and it works great for us. We had people moved around and nobody was confused. Last, there are more pressing issues than how certain reports should look like!’. Of course, the manager was not pleased. He argued that this had to be done in order to align the whole company and lay a foundation for future improvements. The Scrum Teams replied by explaining some principles and practices of Scrum. They also described how it makes sense to keep on working the same way and that they would be open for some changes when both teams would see the need for it – however, right now they do not welcome it.
This went on for the best part of the hour. Sadly at the end we were told that we would have to obey with whatever decision the management would come up with. Our reasoning was not understood – we had failed.
What had happened? Each party was perfectly able to follow and understand each word of the discussion. However, the management side did not extract the same kind of information. We had a semantics disaccord. They understood each single word but did not get the meaning of what we were trying to communicate.
I’ve come to the conclusion that this could be explained with the Dreyfus model of skill acquisition.
The Scrum Teams each had about 6 months of hands-on Scrum experience and discovered first hand what it really means to walk the agile walk. They learned a lot about agile and enhanced their theoretical knowledge with hands-on practical experience. Their limited explicit Scrum knowledge became tacit and abundant. Tacit knowledge is knowledge that is difficult to transfer to another person by means of writing it down or verbalising it. It was exactly this tacit knowledge that was missing on the managers’ side to really understand what we were trying to explain. Same words, total different meaning.
The Scrum Teams have moved up the Dreyfus model and are around the competent or even proficient level, whereas the management is still novice, advanced beginner at best. We had an interfacing problem and did not communicate on the same skill level. The risk with that is that you think you understand, but don't understand without realizing it.
I am convinced that this is one of the main challenges when communicating certain topics. You cannot assume that everyone has the same tacit knowledge and thereby the same skill level then you. You need to find a way to describe matters to a novice as tangible as possible. Not an easy feat but a necessity.
Consider the Dreyfus Model whenever you head to a meeting where you have to do a lot of explaining. If you are too far apart on the Dreyfus model, the others won’t be able to understand even if they think they do!!!

We're happy to announce the third edition of DevCamp Bangalore - DevCamp Bangalore 3 ( http://devcamp.in/index.php/Bangalore ) on Saturday, September 4th, 2010.
The event will be sponsored & hosted by ThoughtWorks ( www.thoughtworks.com ) at their office in Diamond District, Bangalore. ( View map )
Registration
Like any BarCamp, registration is on the wiki and there is no registration fee.
DevCamp is an un-conference by the hackers, for the hackers and of the hackers. It's a species of BarCamp where anything a lover of computers and technology would consider important or entertaining goes. The first DevCamp took place a little over two years ago, and we've always had a lot of fun being a part of this event; we're hoping to keep that trend going with DCB3.
What's in store?
DCB3 is going to be packed with informative presentations, Fishbowl sessions, lightning talks, and much more, so don't miss it!
Interested in doing a session?
Please keep in mind the fact that everyone at DevCamp is a hacker, a pro. Assume a high level of exposure and knowledge on the part of your audience, and tailor your sessions accordingly. Avoid 'Hello World' and how-to sessions which can be easily found on the net. First hand war stories, in-depth analyses of topics, and live demos are best.
Add your abstract/presentation topic here
shenheng对《系统复杂之路》评论道:
连自己也维护不了的代码,难道可以靠神一般的咨询师?玩笑开大了吧,咨询师的到来,与葬礼上的神父无异!
咨询师会带来天翻地覆的变化,这样的期许本身就是不现实的。
其实,我也不喜欢咨询师。
做咨询之前,我一直想不通,有什么问题自己搞不定,非要请咨询师。founder_chen说,如果大家都像你一样,咨询就没活干了。
可惜,世界上还有很多咨询师,后来,我也成了一个。
做咨询一段时间,我常困惑于我到底可以给客户带来什么。
于今,我释然了。我只不过关注着一些那些人不曾关注过的东西,比如软件设计,比如Clean Code,比如重构,比如TDD,比如如何做程序员,比如如何做事。而在客户那里,我所做的,只是把这些东西以他们习惯的方式展现给他们。
我只是打开一扇门。
做了个培训,结尾,有人问,怎样才能保证设计的一些东西在后续的开发过程中不被破坏。
好问题,保证不了。
真正保证设计不被破坏的是团队,而不是软件设计本身。团队里需要有人知道代码应该写成什么样子,需要有人清楚系统架构是什么样子,需要有人有正义感,在有人无心伤害时,敢于出来喊一嗓子。
在原有的环境下,这样的人对于其他的工作方式知之甚少。不是他们不努力,很多时候,他们只是不知道自己不知道。我所能带给他们的就是,让他们知道另一片风景的存在。
Entry by Adam Monago
Software teams, in the broader sense, are complex adaptive systems. They live within organizations populated by many actors, influenced by the methods, practices and behaviors that coexist with them. Most of all, they have the capability to learn and adapt to each new entrant into their world. It is for this reason that, we tend to avoid recommending ‘best practices’ that all software teams can follow for success, let alone ‘agility’.
At ThoughtWorks Studios, we have defined our ideal state as being one of continuous delivery: one in which the customers and users of software have maximum ownership and influence of the development process.
Read the full article at Tech Journal South (http://www.techjournalsouth.com/2010/09/best-practices-for-adaptive-software-teams/)
I know that lots of organizations are still using old-expensive-counterproductive configuration management systems (ClearCase, VSS, etc.). I understand the fear that prevents many of them from moving to a decent SCM (Subversion, Mercurial , etc.). I’ll try to tell a story about that kind of migration, which might alleviate the fear.
A huge company, with 40,000+ software developers, with 10+ years history using ClearCase, wants to migrate to Subversion, because of SVN’s encouragement to atomic commit and optimistic locking. The movement is still ongoing. Every single pace involves at least one delivery team, normally with 100+ programmers in it.
The movement must be as seamless as possible, because people are pushed to meet their next milestone. For a codebase sized over 4GB, we made the migration in a week:
That’s it. Now your team is on SVN.

On August, 21st of 2010, at RS on Rails 2010, I and Robson Mendonça gave a talk about a game development framework for Ruby called Chingu. Our main goal with this talk was to show that you can have fun with pure Ruby without riding Rails. I believe we successfully achieved that!
For those who might have interest, below are our slides (Portuguese only). Our game’s source code you can find at zukunftsalick’s github.
Ah, one more thing: On September, 12th, I and Carlos Villela will be giving a talk at qCon São Paulo. We’ll be presenting “Especificações de Fora pra Dentro Usando BDD e Selenium 2” roughly translated to “Specifications from outside-in using BDD and Selenium 2″. See you guys there!
Rs on Rails 2010View more presentations from Pedro Pimentel.Probably Related posts:
I've been playing around with Objective C over the last month or so and although my knowledge of the language is still very much limited I thought it'd be interesting to describe some of the things about the language that I think are quite interesting and others that keep catching me out.
I touched on protocols a bit in my first post but they seem like an interesting middle ground between interfaces and duck typing.
I like the fact that protocols can define optional methods so that if we're not interested in some parts of the protocol we can just ignore those parts.
From the documentation page:
Protocols free method declarations from dependency on the class hierarchy, so they can be used in ways that classes and categories cannot. Protocols list methods that are (or may be) implemented somewhere, but the identity of the class that implements them is not of interest. What is of interest is whether or not a particular class conforms to the protocol
We played with Smalltalk in a coding dojo a bit last year and the first thing that I noticed with Objective C is that the method names are very similar to those in Smalltalk.
I think this influences the way that we define the method name and its parameters as you try and define those in such a way that when you call the method it will read better.
For example I created the following method:
UILabel *aLabel = [self createLabelFrom:project withXCoordinate:x withYCoordinate:y];
If I didn't have to name the parameters when calling the method I doubt I would have used such descriptive names. I would have just used 'x' and 'y' as the names!
As I understand it all the methods defined on an object are available to any other object to call i.e. all the methods are public
I've read about others using categories to simulate the idea of having non public methods but I haven't tried anything myself yet.
Interestingly we get a compiler warning when trying to call methods on an object if those methods haven't been defined in the appropriate header file although the code still seems to execute fine at run time.
One other thing that I sometimes forget is that we're dealing with messages rather than method calls.
We still need to send the message to 'self' even if it's a message being sent to another method on the same object.
Writing in the FT's Long View column, James Mackintosh makes the point that hedge fund managers “appeared smarter than they really were, because they were taking a risk they did not recognize.” That’s an apt description for a lot of what goes on in IT, too.
Despite all of the risks that commonly befall an IT project, we still deal with IT planning as an exercise in deterministic forecasting: if these people do these things in this sequence we will produce this software by this date. The plan is treated as a certainty. It then becomes something to be optimized through execution. As a result, management concerns itself with cost minimization and efficiency of expenditure.
Trouble is, an operations plan isn't a certainty. It's a guess. As Nassim Taleb observed in Errors, Robustness and the Fourth Quadrant:
Forecasting is a serious professional and scientific endeavor with a certain purpose, namely to provide predictions to be used in formulating decisions, and taking actions. The forecast translates into a decision, and, accordingly, the uncertainty attached to the forecast, i.e., the error, needs to be endogenous to the decision itself. This holds particularly true of risk decisions. In other words, the use of the forecast needs to be determined – or modified – based on the estimated accuracy of the forecast. This, in turn creates an interdependency about what we should or should not forecast – as some forecasts can be harmful to decision makers.In an IT project context, the key phrase is: “This holds particularly true of risk decisions.” We take thousands of decisions over the course of an IT project. Each is a risk decision. Yet more often than not, we fail to recognize the uncertainty present in each decision we make.
This comes back to the notion that operations plans are deterministic. One of the more trite management phrases is “plan your work and work your plan.” No matter how diligently we plan our work in IT, we are constantly under siege while “working our plan”. Developers come and go. Business people come and go. Business needs change. The technology doesn’t work out as planned. The people responsible for the interfaces don’t understand them nearly as well as they believe they do. Other business priorities take people away from the project. Yet we still bake in assumptions about these and many other factors into point projections – as opposed to probabilistic projections – of what we will do, when we will be done and how much it will cost.
Our risk management practices should shed light on this. But risk management in IT is typically limited to maintaining a “risks and issues” log, so it’s never more than an adjunct to our plan.
That most IT projects have only rudimentary risk management is quite surprising given the one-way nature of risks in IT. One-way risks are situations where we have massive exposure in one direction, but only limited exposure in another. Taleb gives the example of trans-Atlantic flight times. It’s possible for an 8 hour flight to arrive 1 or possibly 2 hours early. It can’t arrive 6 hours early. However, it can arrive 6 hours, or 8 hours, a day or even several days late. Clearly, the risks to flight duration are substantially in one direction. IT risks are much the same: we may aggressively manage scope or find some efficiency, but by and large these and many other factors will conspire to delay our projects.
The fact that risk in IT is substantially one-way brings a lot of our management and governance into serious doubt. Having a project plan distinct from the risk log makes the hubristic assumption that we will deliver at time and cost, so we must pay attention to the things that threaten the effort. Given that our risk is substantially one-way, we should make a more humble assumption: odds are that delivery will occur above our forecast time and cost, so what do we need to make sure goes right so that we don't? While such a pessimistic perspective may be in direct contrast to the cheerleading and bravado that all too often pass for "management", it makes risk the core activity of management decision making, not a peripheral activity dealt with as an exception.
In Convexity, Robustness and Model Error in the Fourth Quadrant, Taleb makes the point that one-way risk is best dealt with by robustness – for example, that we build redundancies into how we work. Efficiency, by comparison, makes us more vulnerable to one-way risk by introducing greater fragility into our processes. By way of example, think of the "factory floor" approach to IT, where armies of people are staffed in specialist roles. What happens to the IT "assembly line" when one or more role specialists exit, depriving the line of their situational knowledge? Without redundancy in capability, the entire line is put at risk.
Common sense and statistical analysis both conclude that an optimized system is sensitive to the tiniest of variations. This means that when risks are predominantly one-way – such as in IT projects – it behooves us to err on the side of robustness.
That risk in IT is substantially one-way brings a lot of our management and governance into serious doubt. Having a project plan distinct from the risk log makes the hubristic assumption that we will deliver at time and cost, so we must pay attention to this list of things that could go wrong. Given the one-way risk - and the uncertainty of what those risks are - we should make a more humble assumption: delivery will occur well above our forecast time and cost, so what do we need to make sure goes right? While such a pessimistic outlook may be in direct contrast to the cheerleading and bravado that pass for "management", it makes risk the core activity of management decision making, not a peripheral activity dealt with as an exception.
Robustness is the antithesis of efficiency. Maximum efficiency of execution against a plan calls for the fewest people delivering the most output to a predetermined set of architectural decisions. Building in robustness – for example, redundancy of people so that skills and knowledge aren’t resident in a single person, pursuing multiple technical solutions as a means of mitigating non-functional requirements, etc. – will not come naturally to managers with a singular focus on minimizing cost, especially if, like hedge fund managers James Mackintosh was referring to, they’re blissfully unaware of the risks.
So, what can we do?
First, we have to stop trafficking in the false precision of IT project management. This is no easy task, particularly in a business culture rooted in fixed-budgets and rigid planning cycles, buyers of industrial IT expecting that technology labor is interchangeable, and so forth. We won’t change the landscape all at once, but we can have tremendous influence with current business examples that will be relevant to sponsors and investors of IT projects. If we change the expectations of the people paying for IT projects, we can create the expectation that IT should provide probabilistic projections and take more robust – and therefore one-way risk tolerant – solution paths.
Second, we can introduce risk management that is more sophisticated than what we typically do, yet still easy to understand. If you haven’t read the book, or haven’t read it for a while, pick up Waltzing with Bears by DeMarco and Lister. Their statistical model for risk profiling is a good place to start, quick to work with and easy to understand. Nothing stops us from using it today. Now, the act of using the tool won’t make risk management the central activity of project managers or steering committees, but adding a compelling analysis to the weekly digest of project data will shift the balance in that direction. That, in turn, makes it easier to introduce robustness into IT delivery.
On that subject of robustness, Taleb observed:
Close to 1000 financial institutions have shut down in 2007 and 2008 from the underestimation of outsized market moves, with losses up to 3.6 trillion. Had their managers been aware of the unreliability of the forecasting methods (which were already apparent in the data), they would have requested a different risk profile, with more robustness in risk management …. and smaller dependence on complex derivatives.Given the success rate of IT projects – still, according to the research organizations, less than 40% - IT project managers should similarly conclude that more robustness in risk management would be appropriate.
I’ve been playing with Django & MySQL for a while but for my next project I wanted to integrate it with a PostgreSQL database. Everything went well until I wanted to install Psycopg as my python adapter to PostgreSQL.
After a bit of blundering about here’s what it eventually took:
/Library/PostgreSQL/8.4/bin/pg_config and is not by default on the PATH so if you don’t put it on the PATH or in this configuration file the next step will fail in a spectacular manner.sudo easy_install .‘ in the top level psycopg2 source directory.postgresql_psycopg2 when you configure Django’s database layer for your project.
ThoughtWorks embraces the individuality of the people in the organization and hence the opinions expressed in the blogs may contradict each other and also may not represent the opinions of ThoughtWorks.