Dazed and Confuzzled


Alright, Alright, Alright

For a long time I’ve been on a mission to find the lost parts of object-oriented programming. There is clear evidence that somewhere between its inception and modern programming OOP has lost its definition. Dr. David West says in his book, Object Thinking, “An argument can be made that the contemporary mainstream understanding of objects is but a pale shadow of the original idea. Further, it can be argued that the mainstream understanding of objects is, in practice, antithetical to the original intent.”[1] There is an original form of OOP that promises many benefits, with the foremost benefits being system composability and flexibility. The form of OOP that many use today, and the form being taught today is a diluted version. We typically defer to a structured style that places control procedures in direct command of other procedures and use objects as data structures.

I’ve been using a chess program as a project to experiment with object-oriented design. In a previous post, I wrote about problems getting this project off the ground and my personal introduction to TDD. I now have 17 failed versions of the program on my computer (those are just the ones I didn’t delete).

I recently started the chess project again, but this time with some help from a person I admire (James Ladd). I was inspired to reach out to him after reading his blog post on “East Oriented” code. He accepted my request for help, and is providing me with guidance on the project. I’m thankful for his help and patience.

Our conversation so far has some interesting insights. If you’re an intermediate programmer like me you might find you’re asking yourself some of the same questions I’ve asked James. If you’re an advanced programmer, well la-de-da, take a look at the project anyway, smarty pants. If you’re a beginner programmer, you can only aspire to one day feel as confused as I do right now. You can follow the project at github.com/TheSecretSquad/chess. We’re posting our conversation as well as the code so readers can learn from the process.

In his blog post, James describes a pattern of designing object-oriented code with a focus on objects interacting through messages that show intent. James states, “The rigorous application of this East principle decreases coupling and the amount of code that needs to be written, whilst increasing the clarity, cohesion, flexibility, reuse and testability of that code. It is easier to create a good design, structure and identify dependencies and abstractions by simply orienting East.”[2]

So why is East Oriented code an important idea? I think it’s important for at least the following reasons:

  • Instead of asking objects for contextless data on which to operate, we have methods that show intent. Methods show what we intend to do with some data without actually having to hold that data. The data is virtual, an idea, which means it can exist in any form (or all forms… it’s “Schrödinger’s data”…). We don’t need to know what it looks like.
  • It creates objects that interact with smaller, more focused interfaces, which create opportunities for extension without modifying existing code.
  • It localizes changes in the code to the neighborhood of objects that focus on a particular task instead of requiring changes to client code that uses that neighborhood of objects.

All of these things promote key aspects of OOP like composability and flexibility (or “malleability”[1] as Dr. West says) and that’s why I felt compelled to pursue a concept that so naturally fits these ideas.

Who Put the Code All The Way Out Here in the Woods?

Everything we say in code is significant, so we should write code deliberately. The users of an API expect the programmer designed the API deliberately. If a programmer writes a method in a particular way then a user expects they wrote it that way purposely, and not by coincidence or carelessness.

Looking at James’ blog post, he uses an example of a MovieLister class that can list movies by certain attributes (in this case by director). Example 8 shows the original “West Oriented” moviesDirectedBy method. It looks like this:

public Movie[] moviesDirectedBy(String arg)

If we are a user of this API we must assume that the Movie[] return type is significant. We must assume it is important that we get specifically an array of Movie objects. Why an array and not a Collection<Movie>, List<Movie>, Set<Movie>, IEnumerable<Movie>, etc.? The programmer must have chosen carefully what type to return and deliberately chose an array. Or… The programmer thinking in “West Oriented” fashion decided that we need control of “a bunch of Movie objects” so we can “do stuff to Movie objects”.

This doesn’t seem deliberate. Choosing a return type arbitrarily means users are relying on a careless choice that is likely to change at some point. This also promotes procedural style code:

Procedural: “Get the movies directed by a director, then do some action to them.”

Object-Oriented: “Perform some action with the movies directed by a director.”

James’ East version looks like this:

public void applyToTheMoviesDirectedBy(final MovieAction movieAction, final String director)

Looking further at James’ post, pushing it East allows us to hide the movies collection, and do an internal iteration handing each movie off to a MovieAction object. The caller need not care what collection type stores the movies while they’re “doing stuff to the movies”.

I am a little suspicious of any return values. Do we really need that int, or that double, or whatever it is? Do we really need the data explicitly in front of us to work with it?

The Message, as a Significant Preamble to Something Else

Dr. West says about object-oriented programming, “Distributed cooperation and communication must replace hierarchical centralized control as an organizational paradigm.”[1] I believe that transitioning from our current understanding and usage of OOP to a point where we can leverage its intended benefits comes with understanding messages.

I’ve read a lot lately about the concept of messages. I’m not a Smalltalk programmer (yet), but I know the Smalltalk community is known for its focus on this concept. The idea behind messages is objects send messages and neighboring (or collaborating) objects receive those messages. The receiving objects respond to messages by changing their state or sending other messages, which their collaborators receive, and so on. Objects don’t know who is responding to the message, and in many cases they don’t know what will happen in response. They just know to send the message and trust the object hooked up to it at run time responds with the correct behavior.

The thing about messaging is data becomes irrelevant. Data is hidden within objects, and used to store the state of objects. Objects use this state to decide which messages they should send. Objects can’t ask collaborators for their state or data and operate on it. The only way objects release state is by sending a message signaling a significant event. Other objects can register to receive the message and respond to it. This type of design naturally leads to East Oriented code because you’re not returning data (west).

Kent Beck and Ward Cunningham said, “The most difficult problem in teaching object-oriented programming is getting the learner to give up the global knowledge of control that is possible with procedural programs, and rely on the local knowledge of objects to accomplish their tasks.”[3] Getting messaging right is hard, and I’m only recently finding how the concept differs from methods. Methods implement messages. In many languages methods resemble procedures or functions, so most people (including me) just end up writing classes that are modules with procedures.

In trying to apply this messaging concept to my code I find myself stuck once again. What should these messages look like? The basis for my analysis is:

  1. An object should send messages to client-specific interfaces. This means an object should send messages that are meaningful to itself, and interfacing objects should have only those messages available.
  2. The messages should focus on what not how.

In both cases we are attempting to avoid unneeded context. In the first case an object wants awareness only of the messages it needs to know about. In the second case we want to avoid the context of how an object carries out a task and focus only on what the message does.

The second case is particularly interesting to me: What does “what” mean?

I Hear My Name Over Here? You Guys Talking About Me?

I recently read Practical Object-Oriented Design in Ruby by Sandi Metz. It significantly effected how I think about object-oriented code. My understanding from reading Sandi’s book, is that objects are not modules of functions operating on mutual data and state as we are often taught. Maybe that’s what they are to us as programmers, but that’s not what they are to other objects.

The public interface to an object is not “what the object does”. The public interface to an object consists of the messages it responds to; “what an object does” consists of the messages it sends. I think it’s this inversion of thinking that puts the power into objects. Ideally, a message sender should have no idea what will happen when it sends a message.

One topic Sandi wrote about that keeps rolling around my mind is the context objects have when sending messages. When an object sends a message to a collaborator it carries some knowledge or expectation of its environment. In her book she describes the relationships between communicating objects like this:

  • I know what I want and I know how you do it. [(least flexible)]
  • I know what I want and I know what you do. [(somewhat flexible)]
  • I know what I want and I trust you to do your part. [(most flexible)]
    [4]

It’s easiest to understand with the example from her book, but I’ll try to summarize my interpretation:

  • I know what I want and I know how you do it: Calling methods on an object where the method names are semantically part of the called object’s context. This binds the caller to the process implementation, i.e., how the object accomplishes the process. This is basically treating an object as a module with procedures and the caller must know how to use the procedures to accomplish a desired task.
  • I know what I want and I know what you do: Sending messages to an object where the message names are semantically part of the called object’s context. The caller is not bound to an implementation, but is bound to an expectation. The caller expects the receiver to enact some process related to the called object, and that will never change. Receiving objects have no option to do anything else. If the response to the message has to change or have added processes, then the caller must change to accommodate the new messages or changed names.
  • I know what I want and I trust you to do your part: Sending messages to an object where the message names are semantically part of the calling object’s context. The caller is not tied to an implementation, and has no expectation of the called object’s reaction. The programmer expects a specific reaction based on the object hooked in at run time, but the result of the message can differ in both implementation and result.

I don’t know if this is the best explanation, but I tried. It’s probably better with an example. One thing that comes to mind that I can use as a short case study is the “tell, don’t ask” example given by Steve Freeman and Nat Pryce in their Mock Roles, not Objects paper.

They start with the example of a “train wreck” of getters:

dog.getBody().getTail().wag();[5]

This is I know what I want and I know how you do it. An alternative design of the same nature could be:

// Dog being happy
dog.wagTail();
dog.bark();
dog.drool();

They then refactor to “tell, don’t ask” style:

dog.expressHappiness();[5]

This is more like a message than calling procedures on a dog module. Here we tell the dog object what we expect, not how to do it. The caller doesn’t know how that happens; the dog might reference a body object, or it might bark or wag its tail, etc.

This is where they stop the refactoring, but I think it could be better. If we apply Sandi’s ideas, this is I know what I want and I know what you do.

Any caller sending this message, knows to expect a dog will express happiness. That will always be the result. The clients of this message are also responsible for figuring out what makes the dog happy, and then telling the dog to express happiness. We can see that this message takes the perspective of “what the caller expects from an object”, which means the caller is aware of the called object, and must carry it in its context.

Lets say a feature we want is for the dog to show certain emotions based on some actions or events, we would end up writing code logic like this:

if someone throws a ball
dog.expressHappiness()

if loud noise
dog.expressFear()

if owner is gone
dog.expressSadness()

etc.

I can’t even think of what to call the class that figures out what makes a dog express certain emotions. It doesn’t seem like clients should figure out what makes a dog express certain emotions anyway. It’s something the dog should do.

One pattern that stands out to me is if you can predict the outcome of a message, then you can probably abstract it further. For example, when we say dog.expressHappines(), we don’t know in what way the dog will express happiness, but we do know the semantic outcome will be the dog expressing happiness. We have locked ourselves into that. It’s now part of the client’s vocabulary. If one of the main benefits of OOP is flexibility (malleability), then I think we can take this a step further.

So how do we get to I know what I want and I trust you to do your part? I’ve experimented with an idea that I stumbled on while talking with James as part of our chess project (you can see how that went on github).

The idea is to rephrase the problem from the perspective of the caller (or client) like this:

“Y is an example of something Y-object could do when “the client” does X”.

“Expressing happiness (or fear, or sadness) is an example of something a dog could do when someone throws a ball.”

Using this statement we can see that the dog’s behavior is a reaction to a message sent by someone else throwing a ball.

It might look like this in code:

public class Dog {

	public void throwBallTo() {
		this.expressHappiness();
	}
}

We’ve now protected clients from changes to the dog’s expressions. Dog implementations are free to express any emotions when someone throws a ball, like fear, if it’s a nervous dog. A grumpy dog that never expresses happiness doesn’t have an expressHappiness() method hanging around for no reason. Obviously the throwBallTo() method could be generalized to something like throwObjectTo(), or whatever else. The point is that the message sender no longer expects the context of a dog or any other animal that expresses emotions. If throwBallTo() was a method of a separate interface, then the caller doesn’t even need to know about the Dog class. The caller expects it can throw a ball to anything and if it’s a dog it will express the implemented emotions or generally do dog stuff.

Notice the difference compared to before. We could predict the outcome of the method call; expressing happiness declares that in one way or another the dog expresses happiness. Throwing a ball to something guarantees infinitely more possible outcomes from the client’s perspective.

Sandi says, “The best possible situation is for an object to be completely independent of its context. An object that could collaborate with others without knowing who they are or what they do could be reused in novel and unanticipated ways.”[4] I think this type of design change achieves this. I think looking at the messages from the client’s perspective helps.

Fixin’ to be A Lot Better, Man

So how does this relate to the chess code? Here’s the relevant code from chess:

Tests for the Game class:

@RunWith(MockitoJUnitRunner.class)
public class GameTest {

	private Game game;
	private Square square;
	@Mock
	private MovesReceiver movesReceiver;
	@Mock
	private Board board;
	@Mock
	private StartingPieceConfiguration startingPieceConfiguration;

	@Before
	public void setUp() throws Exception {
		square = anySquare();
		game = new Game(board, startingPieceConfiguration, movesReceiver);
	}

	private Square anySquare() {
		return Square.A1;
	}

	@Test
	public void shouldSendMovesForSquareWhenSquareIsChosen() {
		game.chooseSquare(square);
		verify(board).sendMovesForTo(square, movesReceiver);
	}

	@Test
	public void shouldSetupPiecesOnTheBoardWhenStarted() {
		game.start();
		verify(startingPieceConfiguration).setup(board);
	}
}

The Game class:

public class Game {

	private final Board board;
	private final MovesReceiver movesReceiver;
	private StartingPieceConfiguration startingPieceConfiguration;

	public Game(final Board board, final StartingPieceConfiguration startingPieceConfiguration, MovesReceiver movesReceiver) {
		this.board = board;
		this.movesReceiver = movesReceiver;
		this.startingPieceConfiguration = startingPieceConfiguration;
	}

	public void chooseSquare(final Square square) {
		board.sendMovesForTo(square, movesReceiver);
	}

	public void start() {
		startingPieceConfiguration.setup(board);
	}
}

The Board interface:

public interface Board {

	void sendMovesForTo(Square square, MovesReceiver movesReceiver);
}

The StartingPieceConfiguration interface:

public interface StartingPieceConfiguration {

	void setup(final Board board);
}

The gist of what’s shown here is when someone chooses a square, the Game responds by sending the available moves for that square on the board to an object that receives the moves. The receiver of moves most likely will display them in some way, but could do anything it wants with the moves. When someone starts the game, the game sets up starting piece configuration on the board.

I think the code and tests model the domain well and it’s all clear as far as code comprehension. Still, something about this causes conflict in my squishy brain parts.

The question I have, is should the Game class send the message sendMovesForTo(square, movesReceiver) to the board? This is a feature that I wanted to implement, and I think we did a good job of abstracting it (you can see how on github), but I can’t help but look at this as I know what I want and I know what you do. If the point of using OOP is its flexibility, then we should try to keep it maximally flexible, so in my mind the goal is code that embodies I know what I want and I trust you to do your part, and I should seek to change this code.

If someone else wanted to use the Game class, but had no interest in sending the moves anywhere, they are still dependent on an interface that has that message. Their Board implementation needs to make sure that it sends the moves to a receiver even if they don’t care about this.

The Game knows about something that is holding the pieces on a grid of squares, i.e., the board. What message can the Game send that the Board could respond to with our expected result, and still supports many possible outcomes?

Looking at it from the client’s perspective:

“Sending the moves for a square to a receiver is an example of something that could happen when a square is chosen on the board.”

I thought of changing the code to:

public void chooseSquare(final Square square) {
	board.chooseSquare(square);
}

It seemed pointless at first to call the same message on Board that we call on Game; what does this accomplish? Is this just frivolous indirection. Then I thought that maybe choosing a square in the context of the game is different from choosing a square in the context of the board. These objects have different opinions on what happens in response to the chooseSquare message. It’s the Game‘s job to invoke the behavior on the Board.

With this change the MovesReceiver would be removed from the Game class and be passed as a constructor argument to a class implementing the Board interface.

I made similar changes to “setting up the pieces on the board”. I changed the test to:

@Test
public void shouldPrepareTheBoardWhenStarted() {
	game.start();
	verify(board).prepareToPlay();
}

And the Game to:

public void start() {
	board.prepareToPlay();
}

The reasoning is “Setting up the pieces on the board is an example of something that could happen when the game is preparing to play.” Maybe the board does other things during preparation. If the game knows about one of those things, then Game would have to know about all of those things when we inevitably add to the list of things the board does during preparation.

I can see how the prepareToPlay() method might create an opportunity to have other objects that are part of the Game‘s preparation and respond to the message. However, this is not something I would worry about now. I’m just examining the possible effects these changes have on the design.

Despite everything I just said, and all the research and evidence I have for making my point. I’m still not convinced of any of this. I don’t know if these changes are better than before.

Wait, Why Are You Smiling?

Lastly, I noticed these changes affect the tests. I can no longer write a Game test that guarantees that we send the moves to a receiver, which is the feature I wanted in the first place.

Instead my test would have to read something like this:

@Test
public void shouldChooseSquareOnTheBoardWhenSquareIsChosen() {
	game.chooseSquare(square);
	verify(board).chooseSquare(square);
}

At this point, to make sure the feature exists I would have to begin implementing a class that implements the Board interface, and test that it implements the “sending moves” feature. I’m relatively new to unit testing, so I’m not sure what to do here. Do I stop writing/testing the Game class and switch to implementing this feature in another class? Do I hang up the feature for now (put a note in Trello or something) and worry about it later? Is this a sign that I’ve abstracted too much and should instead revert my changes? I don’t know.

There Was Just a Little Bit of Bullshit in All That Right?

That’s all I have to say for now. I still have an inkling that everything I just said is complete nonsense.


[1] West, David (2004-02-11). Object Thinking (Developer Reference) Pearson Education. Kindle Edition.

[2] Ladd, James. “DRAFT – A Design Compass: East Oriented …” JamesLaddCode. JamesLaddCode, Feb 2007. Web. 13 Oct. 2014.

[3] Beck, Kent, and Ward Cunningham. “A Laboratory For Teaching Object-Oriented Thinking: From the OOPSLA’89 Conference Proceedings October 1-6, 1989, New Orleans, Louisiana.”SIGPLAN Notices 24.10 (1989).

[4] Metz, Sandi. Practical Object-Oriented Design in Ruby. Pearson Education, 2013.

[5] Freeman, Steve, Nat Pryce, Tim Mackinnon, and Joe Walnes. “Mock Roles, Not Objects.”OOPSLA (2004).

Blogs and Other Sources I’ve Been Studying While Thinking About All This

Advertisements

10 thoughts on “Dazed and Confuzzled

    • Hey Pawel, thanks for reading. Those links look interesting. I’m always interested in different perspectives on this subject. Looking forward to checking them out. Thanks for sharing.

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