Product and Service companies have their unique characteristics. Whereas in a Product organization, it is quite commonplace to deep dive into topics, over engineer and over generalize. The talk is always about frameworks. Frameworks and reusable components out of everything. Generating stuff wherever possible.
Quite a contrast to this is the Service set-up. On time, On budget, On quality … these words keep echoing the walls of any service organization. Doing just enough what the client would accept. As a rule, no generic/reusable components. If there is lot of reuse, the opportunity to bill the client is lost.
Time and Material is the preferred deal, where, longer the project, better it is for the Service Organization.
Can these two worlds meet ?
How about an organization that creates products in a particular domain but also services clients pertaining to that domain. This is not very uncommon. There are teams that work on product development. Such teams retain the characteristics of a Product set up described above. And there are client specific project teams that carry out various projects.
There are those rare opportunities when people from one set up move to the other. Recently I was responsible for the design and implementation of a particular module. Being relatively new to the domain, the learning curve was steep. The module wasn’t an easy one. There were enough ambiguities in the
requirements. In all there was enough to think. To think hard enough.
While BR, S and myself were excited at this prospect, there was enough to dampen our spirits. The deadline has been fixed even before any attempt at estimations were made. We were given a team but we hardly knew the team members. It wasn’t certainly a top notch team. This meant that we have to do as much as upfront thinking as possible leaving very little to the team. The team had just enough time to code.
I was wondering how to go about this. While we want to know the domain and solve real world problems, we are given these constraints as well. Then I decided to “Design Big and Implement Small”. The design team consisting S, BR and myself started off with Data modeling. We argued, debated and fought over what to include, how much to generalize and what to leave out. We had this understanding amongst us – if we get into a sort of discussion loop, I shall take the final call. On a couple of occasions I had to use this “power” to resolve certain issues.
We did quite a generic data model. Documented it well. We then knew what parts we wont implement for the lack of time and the risk of over engineering. As expected, we encountered certain changes in requirement but our data model was already geared to take up that. It wasn’t a surprise but reinforced our faith in spending adequate time upfront.
Project pressures can do wonders. It can dumb down a smart guy, make you stop thinking and the like. We learnt this the hard way when we initially exposed every team member to the entire data model extolling the virtues of good design etc. They were hardly interested ! Later, development team members were exposed to the data model to the extent they need to know. Gradually they got to know the entire model as the project progressed.
Certain design decisions we made that paid a lot of dividends were
1. Not trying to minimize the number of tables. Have as much as needed. We later removed one or two.
2. Never put any business logic into the tables. ie., if there are columns ColA and ColB, you have done a bad design if you explain something like this to your team – “it is always the case that whenever ColA is null ColB is not null and therefore the Type is inferred as X. If ColA is not null and ColB is null then the type is infereed as Y … blah blah”.
3. We had to pick the top three performers (winners) through the application. But we did not know how to handle ties. So we decided that the system shall only “suggest” the winners and not handle ties. The suggested winners can be manually overridden. This decision saved us a lot of trouble. The code became much simpler.
4. Coming up with the set of services. For each services, we listed out
a) Description of what it is supposed to do.
b) Business logic and validations.
c) pseudo code in case of any complex logic
d) special considerations if any.
5. In other project teams, the developer had to do UI and then code the business logic and DAOs. There wasn’t clear service separation. Service implementation and UI implementation were done in parallel. We had a tool that generated all DAOs. Using spring helped a lot. It took care of much of the housekeeping code. The developers could focus on the business aspects to be implemented.
6. Asynchronous processes were identified and were processed through a standalone program. This helped in better performance and scalability.
In spite of all this, the project did have its share of dramatic moments. Some key developers let us down, some (personnel) decisions backfired. But overall, it was smooth. At no point were things out of control.
With the lessons learn in this module, we are going ahead with the second module. We would follow the same approach. I expected much smoother going this time. Lets see !