Genealogical module A genealogical system may represent relationships between people as a graph of direct relationships between them (father-son, father-daughter, mother-son, mother-daughter, husband-wife, wife-husband, etc.). This is very efficient and extensible, as it is easy to add an ex-husband or a legal guardian. But some higher-level modules may require a simpler way to browse the system: any person may have children, parents, siblings (including half-brothers and -sisters or not), grandparents, cousins, and so on. Depending on the usage of the genealogical module, presenting common relationships as distinct direct properties (hiding the graph) will make the coupling between a higher-level module and the genealogical module much lighter and allow changing the internal representation of the direct relationships completely without any effect on the modules using them. It also permits embedding exact definitions of siblings or uncles in the genealogical module, thus enforcing the
single responsibility principle. Finally, if the first extensible generalized graph approach seems the most extensible, the usage of the genealogical module may show that a more specialized and simpler relationship implementation is sufficient for the application(s) and helps create a more efficient system. In this example, abstracting the interaction between the modules leads to a simplified interface of the lower-level module and may lead to a simpler implementation of it.
Remote file server client A remote file server (FTP, cloud storage ...) client can be modeled as a set of abstract interfaces: • Connection/Disconnection (a connection persistence layer may be needed) • Folder/tags creation/rename/delete/list interface • File creation/replacement/rename/delete/read interface • File searching • Concurrent replacement or delete resolution • File history management ... If local and remote files offers the same abstract interfaces, high-level modules that implement the dependency inversion pattern can use them indiscriminately. The application will be able to save its documents locally or remotely transparently. The level of service required by high level modules should be considered. Designing a module as a set of abstract interfaces, and adapting other modules to it, can provide a common interface for many systems.
Model–view–controller UI and ApplicationLayer packages contain mainly concrete classes. Controllers contains abstracts/interface types. UI has an instance of ICustomerHandler. All packages are physically separated. In the ApplicationLayer there is a concrete implementation of CustomerHandler that Page class will use. Instances of the ICustomerHandler interface are created dynamically by a Factory (possibly in the same Controllers package). Concrete types Page and CustomerHandler depend on ICustomerHandler, not on each other. Since the UI doesn't reference the ApplicationLayer or any other concrete package implementing ICustomerHandler, the concrete implementation of CustomerHandler can be replaced without changing the UI class. Also, the Page class implements interface IPageViewer which could be passed as an argument to ICustomerHandler methods, allowing the concrete implementation of CustomerHandler to communicate with UI without a concrete dependency. Again, both are linked by interfaces. ==Related patterns==