Do Patterns Make Code More Complex?
One team I worked with included programmers who knew patterns and programmers who didn't know patterns. Bobby knew patterns well and had ten years of programming experience. John had little exposure to patterns and had four years of programming experience.
One day John looked over a significant refactoring Bobby had completed and exclaimed, "I liked the code better before! Now the code is way more complex!"
Bobby had refactored a large amount of conditional logic associated with validating data entry screens. His refactoring led him to the Composite pattern. Bobby had converted many pieces of validation logic into separate validation objects, all of which shared the same interface. For a given data entry screen, the appropriate validation objects were now assembled into a single Composite validation object. At runtime, a data entry screen's Composite validation object would be queried to discover which validation rules passed or failed.
I happened to be pair-programming with John when he expressed his discontent with Bobby's refactoring. I wanted to understand the root of John's discontent, so I asked John some questions. I quickly learned that John was not familiar with the Composite pattern. That explained a lot.
John was open to learning the Composite pattern when I offered to teach it to him. After I felt that he had grasped the pattern, we went back to looking over Bobby's refactored code. I then asked John whether he felt differently about the refactoring. Reluctantly, he agreed that the code wasn't as complex as he had thought, yet he didn't go so far as to say it was better than the previous code.
From my perspective, Bobby's refactoring represented a vast improvement over the previous code. Bobby had removed large chunks of conditional logic and duplicate code in classes associated with data entry screens. He had also dramatically simplified the way to discover passing and failing validation rules.
My own comfort and familiarity with the Composite pattern influenced my perspective on Bobby's refactoring. Unlike John, I found the refactored code to be simpler and cleaner than the previous code.
In general, pattern implementations ought to help remove duplicate code, simplify logic, communicate intention, and increase flexibility. However, as this story reveals, people's familiarity with patterns plays a major role in how they perceive patterns-based refactorings. I prefer that teams learn patterns rather than avoid using them because the teams view patterns as being too complex. On the other hand, some pattern implementations can make code more complex than it needs to be; when that happens, backtracking or more refactoring is necessary.