Program Analysis and Software design

Table of Contents

1. System modeling

Diagram formalizes model

Model composes view

View adresses requirements

Requirements are important to the stakeholder

1.1. C4 model

A “zooming” framework. You go deeper and deeper into things, based on what’s important. Eventually, you can arrive at the code itself.

Good example: it’s like a map. You start zoomed out, seeing the whole world. You can progressively zoom in until you’re on specific streets. Another beautiful example of this is the banking system example linked on the slides.

C4 models can be made by dragging boxes, or writing code.

C4 made out of 4 levels:

1.1.1. Context

Describes main parts of the system. This is extremely general.

This can be the system itself, the entities the system interacts with, external systems.

1.1.2. Containers

This explains how the system is composed, and can also describe how these parts of the system interact with the bigger systems.

This a description of system organization, no specific details on how everything works

In Java, like modules.

1.1.3. Components

How components interact with each other.

Describes the features of the program and how they interact with each other.

In Java, like packages.

1.1.4. Code

The code itself. Can be viewed as individual classes in Java.

*

2. Design metrics

2.1. WMC

Weighted Methods per Class. This finds the “complexity” of a class by summing the “complexities” of its methods.

How is a complexity calculated? It depends on the type of complexity The most basic one is just the number of operations or methods in a class.

Example: In a class with 10 methods which each have a complexity of 1, the WMC would be 10.

2.2. DIT

Depth of Inhertitance Tree. This measures how many levels there are to the root class.

Example: If a class C inherits from a class B which inherits from another superclass A, the DIT of C would be 2, DIT of B would be 1.

We don’t count superclasses.

2.3. NOC

Number of Children. Similar to DIT, this measures things from the superclass point of view. It counts how many children the superclass has.

Example: Iff 2 classes inherit from some superclass A, the the NOC of A is 2.

2.4. CBO

Coupling Between Object Classes. This measures the number of classes that some class is coupled to.

Example: If some class A uses methods or attributres of 5 other classes, its CBO is 5.

2.5. RFC

Response For a Class. The number of unique methods that can be executed in a response. To find RFC, sum the number of methodsin a class and the number of methods called within these methods.

Example: If some class A has 5 methods, and calls 3 other methods within its own methods, the RFC is \(5+3=0\).

2.6. LCOM

Lack of Cohesion in Methods. Ideally, you want to have a lack of cohesion in methods. This means that methods don’t share much of the same data. If classes have high cohesion, it means that they rely on each other (fact check) quite a bit which results in harder to understand and harder to maintain code.

3. Code smells

3.1. Abstraction smells

Smells that relate to the abstractation (simpilifcatio) of code. *

When something that is not needed to be abstracted is abstracted.

When an operation is turned into a class.

org.apache.shiro.tools.hasher.Hasher

*

3.1.1. Multifaceted Abstraction

When a single class or interface tries to represent too many things.

3.1.2. Unutilized Abstraction

WHen you create abstraction but you don’t use it or it’s not reachable.

3.2. Encapsulation smells

Self explanatory. Encapsulation smells.

3.2.1. Deficient encapsulation

Public methoids that are only used by the class that holds it or its children.

3.2.2. Unexploited encapsulation

When code uses if elses instead of fully exploiting encapsulation (?)

3.3. Modularization smells

Separation and dependecy type smells.

3.3.1. Cyclic-dependent modularization

Two or more abstractions depend on each other. Cyclic dependencies.

3.3.2. Hub-like modularization

An sbtraction having many dependencies, acting as a “hub.”

3.3.3. Broken modularization

Data and/or methods are separated into multiple abstractions when they really don’t need to be.

3.3.4. Insufficient modularization

The opposite of the above. Not enough abstraction, massive classes.

3.4. Hierarchy smells

Smells related to the hierarchy of code. Generally, subclass/superclass smells.

3.4.1. Wide hierarchy

Too many child classes inheriting from one superclass.

3.4.2. Cyclic Hierarchy

A supertype depends on any of its subtypes.

3.4.3. Deep hierarchy

Too much inheritance.

3.4.4. Missing hierarchy’s

Uses conditional logic where a hierarchy could have been created to encapsulate variations, for example, using switch statements instead of the strategy pattern.

3.4.5. Rebellious hierarchy

A subtype rejects methods given by its supertype. For example, when a class implements a method interface with an empty body.

3.4.6. Multipath hierarhchy

A subtype inherits both directly as well as inderatly from a supertype leading to unnecessary inheritance paths.

Author: Jay

Created: 2025-04-15 Tue 16:07