Stick with “good enough,” until it isn’t

In business, we want to focus on our core domain, and let everything else be “good enough.” We need accounting, payroll, travel. But we don’t need those to be special if our core business is software for hospitals.

As developers, we want to focus on changing our software, because that is our core work. We want other stuff, such as video conferencing, email, and blog platforms to be “good enough.” It should just work, and get out of our way.

The thing is: “good enough” doesn’t stay good enough. Who wants to use Concur for booking travel? No one. It’s incredibly painful and way behind modern web applications that we use for personal travel. Forcing them into an outdated travel booking system holds your people back and makes recruiting a little harder.

When we rent software as a service, then it can keep improving. I shuddered the last time I got invited to a WebEx, but it’s better than it used to be. WebEx is not as slick as Zoom, but it was fine.

There is a lot of value in continuing with the same product that your other systems and people integrate with, and having it improve underneath you. Switching is expensive, especially in the focus it takes. But it beats keeping the anachronism.

DevOps says, “If it hurts, do it more.” This drives you to improve processes that are no longer good enough. Now and then you can turn a drag into a competitive advantage. Now and then, like with deployment, you find out that what you thought was your core business (writing code) is not core after all. (Operating useful software is.)

Limiting what you focus on is important. Let everything else be “good enough,” but check it every once in a while to make sure it still is. Ask the new employee, “What around here seems out of date compared to other places you’ve worked?” Or try a full week of mob programming, and notice when it gets embarrassing to have six people in the same drudgery.

You might learn something important.

Library vs service: who controls change?

When you have a common piece of functionality to share between two apps, do you make a library for them to share, or break out a service?

The biggest difference between publishing a library or operating a service is: who controls the pace of change.

If you publish a library for people to use, you can put out new versions, but it is up to each application’s team to incorporate that new version. Upgrades are gradual and may never fully happen.

If you operate a service, you control when upgrades happen. You put the new code in production, and poof, everyone is using it. You can upgrade multiple times per day, and you control when each is complete.

If you need certain logic to be consistent between applications, consider making a service. Control the pace of change.

(For one flipside, see: From Complicated to Complex)

Data Flows One Way

At QCon NY, Adam Ernst talked about the way Facebook is rewriting their UIs to use a functional approach. When all the UI components subscribing to the model, and the model subscribing to UI components (even through the controller), it’s a whole wad of interconnectedness.

Instead, it has been decreed that all data flows from the top. The GUI structure is a function of the model state. If a GUI component wishes to change the model state, that event triggers a regeneration of the GUI structure. Then, for performance, React.js does a comparison of the newly-desired DOM with the existing one, and updates only the parts that have changed.

Data flowing in one direction is a crucial part of functional programming. Persistent data structures, copy-on-mutate with structural sharing, and two-way links between parts of the structure don’t go together. Choose the first two.

In higher-level architectures, microservices are all the rage. Unlike old-style legible architecture diagrams, the dependency diagram in microservices looks like the death star. Services connect directly to each other willy-nilly.

There are alternative microstructure architectures that, like React.js, get the data flowing in one direction. Fred George describes putting all the messages on a bus (“the rapids”) and let services spy on the messages relevant for them (“the river”). The only output a service has is more messages, delivered into the rapids for any other service to consume.

This is cool in some ways. New services can build on what’s out there, without anyone knowing to send anything to them directly. However, the dependencies still exist. And it’s slower than direct connections.

What about… (also from a QCon session) OSGi is the very well-developed solution to this on the JVM. Anyone can look for a particular service, and get connected up through a trusted broker. Once the connection is made, it’s direct, no more overhead. Is that ideal?

Adam’s talk The Functional Programming Concepts in Facebook’s Mobile Apps” isĀ on InfoQ