Tag Archives: OO

Object Orientation – you’re probably doing it wrong

Is it possible that almost everyone really has no idea that they’re doing it wrong?

If taken literally, and to the extreme, encapsulation means that objects should have no getters or setters, only command methods. If we follow this pattern, then our code becomes a lot simpler and easier to understand. But how then do we write user interfaces? We follow the CQRS pattern, of having two distinct sets of code — one containing our object model which is used for writing, and which contains the true status of our application, and a second containing the information used by the UI. The read-side model is updated by responding to events in the write-side model. As a consequence, we gain the ability to independently tune the performance of the two aspects of the application.

Martin Fowler called this pattern CQRS, but I think it’s more than that — I think that this is object orientation. Having accessor and mutator methods (getters and setters) leads to all sorts of trouble. The kind that encapsulation was designed to fix. A long time ago, the industry jumped onto interfaces as the defacto pattern for implementing encapsulation — after all, you’re not exactly exposing internal representation if you use a method — you can vary the implementation separately from the interface, the getter method, without changing your dependent code — problem solved, right? No, the problem is still very much in effect because this naive approach is still exposing way too many implementation details. It is almost always the case that when we change the implementation, we’ll also change the interface. This is seen very commonly in the java beans approach to OO — a very influential approach that I now believe is retarding engineering practices.

Try the cqrs approach for a while, and you’ll probably find that your code is cleaner and more elegant, and just as importantly, it is easier to maintain, contains fewer defects, and is faster, and therefore, less expensive to develop. All of this adds up to reduced costs, shorter time to market, and reduced risks.

In a typical webapp, the pattern is simple: javascript fires off rest requests to the server for data to display — that’s handled by the read-side, which is optimised to handle these queries. Eventually, the user submits a change that the server needs to know about, so the javascript at the front formulates a command and sends it, along with any appropriate data, to the back end for processing. This command will be processed by the rest controller, which will call a method on an aggregate root object which is responsible for propagating instructions to its subservient parts. While this is happening, events will be raised which are handled by both other parts of the write-side model, and by the read-side model which updates itself to reflect changes made to the write-side model (this is a one-way street — no read-side events are handled on the write-side). When the command processing is complete, the rest server returns the appropriate code to the client, which then issues a request for updated data from the read-side.

This pattern is remarkably simple, but it leads to very clear code and very clear separation of concerns. Rest services provide data to be rendered by the client. Rest services provide command processing interfaces. Write-side models process those commands. Read-side models react to notifications that the model has changed. All independent of each other. Not a getter in sight.

Where I have done this we have had separate databases for the two sides, and we’ve used the excellent Axon framework for the write-side, and the excellent spring-data framework for the read-side. I’d like to have used spring-data-rest, but that’s just not ready yet. We have also used spring-webmvc for our rest controllers.

We build all of this through maven — once — and release it to a common repo. Builds are repeatable, but we don’t care about that — we promote a single built artifact through all of our environments, ensuring that the artifact in production is the one we tested in functional testing, integration, QA, UAT, and Pre-Prod.

Optimistic Locking and Object Identity

Optimistic locking is the process by which we block a client from changing an object that was changed by someone else during this client’s edits. The process is common: user A and B both load the same resource and start work. User B submits their work first. When user A submits their work it’s rejected because the underlying object has changed while they were editing it. We call this optimistic locking because we assume it isn’t going to happen very often and the user is optimistic that they won’t have wasted their edits.

Usually we implement this with a number (or timestamp — same thing) on the object. We get a request to change an object so we load it by ID and check it’s version number. If it’s different from the version number on the submitted object we know that the submitted object is out of date and we can’t accept the changes.

Of course, we don’t need to load the whole object just to find out that we’re going to reject the changes — an optimistic locking exception. For efficiency, we could query for the object using a compound key — the ID and Version Number together – if we don’t find an object to update we reject the changes. We could even simply issue the DB update (if we’re using a DB), using the compound ID+version key in the where clause and note if a change was made, offering a rejection response if nothing was updated. Efficient it may be, but really it’s 100% equivalent to load and check (actually, it’s better to use the direct update, rather than load and check, unless you want to risk the underlying data changing between the load and the check).

But, given the optimisation above I noticed that, effectively, the object’s identity changes on every update. An object with optimistic locking is an object who’s identity is encoded in the sum of its attributes, and if a single byte changes then so does its identity.

This is deep. We often assume that an object’s identity is tied to its ID, but here we’re deliberately subverting the id to ensure that a user is fully informed before they take an action. In so doing, we’re forcing an object’s identity to change, when we should be changing only the value of its attributes.