Friday, January 31, 2020

Reduce Excessive Nesting



https://www.veracode.com/blog/secure-development/avoiding-nested-try-catch-java
Extracting the nested part as a new method will always work for any arbitrarily nested Try-Catch-Finally block. So this is one trick that you can always use to improve the code.

return early
https://www.codeproject.com/Articles/626403/How-and-Why-to-Avoid-Excessive-Nesting

Replace Nested Conditional with Guard Clauses
https://refactoring.guru/replace-nested-conditional-with-guard-clauses

Isolate all guard clauses that lead to calling an exception or immediate return of a value from the method. Place these conditions at the beginning of the method.

After rearrangement is complete and all tests are successfully completed, see whether you can use Consolidate Conditional Expression for guard clauses that lead to the same exceptions or returned values.


https://testing.googleblog.com/2017/06/code-health-reduce-nesting-reduce.html
The refactoring technique shown above is known as guard clauses. A guard clause checks a criterion and fails fast if it is not met. It decouples the computational logic from the error logic. By removing the cognitive gap between error checking and handling, it frees up mental processing power. As a result, the refactored version is much easier to read and maintain.

Here are some rules of thumb for reducing nesting in your code:

  • Keep conditional blocks short. It increases readability by keeping things local.
  • Consider refactoring when your loops and branches are more than 2 levels deep.
  • Think about moving nested logic into separate functions. For example, if you need to loop through a list of objects that each contain a list (such as a protocol buffer with repeated fields), you can define a function to process each object instead of using a double nested loop.
https://www.drdobbs.com/architecture-and-design/refactoring-deeply-nested-code/231500074
https://dzone.com/articles/code-smells-deeply-nested-code
    public MappedField getMappedField(final String storedName) {
        for (final MappedField mf : persistenceFields) {
            for (final String n : mf.getLoadNames()) {
                if (storedName.equals(n)) {
                    return mf;
                }
            }
        }
        return null;
    }


This what the Law of Demeter warns us against, therefore suggests to me we consider a tell-don’t-ask approach.  Wouldn’t it be prettier to ask mappedField if one of its names matched the name we wanted?
    public Optional<MappedField> getMappedField(final String storedName) {
        return persistenceFields.stream()
                                .filter(mf -> mf.hasName(storedName))
                                .findFirst();
    }
Symptoms:
  • Deeply nested code, usually loops and/or conditionals
  • Chained method calls that are all getters (or other non-builder, non-DSL method chains).
Possible solutions:
  • Consider tell, don’t ask. Where the code previously grabbed internal data and did checks against it, move those checks into the object containing the data and create a method with a useful name to help other objects answer their questions.
  • Examine your encapsulation. Does the data really need to leak out into other classes? Should data and/or responsibilities be relocated so that operations on the data are moved closer to the data itself?
  • Collection Encapsulation. Sometimes this pattern is a sign that you’re using a data structure as a domain object.  Consider encapsulating this data structure (Collection, array, etc) inside a domain object of its own and adding helper methods to let other objects ask it questions rather than poke around its internals.


    public Optional<MappedField> getMappedField(final String storedName) {
        return persistenceFields.stream()
                                .filter(mf -> mf.hasName(storedName))
                                .findFirst();
    }



Refactoring with Cognitive Complexity
https://resources.sei.cmu.edu/asset_files/Presentation/2017_017_001_497517.pdf

Control flow statements "if", "for", "while", "switch" and "try" should not be nested too deeply
https://rules.sonarsource.com/java/RSPEC-134

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts