> [Pattern 1] Solution: Split the method into two new methods. Voilà, the if is gone.
And so is parametrization.
> [Pattern 2]: Solution: Use Polymorphism. Anyone introducing a new type cannot forget to add the associated behaviour.
OTOH you make extensions more complex. I usually write in lisp and DO NOT use polymorphism for this but etypecase in the base implementation of a method (switch/case where the default case automatically throws an error). This allows people who extend my code to implemented a method specific to a type that my base implementation handles and thereby overriding my implementation with minimal effort.
> [Pattern 3]: Solution: Use a NullObject or Optional type instead of ever passing a null. An empty collection is a great alternative.
This is, IMHO, not relevant at all - the decision how null values are handled simply has to be documented so programmers can make an informed choice. The only exception I accept is an empty collection which I'll always prefer over null, assuming that all other code handles empty collections gracefully.
> [Pattern 4]: Solution: Simplify the if statements into a single expression.
Works for the contrived example (and we all know that the code is really bad). For more complex code I rather follow the logic line by line instead of mentally disassembling a 10 line boolean expression.
> [Pattern 5]: Solution: Give the code being called a coping strategy.
No, just no. One does not aim at removing exceptions. Those are to be handled by a higher layer who actually knows how to handle it. If one uses default values one still has to check on that layer with the added burden of using a default value that is guaranteed to never be returned as a real value so we can make the distinction between record found/record not found.