How to enumerate bad Smells in a software?

Asked

Viewed 163 times

5

I am working on a relatively large system (considered unworkable rewriting effort) PHP that implements in a certain way the MVC architectural pattern and that has (under a higher point of view) several "bad Smells". Think of everything: from unnecessary couplings, lack of Patterns design to solve recurring problems and incorrect use of inheritance and polymorphism to memory misuse and impossibility of scalability (through the creation of new instances).

I was given the challenge of cleaning up this mess (I think through refactoring on refactoring), but I don’t know exactly where to start. I believe enumerating the problems would be the first step to take, and then questions arise: How can I list software problems for further analysis? There are automated tools that can discreetly detect problems, or group them together?

Rebound that is not feasible to rewrite on account of time invested, obscure business rules and non-existent documentation.

Good luck to me.

  • 1

    I don’t think there’s a "right" answer in your case. IMHO the problem of not scaling should be a priority, but I do not see how to solve this type of problem only with refactoring.

  • @Pagotti certainly the problem of scalability will need something more complex, I agree. For the rest, do you know any automated tools that can give me an overview of the use of bad practices in source code? I don’t think it’s practical to list everything one by one.

  • I don’t know but those indicated by Gabriel seem to help in this direction.

  • 1 bath a day should solve the problem of smell. Now seriously, bad Smells is also better known as code Smells, wikipedia until it is well detailed on the subject https://en.wikipedia.org/wiki/Code_smell (English) for those who want to know what it is about.

  • @Guilherme I know the terminology "Code Smell". I used "bad Smell" to specify that it was a bad smell. In my graduation the professor used the terminology "good Smell" to indicate an indication of a hit when implementing.

  • Yes some use a way more than others, I just put so that people understand what you mean.

  • I suggest that whoever marked as "subjective" can point to subjectivity after editing.

  • Well, I voted in favour of your question, but I also voted to close. The problem in my view is not subjectivity, but the part of being dependent on opinions. I think the half difficult part was the "And from then on, in which order it would be most efficient to start solving them?" that you’ve already removed from the question, that was very opinionated. I could argue one more thing or another in the question and also in the answer about the opinionated bias, but rethinking the situation, probably this would be to sin in the excess of rigidity. I’m voting to reopen.

  • I removed that part of it, although I still feel that an important part of it needed to be ignored in the process. If we think analogously to a question like "what would be the most efficient search algorithm in situation x" for example, the efficiency would be measured among several algorithms to get an answer, and it would not be "based on opinion" because there is a quantitative parameter that would be independent of the respondent’s opinion. I hoped that a comparative approach would be brought to the answer and a logical, nonsubjective conclusion.

  • @Calebeoliveira this is just the basic problem of consulting a community based on Q&A, there are questions that cannot be answered according to the rules and, in my view, are the most important.

  • @Guilhermenascimento Kent Beck treats more like bad smell than how code smell in the book "father" of the TDD. What is the confusion generated? Since the term is mostly used by the TDD.

  • 1

    @Gabrielheming is definitely taking me the wrong way and confusing everything I said. I’ve never read such a book and just because it’s in a book doesn’t mean it’s the most used. I just put the link to who knows how to "Code Smell" know what it is about "bad Smell", do not need to make a storm in a glass of water.

  • 2

    The most bizarre of all is that the closure by "opinion-based" is purely based on opinion, there being for example a bar to measure how opinion-based a question is; there is also the susceptibility to "herd behavior"where almost random votes are induced and computed by the platform.

Show 8 more comments

2 answers

8


TL ; DR

How to enumerate bad Smells in a software?

  • Mapping and relationship (in diagrams);
  • TDD (which is not found by mapping, appears in the Tests, see Liskov Substitution Principle);
  • Understanding the mapping with the business need (bad business Smells);
  • Auxiliary tools.

Explanation

Only through refactoring on refactoring will not be enough to "clean" the system. You can even clean up a unit, but you’re only in it.

Your situation is very delicate and slow-resolution. Also, you can find/use various approaches. The one I’m going to present would be more of a mix between "conservative" and "agile", to prevent the situation, in which the system already stands, from being repeated.

As you will not rewrite the system entirely, it must go in parts. The following approach can be used for both scenarios, just need to find and define the limits of refactoring.

First, map the component you want to refactor:

  • use cases;
  • classes;
  • Storage;
  • sequence;
  • states.

With the above mapping, you will identify how the ecosystem really is that should be refactored.

After, do the conceptual refactoring. See the state that the system/ component is, where and how, you should take it. Use system use cases to understand what would be the optimal integration/interaction between components.

Normally, in such cases, the use case diagram is your base of support for not losing the purpose of the system, along with sequence and states. For, if the system was developed with business in mind, they will have little, if any, change. What I believe is not your case.

Another case that should be highlighted is the refactoring level. If you refactor only one class, sequence and states are unnecessary. However, a set of classes has an integration that cannot be broken, and that is why we find the most appropriate approach.

After understanding, comes the dramatic part. Write tests, many, interspersing in unit and high level tests. You will need to maintain system integrity while refactoring the system. TDD will be very important in this step. As Robert "Unclebob" Martin would say: "TDD is the documentation/manual of your code"

Some tools that can support you at code level:

  • PHP Mess Detector (will inform you about coding issues, will make your code clean and functional);
  • PHP Code Sniffer (will keep your system within PSR standards);
  • PHP Unit (simply TDD);
  • Blackfire. (performs system performance tests, also maps all class interactions, you may find bottlenecks and inefficient interactions).
  • Astah Community (all the above mentioned diagrams can be written on it)
  • Mysql Workbench (if the system is in Mysql, the reverse engineering of this tool is really interesting).

After the "superficial" understanding of how to make the modifications (low-level modifications always appear during the refactoring process), use the Techniques and principles, below, to guide development:

These would be the approaches and tools that I would use to refactor an existing system. Nothing different from what I do in developing a system from scratch.

Some useful links:

Addendum: I don’t want to go into details about whether UML, Scrum or any other methodology is better. Only inform you about situations that can be predicted with one or another diagram. If you don’t like one approach, use a similar one, take what you know from your methodology and apply what will give you confidence.

  • As the system is very much connected with the database, with the Apache server and the operating system, I think I will also have to create a VM or Docker containers to replicate the whole environment.

  • Yes. Isolate your environment. Try working with progressive fixes and complementary updates, so you can upgrade a part of the system (whether small or large) without compromising how it works. Understanding about continuous integration would help (this is beyond my knowledge, my focus is OO itself).

3

Divide and Conquer

First of all, it’s just an opinion, a set of generic tips, maybe even the obvious. As a general rule, when you later tamper with the code, less rework will have.

I think in this case it’s worth remembering Knuth:

Premature optimization is the root of all evil. Programmers get care too much about code efficiency in wrong places and the wrong time.

In the activities it is always good to create diagrams, even if they are on paper. Drawings give you a clearer view than a list of problems.

  • Components. Try to draw the system from the outside in order to know which are the current modules and components and which should be the actual modules.
  • Dependencies. Identify which dependencies between the parties and dependencies should not exist. There are dependencies of other third party components, etc.
  • Communicating. Something important is how each party communicates with the other. The coupling of some parts may be unnecessary but may also not interfere with the efficiency of the whole. With this you can choose what to decouple and what not.
  • Bottlenecks. With the first three you can identify the parts that will prevent you from meeting the new requirements (scalability, for example) and identify what you have to solve first and what you can end up with.

The part of refactoring where you will improve future code maintenance or facilitate understanding comes after you have this more comprehensive view and can divide and prioritize the work.

Good luck to you. =)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.