iTranslated by AI
On "Bad Smells" - Examining the Structure of "Bad Smells"
This article is for the 22nd day of the DDD-Community-Jp Advent Calendar 2020.
Introduction
Overview
In response to the following articles, this article attempts to examine the nature and structure of the "bad smells" we occasionally sense intuitively as a form of perception.
- "Possibilities of combining RDRA and EventStorming (Design Level)" by @t2-kob
- "Bad Smells in Models" by @jnuank_
These articles are based on experiences from an event (commonly known as the "Modeling Session") currently being held (as of 2020/12/19) within the Discord server of DDD-Community-Jp, a community focused on Domain-Driven Design. These articles show that experiences similar to "Code Smells" occur even during modeling, and that these experiences may be categorizable to some extent, just like code smells.
This article focuses on the point that perceptions similar to "Code Smells" are found during modeling—that is, in activities targeting things other than program code. Through the metaphor of "bad smells," it attempts to explore what kind of structure and properties the perceptions we hold actually have.
Important Notes
This article is an exploration of the perception expressed by the metaphor of "bad smells." It does not attempt to elucidate exactly what is recognized as a "bad smell," nor does it attempt to clearly define criteria for when and how to modify code or model expressions.
Notation
In this article, terms like "odor" (臭い), "scent" (匂い), and "smell" (におい) will be unified as the hiragana notation "nioi" (におい), except in quoted sections.
"Bad Smells"
Here, we compare two expressions that apply the same metaphor of "bad smells" to different targets: code and model expressions.
"Bad Smells in Code"
The title's "bad smell" originates from the term "Bad Smells in Code," which has been used in the context of programming and software development. (Henceforth, for consistency and simplicity, it will be referred to as "smell"). This was originally a term coined by Kent Beck and was publicly used in Chapter 3 of Martin Fowler's book Refactoring[1].
"Bad Smells in Code" is a word given as a metaphor representing a "trigger" to engage in refactoring; it does not point to specific criteria or states. In Refactoring (Fowler 2019), he categorizes the types of "bad smells in code"—the signs that trigger the start of refactoring—names them, and provides effective countermeasures, thereby offering several pieces of judgment material on when to start and end refactoring[2].
A "bad smell in code" indicates a "trigger" to proceed toward refactoring a certain piece of code. A person who perceives a "bad smell in code" is driven by that perception to refactor—that is, to "change the internal structure of the software to make it easier to understand and cheaper to modify without changing its observable behavior" for the target where the "smell" was perceived[3].
"Bad Smells in Models"
In the articles mentioned at the beginning, the metaphor of "smell" used in "Bad Smells in Code" is applied not only to code but also to diagrams and text (hereafter referred to as "model expressions") that represent various models applicable to software. Following the lead of "Bad Smells in Code," this is referred to as "Bad Smells in Models."
What I felt had the greatest impact was the point that "everyone's understanding had diverged."
Yes, as implementation progressed, the assumptions of the words and terms everyone was using began to drift apart without anyone noticing.
(Omitted)
Triggered by communication mismatches, people are sensing "model smells" just like so-called "code smells."[4]
In the article mentioned above, the states where "everyone's understanding of the model diverges" or "a sense of incongruity regarding the model occurs" are described as bad smells in the model.
(Omitted)
Here, let's define "Bad Smells in Models" as "situations that make one feel the need to stop modeling or implementation and return to the model itself for review."[5]
Looking at the articles, we can see that some kind of phenomenon expressed by the same metaphor of a "bad smell" as in "Bad Smells in Code" is being intuitively perceived, targeting model expressions rather than code. Furthermore, it describes how the perception of such a "bad smell" serves as a "trigger" to encourage actions such as "revising" or "reviewing" the target model expression, moving to "stop modeling or implementation and return to the model itself for review."
This "revision" or "review" tends to be performed to resolve the state where "everyone's understanding of the model has diverged" or where "a sense of incongruity regarding the model has occurred." It involves correcting the words appearing within the model expression, adjusting the connections between words and diagrams, and clarifying the distinction between ambiguous and clear parts.
Ultimately, these "revisions" and "reviews" seem to point toward an attempt to make the perception of the subject being discussed through that model expression more rigorous and consistent.
Basic Structure and Properties of "Bad Smells"
Whether it is a "Bad Smell in Code" or a "Bad Smell in Models," when we perceive a "bad smell," the following two points are common despite their different targets:
- That "bad smell" acts as a "trigger" to be "driven" in a specific direction.
- That "drive" is primarily directed toward transforming the target in which the "bad smell" was perceived into a "more 'correct' (as anticipated) form."
In "Bad Smells in Code," the "bad smell" is described as a metaphor for the "trigger" to start refactoring. Using this perception of a "bad smell" as a "trigger," we are driven toward the activity of refactoring. This "drive" is directed toward the idea that the target code "must be modified so that it is easier to understand and cheaper to modify." In this drive, the state where the target code becomes "easier to understand and cheaper to modify" is anticipated as the "more 'correct' form."
On the other hand, "Bad Smells in Models" are described as situations where "everyone's understanding of the model diverges," "a sense of incongruity regarding the model occurs," or cases that "make one feel the need to stop modeling or implementation and return to the model itself for review." When obtaining such a perception of a "bad smell," one is "driven" to "stop modeling or implementation and return to the model itself for review," and to modify the model expression so that it speaks to a more rigorous and consistent understanding. In this scenario, it can be considered that such an aspect—namely, that "the model expression speaks to a more rigorous and consistent understanding"—is anticipated as the "more 'correct'" form of the model expression.
"Bad Smells in Code" and "Bad Smells in Models" have different targets. Because the targets differ, the specific content of behaviors after perceiving these "bad smells" will also differ. One might also infer that the specific locations where the perception of a "bad smell" occurs and its specific content will often not coincide.
On the other hand, it can be considered that both are consistent regarding the following points:
- They take some kind of target.
- One is code, and the other is a model expression.
- Regarding the target, they drive the perceiver toward an action to change that target into a "more 'correct' form."
- In one perception, a "more 'correct' form" is anticipated in individual code or code structures; in the other, it is anticipated in diagrams, text, association lines, etc., of a model expression.
- They involve an anticipation that "the target has a more 'correct' form."
- This anticipation is in many cases intuitive, often bypassing logical inference or interpretation based on information.
The structure and properties mentioned here do not seem to be elements that hold true only when targeting code or only when targeting model expressions. Rather, this very structure and these properties can be said to be the basic structure and basic properties of the perception referred to here as a "bad smell."
Thinking this way, we can view "Bad Smells in Code" and "Bad Smells in Models" as examples of applying this underlying structure and property to specific targets like code and model expressions.
Summarizing this basic structure and properties, let's define "bad smell" as a generalization of "Bad Smells in Code" and "Bad Smells in Models."
- A "bad smell" takes some kind of target to be perceived.
- A "bad smell" causes the person who perceives it to have an anticipation that "the target has a more 'correct' form."
- A "bad smell" uses the above anticipation as a "trigger" to drive an action to bring that target closer to its "more 'correct' form."
If we accept this definition, we can say that we have acquired "bad smell" as a more general concept.
Structure of "Bad Smells"
We summarized the characteristics of "Bad Smells in Code" and "Bad Smells in Models"—two expressions applying the same metaphor to different targets—and compared them. As a result, we found that although the targets were different, the overall structure did not lose much similarity, and we eventually arrived at a more general expression: "bad smell."
From here, we will further attempt to analyze and describe this form of perception called "bad smell"—more accurately, what kind of structure this form of perception has and what premises it requires.
The Anticipations that Constitute a "Bad Smell"
Whether it is a "Bad Smell in Code" or a "Bad Smell in Models," when we perceive a "bad smell," there is an anticipation that "there is a more 'correct' form." Let's observe this anticipation more closely.
First, because the anticipation of a "more 'correct' form" includes the word "more 'correct'," it is clear that it is by no means directionless. It is not just staying as it is, nor is it moving in a "worse" (as anticipated) direction; rather, it is an anticipation oriented toward a "more 'correct' form." Furthermore, from the expression "more 'correct' form," we can see that it includes a kind of "normative" anticipation and an anticipation of the existence of such a form (accompanied by the quality of being "more 'correct'").
From the above, it seems that the anticipation of a "more 'correct' form" is composed of several types of convictions, such as constraints, norms, and existence. Let's consider the following classification and description as a breakdown of these convictions as constituent elements.
1. Anticipation of the existence of a "more 'correct' form"
We don't know if others would have the same impression, but at least for the observer, it is anticipated that the target (from some perspective) has a "more 'correct' form." If this anticipation is absent—that is, if we have the anticipation that "there is no form more 'correct' than this"—we would simply try to deal with the target and ourselves as they are (without particularly taking action beforehand).
2. Anticipation that the divergence from the "more 'correct' form" is caused by the target itself
It is also simultaneously anticipated that the cause of the target being away from the "more 'correct' form" (as anticipated) is not the ability or knowledge of the person perceiving the target, but originates from the state or manner of the target itself. Because such an anticipation is held, we attempt to act to bring the target, rather than ourselves, closer to the "more 'correct' form." Conversely, if we were convinced that most of the difficulty originated from our own ability or knowledge, our next action would be aimed at bringing ourselves closer to a "more 'correct' form" (such as through learning or acquiring knowledge through research).
3. Anticipation that the target can be brought closer to a "more 'correct' form" by human hands
When acting to bring a target closer to the "more 'correct' form" in response to the divergence caused by the target itself (as anticipated in 2), it is anticipated that approaching the "more 'correct' form" is actually possible through human action. When a person dies due to factors such as old age, illness, or an accident, even if the state of "being alive" is strongly anticipated (to the extent of conviction) as the "more 'correct' form" for a human, we do not actually try to bring that deceased person closer to "living (the more 'correct' form)." It is because we simultaneously anticipate that it is actually possible to bring the target closer to a "more 'correct' form" by human hands that the anticipation of a "bad smell" drives humans to act to bring the target closer to its "more 'correct' form."
4. Conviction that "the target should move closer to a more 'correct' form"
Even if the convictions in 1 to 3 are held, the "drive" to actually bring the target closer to a "more 'correct' form" will not occur unless it is ultimately anticipated that the target should proceed toward the "more 'correct' form." Whether the observation of the target is painful, or there is an anticipated risk of hindering future economic activities, or it is simply a feeling that it is not beautiful—when the anticipation that "this target should become a more 'correct' form" is accompanied in some way, the "bad smell" finally becomes a "trigger" to act so that the target approaches the "more 'correct' form."[6]
Four Anticipations
In this article, we will refer to the anticipations identified as constituent elements as follows:
- Anticipation of existence (Anticipation that the "more 'correct' form" of the target actually exists)
- Anticipation of cause (Anticipation that the divergence between the actual target and the "more 'correct' form" is brought about by the actual target)
- Anticipation of accessibility (Anticipation that the target is accessible to a "more 'correct' form" through human action)
- Anticipation of obligation (Anticipation that the target should move from its current state toward a "more 'correct' form")
Using "Duplicated Code" as an Example
In the previous section, we described the four anticipations that constitute the perception of a "bad smell."
In this section, we will examine how these four identified anticipations appear or can be found based on a specific example of a "bad smell."
In Refactoring (Fowler 2019), "Duplicated Code" is listed as one specific type of "bad smell in code." It is explained as follows:
When you see the same code structure in more than one place, you can be sure that your program will be better if you find a way to unify them. Having duplicate code means that every time you come across a copied part, you have to read it carefully to see if there is anything similar but different. When it comes time to fix duplicated code, you need to find the duplicates without fail and apply the same fix to all of them.[7]
Using this "bad smell" as a subject, we will confirm below that the four aforementioned anticipations are included in the "bad smell" and can actually be found as the anticipations that constitute it.
"Anticipation of Existence"
From this explanation, the difficulty of understanding—having to "read it carefully"—and the situation of needing to "apply the same fix to all of them" are anticipated. On the other hand, it is also stated that if they can be "unified into one place, it will be a better program." From this description, it is anticipated that a "more 'correct' form" exists where the aforementioned situations are absent or mitigated.
"Anticipation of Cause"
Furthermore, the above "anticipation of existence" is simultaneously anticipated to originate from the target code itself, rather than from one's own knowledge or understanding ability. It is not that one "has to read carefully" or that the "need to apply the same fix to all of them" arises because of problems in one's own knowledge or programming skills; rather, there is an anticipation here that the cause lies in the existence of duplication within the target code—an "anticipation of cause."
"Anticipation of Accessibility"
In Refactoring (Fowler 2019), after the explanation of "Duplicated Code," methods such as "Extract Function," "Slide Statements," and "Pull Up Method" are listed, explaining that the problem can be solved or put into a state where it is easier to solve through these methods.
From this explanation, we can find the "anticipation of accessibility" toward the "more 'correct' form" anticipated through the "bad smell" of "duplicated code"—that is, a state where "code duplication does not exist, and there is no need to read carefully or fix multiple locations" (which is the "more 'correct' form" in the context of seeing "duplicated code" as a "bad smell").
"Anticipation of Obligation"
In Refactoring, "duplicated code" is treated as a "bad smell," and within its explanation, the following are described:
- A negative explanation of the phenomena caused by "duplicated code."
- Presentation of methods to remove "duplicated code."
- A positive explanation of the methods for removing "duplicated code."
From these, it is considered that the "bad smell" of "duplicated code" is something that "should" be removed, and that an "anticipation of obligation" exists there.
Regarding Other Examples
This time, using "duplicated code" from Refactoring—a specific example of a "bad smell in code"—as a subject, we confirmed that the four anticipations are actually included and that specific examples of "bad smells" are indeed composed of these four anticipations.
Verification of whether this applies to other specific examples of "Bad Smells in Code" and "Bad Smells in Models" will be omitted here. Furthermore, the author has not been able to verify all examples personally. However, the author believes that this structure can be found in common across almost all specific examples.
Summary
This article started by focusing on the point that both "Bad Smells in Code" and "Bad Smells in Models" attempt to express some kind of perception using the metaphor of "bad smells."
First, we organized the content that both attempted to express using this metaphor and summarized their commonalities. As a result, we defined the term "bad smell" as a more generalized expression of both.
Next, we attempted to analyze the structure of the perception of a "bad smell" in more detail. As a result, we confirmed that a "bad smell" is composed of the following four anticipations:
- Anticipation of existence
- Anticipation of cause
- Anticipation of accessibility
- Anticipation of obligation
We also confirmed that these anticipations are actually included, using the "bad smells in code" listed in Refactoring as a subject.
Application
In various activities such as actual programming, modeling, or design, you may have perceptions of "bad smells" or similar feelings. These may sometimes be expressed in words like "bad smells in code," "a sense of incongruity," or "feeling gross."
Such intuitions can sometimes lead to leap-frog problem-solving methods or the discovery of problems that cannot be reached through logical reasoning or the accumulation of information alone. On the other hand, because they often do not pass through logical reasoning or information analysis, they are difficult to share with others or to verify for validity. There is also a possibility that a "bad smell" is actually a preconception or an illusion.
We believe that the four anticipations identified here can be used as tools to help verbalize for sharing with others and to verify validity.
For example, when sensing a "bad smell" from a certain piece of code, you could pose questions such as the following:
- Based on the "anticipation of existence," ask: "What is the 'more correct' form that I am anticipating for this target?"
- Based on the "anticipation of cause," ask: "Is the divergence from the 'more correct' form truly originating from the target? Might my own lack of knowledge or skill be making the target look 'incorrect'?"
- Based on the "anticipation of accessibility," ask: "Is it possible to approach the 'more correct' form? Given the nature of this product, is it practically inaccessible? If it is accessible, how can we approach (the 'more correct' form)?"
- Based on the "anticipation of obligation," ask: "Is this something that should become 'more correct'? Might there be cases where it is actually 'correct' enough as it is, and I just don't know it?"
Through these questions, it seems possible to verbalize the type, nature, and background of a "bad smell" and to verify the validity of the perception itself. Many other diverse questions could also be posed.
In this way, by asking "Is this anticipation truly valid?" regarding each of the anticipations that constitute a "bad smell," we may be able to capture various "bad smells" encountered in reality more precisely and increase opportunities to find more accurate problem-solving methods.
Challenges: The Mechanism of "Bad Smells"
What we have attempted to describe in this article is limited to the structure of the "bad smells" actually perceived. It does not ask why such perceptions occur, or through what process the kind of perception expressed by the metaphor of a "bad smell" emerges as our perception accompanied by such a structure.
If we could ask further questions following this article about the mechanism by which the perception of a "bad smell" is born, and if we could elucidate and define that mechanism...
At that time, we might be able to find criteria for when to stop and move toward "revision" when describing code or model expressions.
References
- @t2-kob (2020) "Possibilities of combining RDRA and EventStorming (Design Level)", https://qiita.com/t2-kob/items/3d1ec6a780107036d6b2 Accessed 2020/12/19 03:01
- @jnuank_ (2020) "Bad Smells in Models", https://jnuank.hatenablog.com/entry/2020/12/14/094851 Accessed 2020/12/19 02:45
- "WikiWikiWeb - Code Smell", https://wiki.c2.com/?CodeSmell Accessed 2020/12/19 01:39
- Martin Fowler (2018) Refactoring: Improving the Design of Existing Code
- Martin Fowler (2019) Refactoring: Improving the Design of Existing Code, 2nd Edition Translated by Yoshinobu Kodama, Akio Tomono, Akira Hirasawa, Masafumi Umezawa, Ohmsha
-
Martin Fowler (2019) Refactoring: Improving the Design of Existing Code, 2nd Edition p. 73 ↩︎
-
Martin Fowler (2019) Refactoring: Improving the Design of Existing Code, 2nd Edition p. 45 ↩︎
-
@t2-kob https://qiita.com/t2-kob/items/3d1ec6a780107036d6b2 Regarding "Bad Smells in Code," it is partially abbreviated as "code smells" in the article text. ↩︎
-
@jnuank_ https://jnuank.hatenablog.com/entry/2020/12/14/094851 ↩︎
-
In this discussion of the anticipation that "it should move closer to a more 'correct' form," judgments based on external conditions such as budget, personnel, and time—like "this is fine as it is"—are not handled. What is at issue here is not a judgment based on such specific information, constraints, or thinking, but an anticipation obtained intuitively through the target. ↩︎
-
Martin Fowler (2019) Refactoring: Improving the Design of Existing Code, 2nd Edition p. 74 ↩︎
Discussion