Sponsored Link •
Bill Venners: That fits with how I think about design. The first guideline in my book Object Design is: Design objects for people, not for computers. I talk about programmers as users and APIs as user interfaces. I make the point that you are not just designing software for a computer to execute, but also for other programmers to understand and use. I've found that the main thing that makes a design good is that it is easy for people (other programmers) to understand and use.
Ken Arnold: It takes a lot more work to understand the other person than it takes to understand you. You might say, "I have these two things together so I will let the user—the person using the API—manipulate them." But that user didn't say, "Hey, I want to manipulate these two data structures!" Often the user is saying, "I want to get this result." If users could get a result without manipulating the data structures, they'd be happy as clams. If you can make it more natural for them to get that result, the fact that you have to go through 10 times as much work to access those data structures is good; it means you are providing value. Many people are much more likely to think about what they have in hand and what they can do. They think from the implementation out, instead of thinking from the user in.
To me, thinking from the user in is the designer's job. If you just want to implement, you should work for somebody who knows how to design. If you want to design, you have to ask, "Who am I designing for? What do they want to accomplish? And what do they have at their disposal to accomplish it?"
Does the user already think of this parameter as an image or a data stream? If the user thinks of it as a data stream and you think of it as an image, then that is your problem not theirs. They should hand you a data stream, and you should do whatever you need to do given a data stream.
Or maybe it is the other way around. If you look at Jini, many times you will hand
something to the Jini APIs that can't be
transmitted across the network as is. Some methods of the lookup service, for example,
Class objects. But you don't want to move
objects around the network in that form. Everyone who implements the lookup service,
therefore, must translate the
Class objects into something that can be
moved around the network. Well, that is just their problem.
That means the user doesn't have to call something that turns a
object into something transmittable. And not only is that easier on the user, but it allows
more variation in the implementation, because you can have one kind of transmitter but I
can have another. And the whole issue of transmittability is an implementation detail.
Design fundamentally to me it is a human factors experience. And, yes, these humans are programmers. And they are a little different than other people. They may be better at formal thinking. Maybe they remember more than the standard seven plus or minus two. Maybe they can remember nine plus or minus two, or eight plus or minus three, who knows. But they are still people.
Another thing to keep in mind is that people will do stupid things. To you, everything you write is important. To the person using that design, it is a means to an end, and they want to understand as little of it as possible. As a result, you want to make illegal or improper things impossible. Any mistakes you can't make impossible, you want to catch. In other words, first design such that improper things can't even be written or expressed. They are impossible to do. Errors you can't make impossible, you want to catch right away. So as soon as a user makes a mistake he or she is told.
Don't give people a method that does something error-prone. Give them the method that
allows them to do the subset that is not error-prone. Suppose you have a file object on
which you can call
close. You can only close an open file. You shouldn't be
able to call
close on the file object, because it may not be open. The
open method should return
something on which you can invoke
Therefore, you can't invoke
close on something you have never opened, because the only
thing you can invoke
close on you get from
open. Now you can't express the error. So
you don't have to catch the error of attempting to close an unopened file, because you
can't even write that.