[In part, this addresses some of MartinLippert's questions from RefactoringFrameworkBasedApplications.]
Forces:
- You have to deal with an interface that you find objectionable, inconvenient, or inappropriate -- it may not be well designed to meet your particular needs.
- You can't change the interface because the system "on the other side" of the interface is on a different release schedule: It may be maintained by some other independent group in your company, it may be a 3rd party purchased vendor product, or it may be a framework in use by a number of projects -- not just yours.
Solution:
- Put a layer of abstraction between yourself and the parts of the interface that display the greatest ImpedanceMismatch with your code.
Particulars:
If you inherit from an excessively large interface, having a "split personality" of functionality, then ExtractClass each logical piece of functionality.
- Seen in RefactoringWithDesawareNtServiceToolkit, where the IdwEasyService? interface you must implement includes both service control (start/stop/pause/resume) and scheduling (timer) interfaces (and one or two others): Extract the functionality of interest to your application to separate control and scheduler classes; you can control the interfaces of these classes.
If you must work with an excessively complicated and robust interface that does much more than you need, build a simple adaptor for your use that hides the complexity of the full interface. (
AdapterPattern)
This is commonly an issue with database interfaces like ADO, DAO, RDO, ODBC and JDBC; each of these interfaces can and should be able to do much more than just the things you need to do for any particular application.
- Seen in RefactoringWithComPlusTechnologies, where the framework gives no particular support for interfacing with the database, making room for an entire library or framework to be introduced at that end. The framework is also weak on the business objects end, suggesting CodeGeneration or creative use of COM metadata for data driven processing -- another strong opportunity for code reuse building up to a full library or framework.
Results:
This approach can very easily lead to a
LayeredApplicationFramework, where you build custom framework(s) to meet your needs on top of existing frameworks that are somewhat resistant to change.
CategoryAbstraction