Gamma – Helm - Johnson – Vlissides
Abstract Factory (68) and Builder (75) yield objects whose only responsibilities are creating other objects.
Visitor (259) and Command (182) yield objects whose only responsibilities are to implement a request on
another object or group of objects.
Specifying Object Interfaces
Every operation declared by an object specifies the operation's name, the objects it takes as parameters, and the
operation's return value. This is known as the operation's signature. The set of all signatures defined by an
object's operations is called the interface to the object. An object's interface characterizes the complete set of
requests that can be sent to the object. Any request that matches a signature in the object's interface may be sent
to the object.
A type is a name used to denote a particular interface. We speak of an object as having the type "Window" if it
accepts all requests for the operations defined in the interface named "Window." An object may have many
types, and widely different objects can share a type. Part of an object's interface may be characterized by one
type, and other parts by other types. Two objects of the same type need only share parts of their interfaces.
Interfaces can contain other interfaces as subsets. We say that a type is a subtype of another if its interface
contains the interface of its supertype. Often we speak of a subtype inheriting the interface of its supertype.
Interfaces are fundamental in object-oriented systems. Objects are known only through their interfaces. There is
no way to know anything about an object or to ask it to do anything without going through its interface. An
object's interface says nothing about its implementation—different objects are free to implement requests
differently. That means two objects having completely different implementations can have identical interfaces.
When a request is sent to an object, the particular operation that's performed depends on both the request and
the receiving object. Different objects that support identical requests may have different implementations of the
operations that fulfill these requests. The run-time association of a request to an object and one of its operations
is known as dynamic binding.
Dynamic binding means that issuing a request doesn't commit you to a particular implementation until run-time.
Consequently, you can write programs that expect an object with a particular interface, knowing that any object
that has the correct interface will accept the request. Moreover, dynamic binding lets you substitute objects that
have identical interfaces for each other at run-time. This substitutability is known as polymorphism, and it's a
key concept in object-oriented systems. It lets a client object make few assumptions about other objects beyond
supporting a particular interface. Polymorphism simplifies the definitions of clients, decouples objects from
each other, and lets them vary their relationships to each other at run-time.
Design patterns help you define interfaces by identifying their key elements and the kinds of data that get sent
across an interface. A design pattern might also tell you what not to put in the interface. The Memento (221)
pattern is a good example. It describes how to encapsulate and save the internal state of an object so that the
object can be restored to that state later. The pattern stipulates that Memento objects must define two interfaces:
a restricted one that lets clients hold and copy mementos, and a privileged one that only the original object can
use to store and retrieve state in the memento.
Página 18