Let's take a break for a moment from improving Wizbang Widget's testability and adherence to good design principles, so we can start to see some reasons why good design principles pragmatically matter.
ACME hasn't been doing very well over the past few years. Their algorithm for determining if a Thing conforms to industry rules is the best in the business; but over the past few years, the following shifts have occurred:
- In the business climate that ACME started out in, it was of paramount importance to know with as much certainty as possible whether a Thing conforms to industry rules. While this is still important, over the past few years, due to regulatory and industry changes, it is no longer of such paramount importance as it used to be. This has reduced the competitive advantage to ACME of having its advanced algorithm.
- There are other industries that work very similarly to ACME's industry, but they have different rules for determining if a Thing conforms.
- When ACME started out, all that could be done with a Thing is to Poke It With A Pointed Stick and see what noise it made; however, in the past few years, many new and innovative things to do to a Thing have emerged in the marketplace, each making a different set of noises to record.
- The importance of determining what noise a Thing makes when Poked With A Pointed Stick, as well as when other things are done to it, has increased in the industry and marketplace relative to determining whether a Thing conforms to industry rules. ACME's algorithm for this is sufficient, but not noteworthy in the industry.
So ACME's Board and CEO have recognized that if ACME doesn't figure something out, the company's prospects will continue to decline until eventually it will face some sort of unsavory fate: going out of business, massive layoffs and being sold at firesale prices, etc. So it's clear to them that now is the time to take action, and it's pretty clear that the best course to pursue is a merger of one sort or another with another company. What ACME brings to the table is their algorithm for determining if a Thing conforms to industry standards.
Enter AcquiCorp. AcquiCorp's specialty is finding and buying businesses like ACME, integrating their products together into Best-Of-Breed products, and marketing them across industries with similar needs. AcquiCorp is very interested in ACME's algorithm for determining a Thing's conformance to industry standards in the DoItAll industry; however, they are hesitating to make an offer because ACME's product is very
monolithic and will be hard to integrate. The ACME CEO and the Board have taken this as a cue to make ACME's product more integrable, and have challenged to team to do so in the next six months.
Take a look at AcquiCorp's application, in the solution RuntimeCompositionApplication. The team's goal is to make the Wizbang Widget integrable with this product. Note that AcquiCorp's application, since it stresses integrability, is big on Runtime Composition. Notice how the dependencies have been abstracted out into interfaces*. They have identified a method, EvaluateAndReport, which seems to be how it's done in the industry (this is very equivalent to ACME's 'DoItAll' method). So they identified an interface, IThingEvaluatorAndReporter, which any integrated component needs to implement. They already have a component, Protocol1EvaluatorAndReporter, which contains an inferior algorithm for determining if a Thing conforms to industry standards, but has the advantage of being integrable. Notice that Protocol1EvaluatorAndReporter makes no assumptions whatsoever about what components it's going to use for its dependencies; via constructor injection, it allows the client to make those decisions at runtime (Runtime Composition). Thus Protocol1EvaluatorAndReporter can be dropped into any application that needs its services, without having to change Protocol1EvaluatorAndReporter, and with the only changes necessary to the client application being those to use Protocol1EvaluatorAndReporter for its services.
Don't worry right now about Protocol 2 or the MuchBetterWizbangFolder under Adapters (Look away from Protocol 2!!! Look away from MuchBetterWizbangFolder!!! There is no man behind the curtain!!) Later we're going to have an exercise for you, and Protocol 2 and MuchBetterWizbangFolder will be involved in that.
*If or when AcquiCorp becomes interested in reducing the coupling here to the bare minimum, they will pull the interfaces out into their own component. Thus any class wanting to implement those interfaces will not have to reference the client Application (i.e. referential coupling, or the necessity for a client to have references to a class it will never use, will be reduced). However, also notice the 'Adapters' folder (which is empty at the moment), which indicates AcquiCorp's intention to use adapters for acquired components that adhere to SOLID Principles, helping in many cases to eliminate the need for components to have any knowledge whatsoever of AcquiCorp's application. The latter strategy is preferable, and there are even more preferable strategies that involve both techniques.