Are there any techniques to apply maintenance in the code?

Asked

Viewed 173 times

1

Besides applying high cohesion and low coupling, how to handle codes like this? They may even be legible but this excess of logical operators, I do not see it possible to refactor even with switch-case.

                        if (!entry.isDirectory()
                        && !entry.getName().startsWith("__MACOSX/")
                        && !entry.getName().startsWith("_images/")
                        && !entry.getName().contains("/_images")
                        && !entry.getName().contains("/._")
                        && !entry.getName().contains("/_img")
                        && !entry.getName().contains("/imgs")
                        && !entry.getName().contains("/_old")) {
                    String filename = Util.buildFilename(nome);
                    filenameMap.put(filename, nome);

                    if (!nome.startsWith("[.]")
                            && (nome.toLowerCase().endsWith(".swf")
                            || nome.toLowerCase().endsWith(".gif")
                            || nome.toLowerCase().endsWith(".jpg") || nome
                            .toLowerCase().endsWith(".jpeg"))) {
                        files.add(dest + nome);
                    }

                    File destFile = FileUtils.getFile(dest, filename);

                    copyInputStream(zipFile.getInputStream(entry),
                            new BufferedOutputStream(new FileOutputStream(destFile)));
                } 

Sonarqube

Expressions should not be Too Complex

The Complexity of an Expression is defined by the number of &&, || and condition ? ifTrue : ifFalse Operators it contains. A single Expression’s Complexity should not become Too high to Keep the code readable.

  • 1

    I think it would help you to have better answers if you included in your question what the intention (i.e., the function) of this code snippet is. If you want to "filter" file patterns, maybe the best answer is really a combination of the two you already have: create a function that gets the file and a list of patterns to ignore, and then use regular expressions to check the file for each pattern in the list.

  • 1

    Any answer solved the problem?

3 answers

2

In this case little can be done. These code analyzers do not distinguish the intention. What can improve a little is to create the condition in a method and the if just call the method that will return a boolean. I don’t know if it will fully satisfy the analyzer or just change the claim place, but it leaves the code more semantic.

In fact the switch it wouldn’t make sense there.

The other answer gives a solution but has a joke that says when you try to solve a problem with RegEx you happen to have two problems. This has your truth bottom there, although it may not be the case for what you are doing specifically.

I would particularly create a generic function that checks by passing a list of texts. But you can try with RegEx to see if you like the solution.

Note that logic may not present the desired result in all situations. As I do not know the exact situation but it seems to me that there is a chance to produce false positives in some cases where the path may be in a different order.

1

You are basically making comparisons of strings to define the code flow. Regular expressions can make your code cleaner.

Lesson: Regular Expressions

Java Regex - Tutorial

However, regular expressions can become confusing to read and difficult to track during debug. I recommend isolating the test method and implementing a good unit test to validate it.

A little code to inspire you:

public static void main(String[] args) { 
    String regularExpression =
            "(" + 
            "(__MACOSX/.*)" +
            "|(_images/.*)" +
            "|(.*/_images.*)" +
            "|(.*/\\._.*)" +
            "|(.*/_img*)" +
            "|(.*/imgs*)" +
            "|(.*/_old*)" +
            ")";

    System.out.println("__MACOSX/".matches(regularExpression));
    System.out.println("_images/".matches(regularExpression));
    System.out.println("/_images".matches(regularExpression));
    System.out.println("/._".matches(regularExpression));
    System.out.println("/_img".matches(regularExpression));
    System.out.println("/imgs".matches(regularExpression));
    System.out.println("/_old".matches(regularExpression));
}

1

There is no standard technique unfortunately, but there are several techniques, I do not know if this is the best, but it is something that we can apply (based on Soen) would create a variable and testing one condition at a time, for example:

boolean returnValue;

returnValue = !entry.isDirectory();
returnValue &= !entry.getName().startsWith("__MACOSX/");
returnValue &= !entry.getName().startsWith("_images/");
returnValue &= !entry.getName().contains("/_images");
returnValue &= !entry.getName().contains("/._");
returnValue &= !entry.getName().contains("/_img");
returnValue &= !entry.getName().contains("/imgs");
returnValue &= !entry.getName().contains("/_old");

if (returnValue) {
    String filename = Util.buildFilename(nome);
...

These operators are called bitwise/bit-a-bit:

  • & (AND) - Example: a & b - returns true if a and b are both true. Else returns false. Both expressions a and b are always evaluated.

  • | (OR) - Example: a | b - returns true if a or b for true. Else it returns false. Both expressions a and b are always evaluated.

  • ^ (OR exclusive) - Example: a ^ b - returns true if a for true and b is false or vice versa. Otherwise false

You can also do a line-by-line check by reusing the returnValue:

boolean returnValue;

returnValue = !entry.isDirectory();
returnValue = returnValue &&!entry.getName().startsWith("__MACOSX/");
returnValue = returnValue &&!entry.getName().startsWith("_images/");
returnValue = returnValue &&!entry.getName().contains("/_images");
returnValue = returnValue &&!entry.getName().contains("/._");
returnValue = returnValue &&!entry.getName().contains("/_img");
returnValue = returnValue &&!entry.getName().contains("/imgs");
returnValue = returnValue &&!entry.getName().contains("/_old");

if (returnValue) {
    String filename = Util.buildFilename(nome);
...

In my view this second example is easier to maintain.

Browser other questions tagged

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