More on this book
Kindle Notes & Highlights
Design patterns are little spring-loaded solutions to common programming problems. Ideally, when the appropriate problem comes along, you should trigger the design pattern and your problem is solved. It is that first part—the bit about waiting for the appropriate problem to come along—that some engineers have trouble with. You cannot say that you are correctly applying a design pattern unless you are confronting the problem that the pattern is supposed to solve.
A key goal of software engineering is to build systems that allow us to contain the damage.
If your introduction to object-oriented programming was like mine, you spent 10 minutes on information hiding, 22 minutes on scope and visibility issues, and the rest of the semester talking about inheritance.
Frequently, the base class will define hook methods solely to let the concrete subclass know what is going on.
The Template Method pattern is at its best when it is at its leanest—that is, when every abstract method and hook is there for a reason. Try to avoid creating a template class that requires each subclass to override a huge number of obscure methods just to cover every conceivable possibility.
The ducks would argue (quack?) that HtmlFormatter and PlainTextFormatter already share a common interface because both implement the output_report method. Thus there is no need to artificially grind in the point by creating what is essentially a do-nothing superclass.
An extremely useful aspect of the Proc object is that it picks up the surrounding environment when it is created. Thus any variables that are visible when a Proc is created remain visible inside the Proc when it is run.
We can do so by adding a special parameter to the end of our parameter list. This special parameter, which is preceded by an ampersand, is assigned the Proc object created from the code block that came after the method call.
The ampersand works in the other direction, too. If we have a Proc object in a variable and we want to pass it to a method that is looking for a code block, we can convert the Proc object back into a code block by sticking an ampersand in front of it:
Does all of this mean we should just forget about the class-based strategies? Not really. Code block-based strategies work only when the strategy interface is a simple, one-method affair. After all, the only method that we can call on a Proc object is call. If you need more than that for your strategy, by all means build some classes.
a.sort { |a,b| a.length <=> b.length }
As we shall see in coming chapters, the Strategy pattern resembles, at least superficially, several other patterns. For example, in the Strategy pattern we have an object—the context—that is trying to get something done. But to get that thing done, we need to supply the context with a second object—the strategy object—that helps get the thing done. Superficially, the Observer pattern works in much the same way: An object does something, but along the way it makes calls to a second object, which we need to supply.
The Ruby standard library comes with a fine, prebuilt Observable module that provides all of the support you need to make your object, well, observable.
the notify_observers method will not actually make any notifications if the changed flag is not set to true. Each call to notify_observers sets the changed flag back to false.
The difference is mostly one of intent. In the case of the observer, we are informing the other object of the events occurring back at the observable. In the case of the strategy, we are getting the strategy object to do some computing.
The Observer pattern also serves more or less the same function as hook methods in the Template Method pattern; both are there to keep some object informed of current events. The difference is, of course, that the Template Method pattern will only talk to its relatives: If you are not a subclass, you will not get any news from a Template Method pattern hook.
If you look around for real examples of the Composite pattern in the Ruby code base, the graphical user interface (GUI) libraries jump out. All modern GUIs support a pallet of basic components, things like labels and text fields and menus.
JDBC includes ResultSet, which allows us to iterate over each row in a SQL query result. This style of iterator is sometimes referred to as an external iterator—“external” because the iterator is a separate object from the aggregate.
The each method is the explanation for all of those funny-looking each loops that you have been seeing in this book. Those loops are not, in fact, actual “built-into-the-language” loops, but rather applications of internal iterators.
To mix in Enumerable, you need only make sure that your internal iterator method is named each and that the individual elements that you are going to iterate over have a reasonable implementation of the <=> comparison operator. For
The main danger is this: What happens if the aggregate object changes while you are iterating through it?
use ObjectSpace to implement your own memory profiling system: Simply start a thread that looks for the objects of interest and prints a report about them.
In the world of Ruby code blocks and Proc objects, are hand-coded command classes like our SaveCommand class passé? Not really—it all depends on the complexity of the job at hand. If you simply want a command that executes some straightforward actions when it is run, by all means use a Proc object. But if you are doing something fairly complex, if you need to create a command that will carry around a lot of state information or that naturally decomposes into several methods, by all means create a command class.
Madeleine relies on the Ruby Marshal package, a facility for converting live Ruby objects into bytes and for turning those bytes back into objects.
A command object simply knows how to do something, but is not particularly interested in the state of the thing that executed it. Conversely, an observer is intensely interested in the state of the subject, the thing that called it.
The key bit of syntax in this code is this line: class << bto Essentially, this code is an instruction to modify the behavior of the bto object independently of its class. You can achieve the same effect with a different syntax by simply defining the methods on the instance:
Lean toward an adapter solution in the following situations: The interface mismatch is extensive and complex. For example, you probably would not want to modify a string to look like a Fixnum object. You have no idea how this class works. Ignorance is always cause to tread lightly.
Partially implemented adapters are something of a double-edged sword: On the one hand, it is very convenient to implement only what you absolutely need; on the other hand, your program can come to grief if the client decides to call a method that you didn’t think you needed.
At the risk of repeating myself, keep in mind that a pattern is not just about code: Intent is critical. An adapter is an adapter only if you are stuck with objects that have the wrong interface and you are trying to keep the pain of dealing with these ill-fitting interfaces from spreading throughout your system.
From the client’s point of view, it called a method on what it thought was the real BankAccount object and sometime later—perhaps an unusually long time later—the answer came back. This is how virtually all remote procedure call (RPC) systems work.
In a sense, the virtual proxy is the biggest liar of the bunch. It pretends to be the real object, but it does not even have a reference to the real object until the client code calls a method. Only when the client actually calls a method does the virtual proxy scurry off and create or otherwise get access to the real object.
The beauty of the method_missing method is that by implementing it in your class, you can build classes that can catch any arbitrary method—or, should I say, message—that comes down the road and do whatever seems correct in that situation.[3] This is message passing.
the method_missing version will run somewhat more slowly. On my machine, the first, traditionally written class runs about 10 percent faster than calling add on the second version and letting the unknown method fall through to method_missing.
We could eliminate all of this boring code with a variation on the method_missing technique that we learned in Chapter 10, but the forwardable module is probably a better fit. The forwardable module will automatically generate all of those dull delegating methods for us with very little effort.
In particular, we can obtain most of that decorator goodness either by dynamically wrapping methods or via module decorations.
It offers an alternative to creating a monolithic "kitchen sink" object that supports every possible feature or a whole forest of classes and subclasses to cover every possible combination of features. Instead, with the Decorator pattern, you create one class that covers the basic functionality and a set of decorators to go with it. Each decorator supports the same core interface, but adds its own twist on that interface.
Pity the poor Singleton pattern. Even coders who do not know very much about patterns know about the singleton. Mainly they know one thing: Singletons are Bad, with a capital "B".
Personally, I like the self format, because you have less to change if you rename the class or transplant code to another class.
The detail is that by adding the private_class_method call, we have done exactly what the name suggests: We made the new class method private, preventing any other class from creating new instances of our logger.
The point is not that this kind of thing is a good idea, but rather that in a language where virtually everything done at runtime can be undone a little later in runtime, very few decisions are irreversible. The Ruby philosophy is that if you decide to circumvent the very clear intent of the author of the ClassBasedLogger class by cloning it, the language is there to help you out.
A singleton bears a very strong family resemblance to its outlaw cousin, the global variable.
There is only one solution to this problem: Don’t do that. Properly applied, singletons are not global variables. Rather, they are meant to model things that occur exactly once.
The Singleton pattern is a bit like that ancient table saw that my dad used to have. That saw was incredibly effective at cutting lumber, but, since it had very few safety features, it was equally adept at slicing an unwary hand in two.
If you stare at Figure 13-1 long enough, you may discover that the Factory Method pattern is not really a new pattern at all. At its heart, this pattern is really just the Template Method pattern (remember Chapter 3?) applied to the problem of creating new objects.
An object dedicated to creating a compatible set of objects is called an abstract factory.
In the same way that the Factory Method pattern is really the Template Method pattern applied to object creation, so the Abstract Factory pattern is simply the Strategy pattern applied to the same problem.
If you have a choice of exactly one class at the moment, put off adding in a factory.
The most prominent examples of magic methods are the finder methods in ActiveRecord. In exactly the same way that our last computer builder allowed us to specify computer configurations with the name of the method we call, ActiveRecord allows us to encode database queries.
Also, think about who will be writing programs in your new language. Will these programmers be experienced software engineers, who will be able to get along with minimal error messages, or will your users be less technical civilians, who may need more elaborate diagnostics?
The heart of the Interpreter pattern is the abstract syntax tree.

