This boils down to composition vs. inheritance.
Let's take a look at one pattern that you can do in both ways.
adapter pattern is, as the name implies, an adapter between two classes that are otherwise incompatible.
Say you write a 3D engine and you need a
Point class. You have your
Point all ready and it kind of works, but then you find another class
OtherPoint in some library that does everything your class should be doing in a nicer way, but its methods have different names. Your 3D engine expects your
What can you do to make both classes compatible in order to use
Point extends OtherPoint inheritance for the win.
Point receives all the functionality it needs. The methods specific to your engine that
Point declares simply call the corresponding ones from
OtherPoint. This is the class pattern style of the adapter.
- On the other hand, you could do
Point(OtherPoint constructorParameter) to receive an
OtherPoint object. The idea is similar: the
Point methods now don't delegate to the methods it received via inheritance but to the object it received as a parameter in the constructor. This is the object pattern style of the adapter. This is a comparable to the wrapper pattern.
How does that explain the GoF statement(s)?
"Class patterns [...] are static-fixed at compile-time.
Point extends OtherPoint you say that a
Point is a
OtherPoint. It's a plain old simple inheritance chain. You cannot change them at run time.
Object patterns [...] which can be changed at run-time and are more dynamic
Point(OtherPoint constructorParameter) you say that a
Point has a
OtherPoint. Maybe you find out that this library has an even fancier class, i.e.
FancierOtherPoint extends OtherPoint. You can pass that to
Point as well. In fact you can pass any sublcass of
Point, because of polymorphism.
FancierOtherPoint only works on certain hardware and you have to check for that hardware at run time. With the object pattern style of the adapter, you can do exactly that: decide dynamically what class to use.
I've never heard of "object relationships" outside of this book.
"object relationships" is not special phrase. It means exactly what is says: relationships between objects. Design patterns are just names for common ways to define relationships between objects.
If I were to say "3.14159265359..." you'd probably stop me to ask if I mean "pi". Now if you were to tell me you "inherit from that one class to make things compatible and delegate methods and..." I would stop you to ask if you mean the adapter pattern.
It simplifies communication and everybody has a rough understanding of what the conversation is about without explaining everything in full detail.