Databases, Middleware, and Other Third-Party Interfaces


Third-party APIs are a fact of life for software engineers. We buy database engines, middleware engines, class libraries, threading libraries, and so on. Initially, we use these APIs by making direct calls to them from our application code (see Figure 34-5).

Figure 34-5. Initial relationship between an application and a third-party API


Over time, however, we find that our application code becomes more and more polluted with such API calls. In a database application, for example, we may find more and more SQL strings littering the code that also contains the business rules.

This becomes a problem when the third-party API changes. For databases, it also becomes a problem when the schema changes. As new versions of the API or schema are released, more and more of the application code has to be reworked to align with those changes.

Eventually, the developers decide that they must insulate themselves from these changes. So they invent a layer that separates the application business rules from the third-party API (see Figure 34-6). They concentrate into this layer all the code that uses the third-party API and all the concepts that related to the API rather than to the business rules of the application.

Figure 34-6. Introducing an insulation layer


Such layers, such as ADO.NET can sometimes be purchased. They separate the application code from the database engine. Of course, they are also third-party APIs in and of themselves, and therefore the application may need to be insulated even from them.

Note that there is a transitive dependency from the Application to the API. In some applications, that indirect dependence is still enough to cause problems. ADO.NET, for example, does not insulate the application from the details of the schema.

In order to attain even better insulation, we need to invert the dependency between the application and the layer (see Figure 34-7). This keeps the application from knowing anything about the third-party API, either directly or indirectly. In the case of a database, it keeps the application from direct knowledge of the schema. In the case of a middleware engine, it keeps the application from knowing anything about the data types used by that middleware processor.

Figure 34-7. Inverting the dependency between the application and the layer


This arrangement of dependencies is precisely what the PROXY pattern achieves. The application does not depend on the proxies at all. Rather the proxies depend on the application, and on the API. This concentrates all knowledge of the mapping between the application and the API into the proxies.

This concentration of knowledge means that the proxies are nightmares. Whenever the API changes, the proxies change. Whenever the application changes, the proxies change. The proxies can become very difficult to deal with.

It's good to know where your nightmares live. Without the proxies, the nightmares would be spread throughout the application code.

Most applications don't need proxies. Proxies are a heavyweight solution. When I see proxy solutions in use, my recommendation in most cases is to take them out and use something simpler. But sometimes, the intense separation between the application and the API afforded by proxies is beneficial. Those cases are almost always in very large systems that undergo frequent schema and/or API thrashing, or in systems that can ride on top of many different database engines or middleware engines.

Figure 34-8. How the Proxy inverts the dependency between the application and the layer





Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net