I was wondering if someone would clarify a section of the textbook I have referred to in the subject line.
Head First Design Patterns refers to the following block of code, and makes some confusing statements about the nature of this code block. The code block is actually an example of poor object oriented design. The following comments were made in the textbook concerning this code block:
(1) This version of DependentPizzaStore depends on all those pizza objects, because it's creating them directly.
(2) If the implementations of these classes change, then we may have to modify DependentPizzaStore.
(3) Because any changes to the concrete implementations of pizzas affects the DependentPizzaStore, we say that the DependentPizzaStore "depends on" the pizza implementations.
(4) Every kind of pizza we add creates another dependency for DependentPizzaStore.
Do you agree with the following statement?
With the exception of changes to the Pizza subclass constructors, the implementations of the Pizza subclasses can be changed at will without having any effect on the DependentPizzaStore. The DependentPizzaStore doesn't depend upon the pizza implementations(?)
Yes, I do partially agree with your statement, as far as it goes, in the context of this specific code; but note that this is due to the specific properties of the Java language, and not to OO theory. The classic discussion of this kind of dependency has been in a C++ context, and in that language, other changes -- such as adding or removing member variables -- would necessitate recompiling the factory as well. So in the general abstract case, the book's stricter claim is valid.
Now, there's another level to this, and this is why I said "partially". Besides the constructor signatures themselves, you can't rename any of the (ostensibly privately-named) pizza classes without recompiling the factory, and you can't add new types or new categories, either. In other words, all the knowledge about what sort of pizza each class represents is (please forgive me!) "baked in" to this class. These are all also undesirable characteristics. I don't have this book, so I don't know where this example is going, but one can definitely design a system in which the factory looked on the classpath for pizza classes, and then queried the pizza classes to build the hierarchy at runtime, so that there'd be no dependencies at all.
Ernest Friedman-Hill wrote:adding or removing member variables -- would necessitate recompiling the factory
I wasn't aware of the this C++ dependency.
If the method calls in the body of the DependentPizzaStore are moved to a separate class and Pizza creation is delegated solely to the DependentPizzaStore class, then the implementation of the DependentPizzaStore class becomes a SimpleFactoryMethod implementation (as described earlier in the textbook). The fact that the pizza class utility methods are combined with the pizza class creation methods is the only thing that contradicts the Java Factory Idiom (this is explicitly referenced in the textbook. The Java Factory Idiom and the Factory Method Pattern are differentiated in the textbook).
Anyway, it was interesting to read your opinion on the matter. Thanks.