📜 ⬆️ ⬇️

Anti-design patterns: Functional Decomposition

Name: Functional Decomposition (functional decomposition)
Other Names: No Object-Oriented AntiPattern "No OO"
Scale: application
Refactoring: object-oriented reengineering

Functional decomposition is a good practice for procedural programming, as it allows you to divide an application into separate functional modules.

Unfortunately, functional decomposition cannot be directly reflected in the class hierarchy, and therefore sometimes there are problems described in the article.

Often the anti-pattern is manifested when experienced developers in procedural programming begin to design and implement a program in an object-oriented language. If developers are accustomed to having a main subroutine that calls other subroutines, then they tend to run each subroutine as a class, completely ignoring the class hierarchy (and the object-oriented approach in general).
')
The resulting code is similar to the constructions of a structured programming language implemented in the form of classes. Such code can be incredibly complex, as experienced developers can come up with clever ways to repeat in an object-oriented architecture time-consuming procedural programming techniques.

You can often encounter an anti-pattern when a C-programmer starts writing in C ++, or tries to connect CORBA interfaces, and also tries to use some kind of object technology. In the long run, it is sometimes easier to hire programmers with object-oriented thinking, rather than wasting time learning object-oriented technologies.

Signs of the appearance and effects of anti-pattern



Typical causes



Exceptions


Functional decomposition is acceptable if an object-oriented solution is not required. This exception can also be applied when, in essence, a purely functional solution is wrapped in classes in order to provide an object-oriented interface.

Refactoring


If it is still possible to determine the initial basic software requirements, then it is necessary to create an analytical software model that describes the most important software features from a user point of view. This is very important for determining the purpose of most software constructs in the code base. At all stages of anti-pattern refactoring, it is necessary to document in detail the changes made - this will make life easier for those who will accompany the system in the future.

Next, create a design model that includes the main parts of the existing system. Focus not on improving the model but on creating the basis for describing as much of the system as possible.

In the ideal case, the design model justifies the presence of most software modules. The development of the existing code base design model is very important - the process provides an understanding of how the system functions as a whole.

It is logical to expect that some parts of the system exist for reasons already unknown. For classes that fall out of the project model, use the following rules:

Explore the architecture and find similar subsystems - these are candidates for reuse. As part of program maintenance, perform code base refactoring to reuse code in similar subsystems (see the Spaghetti Code anti-pattern solution (“spaghetti code”) for a detailed description of refactoring).

Example


The basis of functional decomposition is a sequential call of functions that perform data manipulation, for example, using Jackson Structured programming (JSP) methods. Functions are often methods in an object-oriented context. The distribution of functions is based on different paradigms of OOP, which lead to different grouping of functions and their associated data in classes.

A simple example in the figure below shows a procedural version of a customer’s loan calculation scenario:

Calculation scenario:
  1. Add a new customer.
  2. Update customer address.
  3. Calculate the loan for the buyer.
  4. Calculate loan interest
  5. Calculate loan repayment schedule.
  6. Save new payment schedule.

The following figure shows an object-oriented view of the loan calculation application. Procedural functions are mapped to object methods.

Related solutions


If the development of the system has already been expended significantly, then you can apply an approach similar to the alternative solution to the Blob anti-pattern problem.
Instead of bottom-up refactoring of the entire class hierarchy at once, you can extend the class “main subroutine” to the class “coordinator”, which will manage all the functionality of the system.
Functional classes can then be transformed into quasi-object-oriented classes by combining them and also transferring a part of their functional to the class “coordinator”. The result should be a more efficient class hierarchy.

Source: https://habr.com/ru/post/251089/


All Articles