When factoring interfaces, most approaches fall into one of two patterns: Header Interfaces or Role Interfaces. This post will contrast the two patterns with the hope of giving insight into the strengths and weaknesses of interface factoring.
One interface contains all public members for a class. Similar to C++ header files.
Header interfaces are easy to create but aren’t always the easiest to understand or maintain.
- Very easy to make
- New members on GroceryStore will likely need to be added to IGroceryStore as well.
- Semantics of code aren’t always clear
A class is broken into many interfaces. Each interface represents a different role:
This pattern is harder to implement than header interfaces, but often pays off by being more understandable and easier to maintain. The challenge comes from having many small interfaces instead of one big interface, since there are often many sensible ways to create the “role” interfaces. For example, another option for the sample code could have have been an ICheckout with all sale methods and an ICustomerService with all refund methods.
- Easier to know exactly what you need to mock out for testing
- More clear what a method’s purpose is (e.g. void CloseRegisters(ITally tally))
- Harder to make than the Header Interface
- If project changes considerably might need to rename/reorganize interfaces