Monday, 10 December 2007

The main problem in big software projects is complexity growing as the project unfolds. Generally when the main architecture is ready and the product has been started the number of architectural features grows with the size of the code. The speed of growing, though, is not constant. At the beginning it is almost linear and equal to time multiplied by team. But the longer it lasts, the bigger size of the code, the more complex is the product to develop further. From my personal experience the time spent to develop a new feature of average size increases by an exponential law. [Features are meant to be architectural but perceived in complexity from the customer point of view.] This idea gives a rule to predict milestones and practical limit of the product. For example, if the first 10 features took 4 days to develop and the second 10 new features took another 5 days to develop, then to implement 50 features will take 7 weeks and to implement 100 features 27 weeks. [Formula used is y=F*ln(kt+1). In the example above we find that k=1/16 and F=10/ln1.25]

Friday, 7 September 2007

Coding rules are written for particular community of people who intend to review, maintain, or use the code. It is called coding standard. But there are 2 other important sources which influence the style. These are taste and simplicity. I disagree on that the coding standard, whatever it is, has to be followed blindly.

So 3 points influencing the style are:1. Personal taste: You personal choice2. Simplicity/clarity: Do not sacrifice clarity to your or other people's taste3. Community: What most (other) people expect to see when looking at the code.

My personal preferences are:1. Find which community is likely to work later with the code.2. Follow coding rules if they do not disagree with your taste and code clarity.3. If a rule is not good from your point of view, decide which one: your taste or community is more important in that context.4. If a rule makes code less simple or clear, ignore the rule. [This is very subjective so be prepare to stand for your opinion]

Wednesday, 15 August 2007

Software development is a sequential process. The product is always being developed bit by bit. The main problem arises when new bits added to the future product break the previous functionality. This is called complexity limit. Once the product developed reaches its complexity limit no reasonable development becomes possible. The complexity limit is obviously subject to both the design and the process. The difference between them is that if the design adds absolute value in fighting with complexity the process adds relative. That means that the process can leverage the extent of the final product, but cannot define it. As example, suppose that the product is 100 percent functionality and with some given design the complexity limit appears at about 50 percent. Next suppose that the process may leverage the extent by 20 percent of the reached extent. So the final product will have 50+50*0.2 = 60 percent of desired functionality. Now if the design is poor and allows going only up to say 20 percent, then the gain obtained from the process is 20*0.2 = 4 percent (totalling 24). If the design is good allowing 80 percent with no process, then the process will add 16 percent (totalling 96).

Under design I mean here all development solutions on the whole scale from architectural to coding. Under process I mean here the standards accepted by the development team.

Thursday, 26 July 2007

Programming is a fight against the complexity

When a program is being developed its complexity may increase or remain the same. We can define the program complexity as the complexity of its most complex component (the component decomposition can be seen as a separate component itself). It would be an interesting question what kind of program modifications increase the complexity and what do not.

Complexity multiplies but capacity does not sum up

A number of people cannot create a program which is more complex than at least one of these people can understand. From the other hand, linearly adding a new component of lesser complexity that already exists does not increase the overall complexity. Keyword here is “linearly”, which means that complexity of the decomposition (referring to the level on which the component added) does not increase as well, or increase so as not to outweigh the overall complexity. But making the new component interdependent with existing components opens new dimensions in internal states of the program (non-linearity) that is multiplying the complexity.

Architecture

Each character of the code has its own path to the top level concept of the program. Top level concept of the program lies on the abstract layers braking up the program architecture into independent components, which are lying on lower level layers and so on until we reach each separate character of the code.Understanding this path from the bottom level to the top level is architectural awareness. It is important that the programmer has one. Otherwise the complexity of the product can grow incredibly fast.

Push, pop, and pull requirements

The requirements evolve from the customer to the final coder. It is not possible to imagine that the programmer can develop a program targeting each customer requirement individually.

The requirements can be generally grouped into 3 categories.

Customer requirements (Pull). Something which defines the product.

Architect requirements (Pop). The model which can be implemented in software and is proven to mimic the customer definition of the product. These requirements are conditions to components and their interaction.

Code requirements (Push). Testable functionality of the program.

Push requirements are satisfied when the program undergoes a number of scenarios defined the requirements. This can be done by auto scripts validating expected output.Pop requirements are satisfied when the program conforms to the defined component interfaces. This can be done by documented and frozen APIs.Pull requirements are satisfied automatically given that the model is adequate to the required product. These can be customer acceptance tests, but they would not be a part of the product development.

Failure to break the requirements into these 3 categories and treat the customer requirements as the requirements to the software leads to ad hoc style programming. Programs written in this way are difficult to modify and they are sources of plentiful hard tracking bugs. This can work only for small programs.