Probably the most interesting thing that I read in quite a while is the paper “The Nature of the Firm” ** by Robert Coase which can be viewed here. Ronald Coase answers a pretty interesting question: why in some cases it makes sense to gather resources together to carry out an economic activity while in other cases it makes sense to delegate that altogether to an outside party.
The answer lays in the extra costs that lay in carrying out a transaction or, as they are known, in transaction costs. Let’s say that you want to have your own house. You have 2 choices: one is to sub-contract parts of building the house and orchestrate the activities of the companies that you have sub-contracted: the one that pours the foundation, the one that puts up the walls, the people that paint your house, etc… or you can delegate the operation to the external entity, the home builder. The costs of each choice are (at first sight) the following:
1) carrying out the orchestration on your own: paying for the company that pours the foundation, the one putting up the walls, the one putting up the roof, etc…
2) delegating this to the home builder and paying for all of the above (the home builder will have to pay the sub-contractors just like you do) + the profit of the home builder who will be doing the orchestration for you.
At first sight it appears that you should be doing all the stuff yourself and come off cheaper than by delegating this to the home builder. But apart from the costs of the subcontractors you also incur the costs of interacting with them: you need to inspect the work of each one because you don`t know how good that sub-contractor is, you need to look around for good subcontractors, you waste a lot of time negotiating with them, etc… No suprise that most people prefer to go with a builder***.
What basically The nature of the Firm says is that if the costs of carrying out the activity on your own are less than the costs of delegating this to a dedicated party you should carry out this activity on your own rather than delegate it. You can see Coase’s theorem at work in the current outsourcing/offshoring trend: the transaction costs for outsourcing some operations are so low to the fact that a corporation can delegate efficiently various tasks to outside partners.
So how would this apply to software development? I would say that transaction costs demarcate pretty well what needs to be grouped together and carried out by one entity (which assumes a specialization of some sort) and what needs to be delegated to a different party. Well, this is what is needed for architecting a project: you need to determine how to group various classes, packages, systems together so that they minimize the interactions between them. The interactions between systems (or classes or packages) can be thought of as transactions: one class calls the other to do some work just like a home-builder calls the carpenter to install the hard-wood floor. By looking at the transaction costs between various components of an application you could determine what transactions (method calls) should be consolidated into component that handles them and what transactions should be allowed to exist on their own.
I would say that one big cost associated with a method call (or call to a package/outside system) is extensive orchestration between various classes (a method that calls 15 other methods from 7 different classes). If you have a pattern of method calls repeating over your code-base you should probably try to take a step back and consolidate these calls into a component that will serve the purpose of that particular orchestration. This way you will create a specialized component to which you delegate this orchestration, rather than replicating it multiple times. Efficient specialization of the components will incur lower transaction costs because it will push down on the number of interactions between components. For this you need domain knowledge. While designing a system you should look for specialization and for ways to achieve this specialization and once this specialization achieved you should look for ways to interact with these specialized components efficiently. If this is done properly you will end up with a system in which the cost of interaction between various components is low.
Another big cost for interacting with a different system is knowledge about the other system and class. The more knowledge you need to have about an external entity the more costly it is for you to interact with that system: you will need to be kept up-to-date with changes in this knowledge, there is a ramp-up cost, you can handle only this much knowledge, etc… It is a good thing to minimize the knowledge required for interacting with an external entity, this way a component can interact more efficiently with other components.
One corollary would be that you need to externalize as little as possible from any component and try to keep most of its sub-components private. One side effect of having too much of a component available is that you run the danger of a component coupling to it unnecessarily.
One cost for interacting with an external system is API coupling: the fact that you need classes exported by that external system**** in order to connect to it. If your system shares classes with an external system you will need a way to synchronize the shared classes with the external system. This is done usually either by having the external system having different versions for its points of interaction or by having a mechanism that publishes classes used for interaction. Either alternative is pretty costly, so you may try to keep away from sharing classes with an external system (though sometimes it may be impossible).
Transaction costs can be applied in project management as well: you should look out complex interactions between teams and try to assign them to a resource best dedicated to handle them (this resource could be a team-member, a well-defined process, etc…). However, in this case you should avoid assigning this interaction to a real person because you will run into scarcity constraints (i.e. you will run out of people) very fast if you keep delegating to real people. This is why these interactions are probably best addressed to a process.
I think that developing a software project while keeping an eye on the transaction costs is a good approach.
Later Edit. Transaction costs are very useful in determining the interaction between large components (systems, services, applications) and they are probably best used for managing this interaction. When you design the interaction of various systems the interaction costs (which are transaction costs) should be kept to a minimum for that interaction to occur without many problems.
* In this post transaction will be used for its economic meaning: i.e. it will stand for an exchange between 2 parties.
** If I am not mistaken Ronald Coase received the Nobel prize in economics for his work on transaction costs and this paper.
*** Please note that there are people that actually build their own houses on their own. The vast majority of them are in the construction business or have connections in the construction business so their transaction costs are a lot lower that for the ordinary person.
On a different note, the orchestration needed for building a home (calling the people that put up the jeep-rock after the 2/4`s have been erected, calling the painter for painting the walls after the walls have been put up, etc…) is a very simple business process without any intrisic value and prone to copying. No wonder that the builder itself makes a pretty small margin while the lion`s share of the profits go to the entity which owns the land…
**** You are generally sharing classes with an external system if you interact with it via RMI or EJB. Interacting with an external system via WS-* or REST is a lighter coupling.