Structural fan-in (SFIN) and fan-out (SFOUT) values measure the relationships between files and between procedures. They measure the complexity of the static (design-time) structure of code.
A useful way to look at SFIN and SFOUT is to view them as graph metrics. Visualize procedures (or files) as nodes and calls between them as as arrows. Fan-in is the number of arrows coming into a node. Fan-out is the number of arrows going out of a node.
Fan metrics for files and procedures are related to each other, but they are counted with different rules.
Structural fan-in/fan-out for procedures is calculated from the procedure call tree.
Structural fan-in/fan-out for files is calculated from the file dependency tree.
A file depends on another file if it requires the other file to compile or run. It may call procedures in the other file, read/write its variables, access its constants, or use its class, interface, UDT or enum declarations. This is to say that the file-level fan values are based on a larger number of uses/used-by relationships than the procedure-level values.
A SFIN value of 2 or more indicates reused code. The higher the fan-in, the more reuse. A high SFIN is desirable for a procedure because it indicates a routine that is called from many locations.
A high SFIN is not as desirable for a file. It represents a high level of cross-file coupling. SFIN for a file should be "reasonable". We leave the definition of what is reasonable in a project to be determined case by case.
SFIN=0 indicates that no explicit callers were found in the analysis. It does not necessarily indicate a dead procedure, however. The procedure may be in use via a non-explicit call. An example of this is an event handler which triggers to execute on a control event. Instead of SFIN values, you should use Project Analyzer's dead code detection feature to find and remove dead code.
A special use for procedure-level SFIN is the detection of procedures that could be inlined. If a procedure's SFIN is low but positive, it has a small number of callers. Depending on what the procedure does and how complex it is, you could possibly embed it within the caller(s). This is a speed optimization technique. We don't recommend inlining for usual coding because keeping the code modular improves reuse and legibility.
A high SFOUT denotes strongly coupled code. The code depends on other code and is probably more complex to execute and test.
A low or zero fan-out means independent, self-sufficient code. This kind of code is easier to reuse in another project or for another purpose. A file whose SFOUT=0 is a leaf file in the project. You can include it in another project as such and it will most probably continue to work the same way.
To evaluate the average coupling between files, monitor the average SFOUT/file value. This is the average of "how many other files this file depends on". It makes sense to try to keep this value low. Achieving a low cross-file coupling should be done via restructuring and planning. It should not be achieved by just mechanically joining files — so keep an eye on the file sizes as well. Notice that SFOUT/file is likely to be higher in a large system because the parts of the system need to interact with each other. As your project grows, SFOUT/file is likely to increase even if your code is well designed.
©Aivosto Oy - Project Analyzer Help Contents