Shower Idea: Keyboards and Object-Oriented Design


You know that hypnotic thinking that happens in the shower? I do that outside of the shower. I’m not just staring at the wall. That’s the story of why I’m calling this a shower idea (even though I didn’t think of this in the shower).

I’ll probably post more of these shower ideas in the future. I usually forget to write them down, but I’m going to stop doing that. These ideas aren’t groundbreaking. They’re just interesting food for thought.

In the case of this shower idea, I was reading The Early History of Smalltalk, by Alan Kay and thinking about object-oriented design (as I often do… probably too often. It might be unhealthy at this point). I thought of an interesting relationship between how keyboards interface with computers and object-oriented design.

What happens when you press ctrl+a on your keyboard? I’ll tell you what doesn’t happen. Your keyboard doesn’t ask your computer what application is open and if it’s notepad selects all the text in the note. What the keyboard actually does is send a signal to the computer telling it which keys were pressed.

Just for fun, lets map these two ideas to classes. I admit these are not classes anyone is likely to ever write, but it’s merely an experiment to show how a concept can map to code differently with drastically different results. Given the criteria of “when the ‘ctrl’ and ‘a’ keys are pressed we should highlight all the text in notepad.”

Lets first map (at a high level) what happens when a key is pressed on a real keyboard.

public class Keyboard {
	
	private Computer computer;
	
	public Keyboard(Computer computer) {
		this.computer = computer;
	}
	
	public userKeyPress(Key key) {
		computer.pressKey(key);
	}
}

As in real life, the operating system and eventually the application decide what to do with the key press. This code would eventually do the same thing. You could look at this code and say that the problem presented is not solved. There is no proof here that the text will be selected when ‘ctrl’ and ‘a’ are pressed. You are right. It would be implemented in other classes. This keyboard class gives other classes the opportunity to implement what was asked. It provides a message for other objects (operating systems and applications) to respond to and implement as they see fit. They would implement the functionality that is requested. We’re just not showing it here. You’ll notice this is also an east-oriented design.

The class below is typical. It’s a very literal translation of the given criteria. You’ll notice that when we mapped a real keyboard into the class above it was easy to map the class back to how a real keyboard works, but the class below doesn’t map easily back to a real keyboard. Imagine if real keyboards worked this way. When they invented the keyboard they would have had to look into the future to see that the notepad application was invented.

public class Keyboard {
	
	private Computer computer;
	
	public Keyboard(Computer computer) {
		this.computer= computer;
	}
	
	public userKeyPress(Key key) {
		Application app = computer.getForegroundApplication();
		if(app.name.equals("Notepad.exe"){
			KeyModifier keyModifier = key.getModifier();
			if(key.equals('a') && (keyModifier != null && keyModifier.equals('ctrl'))){
				app.getWindow().selectContents();
			}
		}
	}
}

If we wouldn’t do this with a real keyboard, and we wouldn’t do this with our keyboard class then why would we do this with any other class?

A Few Things on My Mind

Some ideas about objects and messaging:

  • An object should do only what objects of its type are capable of doing, not what interfacing objects are expected to do. (Method names should be appropriate for the object, not appropriate for its collaborators)
  • An object should have all of the resources required to do its job, it should not reach out to others to get them. (Resources are passed in to the constructor or received as arguments in an incoming message)
  • An object should send with messages only information about what it knows or what it is; not what interfacing objects are expected to know or be.

Now examine the two classes above and see that the first one follows these guidelines and the second one does not.

Advertisements

Comments!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s