Sponsored Link •
To actually provide a service to people, a machine must have more than just an interface. It must have an implementation, a mechanism by which the machine actually provides the service. One of the fundamental notions of object oriented programming is a strong separation of interface and implementation. You can see this separation in many traditional machines as well.
One of the main reasons to separate interface and implementation is to hide complexity from the user. If you peel the back off a stamp dispenser, you'll find a nest of wires, circuit boards, chips, and motors. That is the implementation of the stamp dispenser. Normally, all that complexity is hidden from the user. The wires and circuit boards of the stamp dispenser are encased in a box that exposes only buttons, displays, a coin slot, and a change return lever. The complex implementation is hidden. A simpler interface is exposed.
An interface can be simpler than its implementation, because the interface can operate at a higher level of abstraction. If you insert 20 cents into a stamp dispenser and push the button underneath a 20 cent stamp, you expect a 20 cent stamp to come out. As a user, you don't need to understand how that will happen, only what will happen—that you'll get a 20 cent stamp. You don't need to know the details of all the activities inside the stamp dispenser. You need only think in far simpler terms of "a 20 cent stamp will come out."
Raising the level of abstraction in the interfaces of objects you design is an important way to help client programmers, your users, deal with the overall complexity of their systems. The interfaces say what will happen. The implementations say how. Programmers can think about the complex behavior of their systems in terms of its object parts and the interaction between them. The more that programmers can ignore implementation details of objects—the more the object interfaces abstract those details away—the more overall system complexity they can deal with.
The interface to any machine has two parts: shape and semantics. By shape, I mean the way in which the various elements of the interface present themselves to the user. By semantics, I mean the meaning of the various elements of the interface. It is not enough that users can see all the knobs and buttons in an interface: the shape. They also need to know what the knobs and buttons mean: the semantics. To use a machine effectively and safely, users need some understanding of the machine. They need to become familiar with both the shape of its human interface and its semantics. They need to build a mental model of what the machine does when they interact with the various elements of its shape.
One concern the designers of any machine should have is communicating semantics to users. Users need to learn what service the machine will provide when they push a button or turn a knob. They need to learn any rules surrounding the use of the buttons and knobs. If a user must flip a switch hidden underneath the steering wheel of her new car before she can turn the key and start the engine, she needs to know that. If the little red button next to the cigarette lighter in her new car causes the front passenger to be ejected out the sun roof, she need to know that too. Communicating semantics is not something to think about after you complete a design. It should be one of your main concerns while you design.
Three main ways to communicate semantics to users are shape, manuals, and training. The most important way to communicate the semantics of an interface is via the shape itself. To the extent possible, users should be able to intuit semantics from the look, feel, and labels of the interface elements. Semantics that are difficult to communicate via the shape, or dangerous or costly to learn by trial and error, can be explained in writing via a manual or in person via a training class. The reason that shape is the most important strategy for communicating semantics to users is because shape is the way most users figure out how to use most machines. Even if someone does read the manual or take a class at some point, they will often have forgotten what they learned the next time they use the machine. The shape is the one thing you know is in front of a user every time they use the machine, because the shape is how they use the machine.
An API's shape is the names of its types, fields and methods, and their modifiers and parameters. An API's semantics is the meanings of the pieces that make up the shape: the concepts represented by the types, what the methods do when you invoke them, what the values of fields mean, and so on. Why is it important to design types and methods that are cohesive, and to choose names that are pithy and descriptive? Because that's how you enable users to intuit the semantics of your API from its shape. At its heart, this aspect of design is about human to human communication. As the designer, you must transfer your understanding of the API's semantics to your users.