Monday, December 31, 2018

Refactoring to Transfer Functionality Between two MonoBehaviour Implementations

This was a lot of fun. I had one MonoBehaviour class that was hosting behavior which rightly belonged to another. I transferred the method containing the behavior, wrote down the parameters as writes to public fields, and inlined the bit that did the writes to the public fields, leaving the functionality on the other MonoBehaviour class. Then, I configured all the properties on my prefab in the editor.

Once I did that (correctly, it took me two tries), I was able to delete the fields from the old MonoBehaviour class, signifying that I had completely and correctly transferred the behavior.

It was fun.


Friday, December 28, 2018

Story Points as Food Pellets

Someone crouched over a feeding tray eating a pellet stamped with the letters "SP".

Ever see a team invest a bunch of time into deciding how many story points they could claim at the end of a sprint?

You get what you teach people to give you.

Positioning story points as valuable encourages people to treat them as rewards. Rather than trying to be productive and "earning" points, time will be wasted trying to claim points for work that isn't really done.

Wasted time erodes productivity, and lowered productivity provides more incentive for credit-grabbing behaviors. A vicious cycle ensues.

This is what you get when you set story points up as these little food pellets meant to modify the behavior of your developers: Developers whose behavior is optimized for getting story points, not writing software.

The solution is simple but very hard: Start tracking what you want.

Not something you think will lead to what you want. Not something you consider to be an integral part of what you want. Track whether or not you are actually getting what you want.

Thursday, December 27, 2018

Test-Coverage

A person giving address to a group: "To improve personal hygiene, we'll be tracking water-consumption."

Measuring test-coverage tells you almost nothing of value. A disciplined approach leads to high test-coverage. The resulting tests add a lot of value to the development environment.

That correlation isn't something on which you can count, though.

It's like measuring the sharpness of knives in a kitchen. A good cook is going to keep their knives sharp all the time. An amateur cook will probably ignore the a report that their knives are too dull.

The same is true of test-driven development. You're either a professional or you aren't. Either way, test-coverage isn't going to change it.

Most of the time, organizations that are tracking test-coverage end up with something worse than no tests: vast tracts of useless tests that increase cost while providing no real protection.

Wednesday, December 26, 2018

What to Cut?

Imagine you have a timebox and a commitment, like a lot of people imagine sprints and sprint plans to be. Now imagine you can't do everything that was agreed upon at the beginning of the sprint by the end of the sprint.

What do you do?

Regardless of theory, in practice, a lot of people seem to want to cut quality. This is counterproductive because quality and speed are deeply-related. Cutting quality rarely makes you go faster in the moment and always makes you go slower in the mid- to long-term.

Time-boxes like sprints are, by definition, fixed length. Sustainable software development is fixed-quality. The only thing left to cut is scope.

Cut quality to go slower. Cut scope to go faster.

Given timebox, when work > capacity, then cut scope. PERIOD

Tuesday, December 25, 2018

For Encapsulation, Ask "What's the Cost of Changing Visibility Later?"

Santa taking a selfie with the caption "once it's out there it's out there."

Most languages give you a choice regarding how visible a member of a class will be. The choices vary from language to language but, typically, they range from more-widely exposed options to those granting narrower visibility.

Every time you define a member, you are making this choice. Even if you take the default level of visibility, you are still making the choice to accept the implicit level of visibility.

One thing you can do to inexpensively start improving the level of encapsulation in your system is to start asking a simple question:
What's the cost of changing visibility later?
Generally, all levels of visibility have the same cost, initially. You aren't going to choose an access-modifier that prevents something from being used the first time you write it.

What really matters is how the level of visibility will interact with change. If you make something too private, now, how hard will it be to make it more public, later? If you make it too public, now, how hard will it be to change it to be more private, later?

In a lot of cases, it's pretty straightforward but it isn't always obvious. That's why it's worth asking the question.

Monday, December 24, 2018

Easy to Check versus Useful to Check

Two people standing next to a car. One says "Should we test how she corners?" The other says "Let's just see how far we can turn the wheels..."

There are different axes on which you can evaluate whether or not you want to invest in measuring something and acting on those measurements.

One of the most popular seems to be "How easily can I implement this metric?"

Sadly, one of the least popular seems to be "What kind of decisions will this metric help me make?"

Lower implementation cost might be a good reason to choose one good metric over another good one but it is a terrible reason to reject a meaningful metric in favor of a worthless one.

Yet this has basically been the mode of our industry. Three great examples of metrics that seem to get a lot of traction are number of lines of source code per day, percentage of unit test coverage, and number of story points committed versus delivered in a sprint.

All three of those are worse than useless: they are counterproductive. In fact, each of them is downright corrosive. Yet they keep being chosen over their potentially-useful counterparts again and again.

Why?

I think it's because they are easy to measure.

Easy is nice. Easy is good. Easy is core to what we do. It's important to remember, though, that things are almost never just naturally easy in the software world. We make them easy.

If you want an easy metric, take a useful one and keep investing until it's easy to measure rather than cherry-picking metrics because they can tell you nothing quickly.

Friday, December 21, 2018

No Expectations

A bookie says "I'm giving 2:3 odds on heads." One of his patrons says "That's fine. I have low expectations."

Having no expectations is better than having low expectations.

Low expectations are a way of setting yourself up to lose but rationalize that loss as a win: Either you were wrong, which sucks, or you were right, which also sucks.

No expectations, on the other hand, comes with a decided benefit: It's easier to react to unexpected outcomes because all outcomes are unexpected.

It may seem counterintuitive but turns out there's a lot to be gained from not creating an emotional investment in some prediction which, for all intents and purposes, was selected at random.

Thursday, December 20, 2018

Does It Matter if You Mock?

Part of me thinks this is a continuation of this post.

I love mocking and experience none of the problems purported by people who seem to hate it. I also recently tried an experiment of writing tests with minimal (so far, no) mocking.


Guess what. I'm experiencing none of the problems purported by people (such as myself) who prefer to writing code with mocking.

What gives?

I've known that whether or not you use a mocking tool, like Moq, doesn't matter. Hand-rolling a mock or writing a test-double with widely-understood behavior works just as well as using a dynamic mocking tool.

Now, I'm beginning to think that whether or not you mock at all isn't really that impactful at all. I think that, when we measure an impact, what we are really measuring is a correlation with something else; something that does matter.

I think what we are measuring is the degree to which a test specifies a single behavior and is insulated from implementation details. I don't know why, but I'm guessing we blame our tools for the success we've experienced.

More on this as I continue to experiment.

Wednesday, December 19, 2018

Which Is Better: Big Tests or Little Tests?

Two people arguing: "I only use NUTS!" and "I only use BOLTS!" Both are foaming at the mouth.

As an organization starts to get more healthy, a focus is placed on building a meaningful test suite for their product or products. Should you write big tests that cover large swaths of your system or should you write little tests that give you precise, reliable feedback on individual parts?

Tuesday, December 18, 2018

Levels of Done

A person is sitting, contorted in an extremely uncomfortable chair. Another person asks "How do you like my revolutionary new chair?" The uncomfortable person says "I have a few notes".

Previously, I pointed out that an engineer's definition of done should extend at least as far as their software being immediately deployable. That's a step in the right direction.

I think another step is to adopt this simple threshold of done:
Customers are deriving value from this behavior/story/feature.
You can't know you're done without attending to everything that needs to be done:

  • Working software.
  • Deployed in production.
  • Released to customers.
  • Validated with feedback.

Making the standard of done customers actually getting value measures all the things that matter without any risk of measuring something that doesn't.

If it's not self-evident, that's because customers actually getting value is the whole point of what we do...

Monday, December 17, 2018

Connectivity

Two panes. On the left: "NOT LIKE THIS" and a person shouting about encapsulating variation. On the right: "LIKE THIS" and a person asking what is in someone's way. The person being asked says they are afraid to change their code.

Connecting with people is one of the hardest parts of helping people change how they do things. At least, it is for me.

I've identified three major reasons why you might be having trouble making a connection.
  • They don't understand something.
  • They fear something.
  • They don't feel like they have power over something.
I'm sure there are more but these easily cover the majority of the resistance I meet. All three cases demand, for me, the same approach. Try to turn it around and make yourself the person who can help the person you are trying to help the way that they perceive help.

If they don't understand something, explore it with them. If they are afraid of something, face it with them. If they feel powerless over something, help them reconcile that feeling either by creating power or banishing responsibility.

Helping someone with the problem that they can see makes you their friend. Do it a few times and some of them will start to come to you to help them find the problems you can't see.

Friday, December 14, 2018

Doing the Right Thing the Wrong Way

A person is facing a target with a drawn bow it's backwards so that the arrowhead is aimed directly at his eye.

Another big mistake is to imagine that just knowing what to accomplish is sufficient. It's not.

Maybe if you really, truly, could know what to build, get it perfectly right the first time, and never have to change it again, quality wouldn't matter.

Even oracular powers won't prevent you from having to change your code, though, because shifting market conditions mean that what you need tomorrow isn't necessarily the same as what you'll need a year from tomorrow.

The ability to change code quality is valuable on its own, for that very reason. The fact that it mitigates our inability to guess what people want or what will happen in the future is just an extremely useful side-effect.

Thursday, December 13, 2018

Doing the Wrong Thing the Right Way

A zoomed-in box shows a person having drawn a bow and looking very focused. When you follow the zoom-lines, you see he's facing away from his target.

One failure mode that is very common for us is spending all your energy on technical excellence without making sure you're working toward the right goal.

You can be a true hotshot and still miss the mark. No matter how exceptional your skills are or how clean your code is, it won't matter if you apply them to building the wrong thing.

While technical excellence does help you change direction when you realize your mistake, I've seen far too many developers go far too long before learning they weren't even realizing a meaningful objective.

Make sure to continuously invest at least a little energy in finding out if what you're doing even matters.

Wednesday, December 12, 2018

Error Modes

A hand holds a nail steady by putting the thumb over the head. Above it, a hammer is poised.

I've decided to start cataloging things developers do to shoot themselves in the foot.

I don't want to get too negative but I think knowing what to avoid is as important as knowing what to do.

I'll try to tag all such posts with the "error modes" tag I used on this one.

Tuesday, December 11, 2018

Easy Isn't Bad

Two clouds, one of them raining. The non-raining one asks the raining one "What'cha workin' on?" The reply is "We call it 'The Grand Canyon!'"

Just because it's easy doesn't make it bad. It doesn't even make it worthless.

Most of the major successes in history are actually accumulations of many small, easy wins.

Take the value where you can get it.

Monday, December 10, 2018

Simple Is as Simple Does

Two panes. On the left: a circuit board with the word "SIMPLE" superimposed. On the right: An eye with the word "COMPLEX" superimposed.

Simplicity has no relationship to how many code structures are written or boxes are drawn. It has nothing to do with whether or not a particular person can understand some code. There is no relationship between how many "things" you can count in a system and how complex it is because it all depends on what you decide counts as a discrete "thing".

A good yardstick for simplicity, in software, is sustainability. Code that stays about as easy or hard to change over a long period of time is probably simple code. Code that gets harder to work as it evolves is overly-complicated.

Code qualities are proxies for true simplicity. They guide you because they correlate strongly with sustainability. Use them. Talk about them. Weigh them when considering your design changes.

If you want to make a change to your design and it's going to make your code easier to work with over time, don't let someone complaining that it "adds complexity" dissuade you. If you're blindly following a "best practice" and someone has a compelling argument for how it's going to make things harder in the future, you're probably adding complexity.

Saturday, December 8, 2018

Friday, December 7, 2018

Auto-Close to Force Better Communication


Recently, I proposed some rules to eliminate ambiguity from acceptance criteria. They centered around the idea of automatically choosing a particular kind of interpretation.

It seems like a powerful tool, replacing decisions with automatic rules. Of course, you don't want to do it all the time...but it seems like a really good way to drive decision-making away from where we don't want it to be, like interpreting acceptance tests.

Another place we don't want judgment calls to be made is at the end of a story/task/work-item. It should be apparent, at that time, whether or not a story is ready to be closed. If it's not, it's already too late.

What if story-closure was automatic?

Imagine a workflow with the following properties.
  • Anyone can close a story when all its criteria are met.
  • Nobody can close a story if any of its criteria are unmet.
  • The strictest interpretation of any given criterion is always enforced by Product, no matter how hard Engineering worked.
  • Engineering can reject a story based on insufficient/ambiguous acceptance criteria, no matter how high priority Product says it is.
How would that change the conversation about what to do next, for your team?

A picture of a pipeline with the front part cut away. Through it "flows" five stages of work: To Do, Discussion, Development, Release, Done. It shows that development can block work from entering the Development phase and Product can block it from entering the Release phase.

Thursday, December 6, 2018

Local Excellence and Global Alignment

A person holding a broken handle hammer says "I can't make any more chairs without a new hammer." Another person says "Typical carpenter. First, everyone needs to agree on what a chair is."

It's popular in our industry to say you prefer global alignment over local excellence.

Sometimes that's part of an argument against investing in the technical skills of individual developers. Instead of "wasting" energy on that, you should solve the "real" problem: getting everyone marching to the same drummer.

I don't question the truth of the assertion but I do wonder if it considers enough factors to apply to the real world. Here are some questions we can ask ourselves to make sure it is useful guidance and not just some unconsidered platitude...
  • Is global alignment as easy to achieve as local excellence?
  • Is global alignment as enduring as local excellence?
  • Does global alignment have a "critical mass" problem? (e.g., can you have 1% global alignment?)
  • What does it cost to maintain global alignment over time?
  • Does global alignment carry any typically-unexamined risks?
  • Should global alignment and local excellence even be in competition in the first place?
  • Can global alignment really be achieved and sustained in a software organization without skilled individual developers?
I'm not sure either way.

I suspect strongly, however, that the answers to the last two questions are "No", and "No."

Wednesday, December 5, 2018

Downtime

A person jogs, plays video games, eats pizza, and goes drinking with friends. When he's asked how his weekend was, he says he spent it perfecting his craft.

I'll add my voice to this chorus: Take breaks.

Stopping to smell the roses is great. Maintaining your sanity is paramount.

Those aren't the reasons for this post. Taking breaks improves your productivity.

There are immediate effects. You can gain inspiration from time spent doing something other than your main task. Unbroken focus creates blind spots. For those and other reasons, you can be struggling with a problem before a context change that seems simple afterward.

There's also a long-term benefit: As a software developer, your mind is your tool and all tools dull with use. Taking breaks allows your mind to regain its sharpness. Problems that seem intractable when you are tired or burned-out can melt away once you are properly rested and recharged.

Relaxation and recreation may seem selfish, or even hedonistic to some, but they are actually productivity tools of the highest caliber.

Tuesday, December 4, 2018

Acceptance Criteria: Eliminate Ambiguity

One person asks another for an "ice cream sundae". The other says "Okay. I'll get you an ice cream, Sunday."

One of the problems that people have when trying to build real, meaningful acceptance criteria for their work is that the criteria end up being ambiguous. There are several reasons why this might be and I won't get into them, in this post.

Any such force can be at least partially counteracted by introducing one of two simple rules.
  1. Any way to interpret an AC as met means it is met.
  2. Any way to interpret an AC as unmet, it is unmet.
You might think these rules are horribly unfair and one-sided. Yet, that's why they work so well. They eliminate the potential for ambiguity by automatically selecting the most relaxed or strictest version of any AC.

At the same time, they provide an incentive to drive ambiguity out of an acceptance criterion's wording. The easiest way to ensure nobody uses the "wrong" version of an acceptance criterion is to make sure there is only one interpretation.

Over time, the criteria will justify themselves and no incentive will be required to make them unambiguous, but something like this can help at first.

Monday, December 3, 2018

Acceptance Criteria: All or Nothing

Two stick figures. The first one says "That's almost what I meant." The second replies "So I guess you'll get almost what you wanted."

Commitment works both ways. Teams that commit to delivering on little pieces of acceptable work based upon agreed-to acceptance criteria need to know that Product commits to accepting based upon those same requirements.

Once an acceptance criterion is "in-flight", it should not be adjusted without unanimous consent by all stakeholders who originally committed to the requirement, including developers. Any dissent leaves the old criterion in force.

This gives Product several options for changing their minds:
  1. Cancel a criterion and halt all work in that direction.
  2. Renegotiate a criterion with engineering.
  3. Add new criteria after the current ones are implemented.
Limiting your options to renegotiate creates an incentive to limit the size of an increment of work.

Saturday, December 1, 2018

Friday, November 30, 2018

The Danger of Simplistic Models

A couple of people are treading water, encircled by sharks. One of them says "Don't worry. Dolphins are FRIENDLY!"

It's all too common for people to prefer a simpler-seeming model to one that actually works. Another way to put this is that people will typically choose a model with one less variable over one that predicts outcomes more accurately.

Every so often, there's another popular book or article on how people think. They usually try to build a blanket model that explains all people's minds as though each is cast from a single, shared mold.

These kinds of simplistic models are seductive because they feel good. They are easy to understand and easy to rationalize when some of the data don't fit.

That good feeling comes with a heavy price-tag, though.

For the same reasons they are so attractive, simplistic models run the risk of being canonized as right (about which I have previously written). As a result, people will fight to hold a broken model in place when it should be replaced and, ironically, discard a partially-broken model entirely rather than just amending it.

This means we waste a lot of time dropping bad ideas, only to find out they were good again later, then dropping the bad ideas that supplanted them, only to find out they were good, too.

We need a better way of managing this stuff.

Thursday, November 29, 2018

Acceptance Criteria: Entire Scope

A person is standing on a trap door over a water tank with a crocodile in it. He says "I know we agreed to those ACs but you should have known to -". Two other people are standing off to the side. One of them has his hand on a lever. The other one whispers "(pull the lever)".

One way to help you and your team write better acceptance criteria is to make them the sole authority on the scope of any new work. If there's no acceptance criterion for something, it isn't required. If it isn't required, it shouldn't be done.

For this to work, all ancillary documentation must carry exactly zero weight. The title of a story can't be "a little" meaningful. The description can't enforceable under "special circumstances". They are comments. They mean nothing.

Putting this rule in place has some side benefits I'll delve into later. Right now, I'd like to focus on the fact that this provides an incentive to figure out how to write good acceptance criteria.

If you can only specify a requirement with an acceptance criterion, you'll have to figure out how to make sure each one actually specifies a requirement.

Wednesday, November 28, 2018

How to Get Better Acceptance Criteria

One person says to another "It will be done when it's better." The other person, skeptically, asks "How MUCH better?"

It's easy to say "rely more heavily on acceptance criteria" but, without some guidelines, the acceptance criteria written end up not being very helpful; they tend to have little to do with acceptance and do a poor job as criteria.

Instituting a few simple rules can boost the effectiveness of shifting toward acceptance criteria as the main vehicle of communication between groups.
  1. Acceptance criteria are the sole authority on the scope of a block of work.
  2. Acceptance criteria cannot be modified while a block of work is in-flight.
  3. An acceptance criterion is met if any of its valid interpretations are met.
I'll drill into each of these pieces of advice separately.

Tuesday, November 27, 2018

Acceptance Criteria as Vehicles for Specification and Delegation

Two panels. On the left, captioned "not like this": A person tells another "I want a form that collects data, I think?" On the right, captioned "like this", a person tells another: This will be done when I can tell how many of our users eat cheese.

One way to improve the happiness of both Product and Engineering groups is to change the way they communicate to be more validation-centric. Abandon the question "What do we do, now?" in favor of "How will we know when we've done the next thing?"

Anyone paying attention knows that this is a well-traveled topic, so much so that the question "How will we know when we're done?" is basically a cliché in the software industry. Nevertheless. It's my turn to say it.

Get rid of detailed instructions, descriptions, and design documents. Replace them all with acceptance criteria.

After all, what else matters? How useful is a design document that you can't use to tell whether or not you're done? If you have an instrument that tells you that, what's the value in the other documents?

If you can get good acceptance criteria - really, truly, good ones - you can drive noise out of the communication lines between Product and Engineering. It goes further than that, but fixing the (usually) broken handoff between those two organizations yields enough value on its own to justify the change.

Agreeing with this post is the easy part. Making the change is the hard part. There's a social aspect to it and a skills aspect to it.

In the latter category is a hard question:
How do we get really good acceptance criteria?
More on that to come.

Monday, November 26, 2018

Specification and Delegation

Person A: "Give me what I want!" Person B: "What's that?" Person A: "I don't know but you better not get it wrong!"

In any handoff of work, there are two ways for decisions to be transmitted: specification and delegation.

When specifying, the party requesting the work makes a decision and communicates that decision. When delegating, the requesting party conveys intent and authorizes the work-provider to make the necessary decisions on their behalf.

If you aren't getting the results you want out of communicating requests for work - whether it's enablers coming from architects or requirements coming from Product - you have two ways to make it better.

One option is to improve how you delegate. Make an attempt to better-convey intent, give a broad charter to realize that intent, and educate the people doing the work on how to evaluate whether or not they are moving closer to or further from the goal.

Another option is to improve how you specify. Make an attempt to eliminate the potential for misunderstandings in lines of communication, channels that cause information to change hands many times. Install feedback loops to ensure that specifications are met.

While you don't have to choose between getting good at one and getting good at another, do you have to choose one and only one path for any given decision at any given point of time.

That is, you can hand off the specification of a decision you've made or you can delegate a decision to someone else but you cannot delegate a decision to be made exactly as you would have made it.

Friday, November 23, 2018

The Risk of Being Right

Three people each holding a gun on the other two. One shouts "Vanilla's the best flavor!" Another shouts "Chocolate." The last says "You're both wrong... It's tapioca."

Every once in a while, people decide something is right.

"Right" is a very dangerous idea; among the most dangerous we've encountered. "Wrong" is great - it's saved our butts more than a few times but "right", has not done us too many favors, historically-speaking.

The more right something is imagined to be, the more people will fight to retain it past its point of usefulness. A great example of this is the replacement of the phlogiston theory with the oxidation theory of combustion.

If we had a good track record of being right when we say something is right, maybe that would be okay. Actually, it would probably be a good thing.

We've shown we don't have that ability, though. We've also shown that positioning an idea as the truth has a more-or-less-inevitable and very costly battle associated with the uninstall process.

So what we're left with is trying to find a way to position fewer ideas as right.

Thursday, November 22, 2018

The Telephone Game

A person says "Turkey dinner, please!" on the phone. The message changes hands many times, ultimately becoming "Fifty bucks on the turtle to win, please" uttered by someone betting on a race between a tortoise and an hare.

There's a reason they make us play the telephone game in kindergarten. I'd like to think it's more than just that it's an interesting effect you can demonstrate in a small classroom.

I think that, on some level, it's an attempt to demonstrate one of the most fundamental problems faced by mankind, today. Maybe not consciously by the teachers, but I suspect somewhere in its origins lies a motivation along those lines.

For those of you unfamiliar with the telephone game, the classic version goes like this:
  1. The teacher arranges the children in the circle, with herself as part of the circle.
  2. The teacher whispers something to one of the children next to her. It's usually something simple and factual, like "There's a bow in Jennifer's hair, today."
  3. Each student whispers what they heard from the student next to them to the other adjacent student.
  4. The message travels around the circle, changing hands once for each student until it reaches the teacher.
  5. The teacher compares what the final message was with the initial version for the whole class.
Invariably, the message is mangled. Often, it is distorted beyond recognition. If you play the same game without whispering, the message keeps its original form, more or less.

The point of the game is to show that communicating via numerous intermediaries introduces error into the flow of information.

It rings true in business as well. Without a means of combating communication-error, you can be more or less certain that someone won't get what they want if they are asking someone to ask someone to ask someone for it.

Wednesday, November 21, 2018

The Atomic Asymptote

A man tries to eat a watermelon whole while someone out of the "shot" shouts "YOU CAN DO IT!!!"

If you're not willing to completely throw away a piece of work the moment something goes wrong, it's too big.

The bigger the slice of work, the more deeply you are invested. The more deeply you are invested, the less willing you will be to abandon work. The less willing you are to abandon work, the more that work must be "right" up front. The more you have to be right up front, the more timid you will be in selecting your changes. Since you so carefully pick your changes, you'll want to make sure they are big enough to be "worth the effort".

It's a vicious cycle that destroys any sense of safety and, consequently, and kind of speed.

There's no real harm in cutting past the point where you'd be willing to throw everything out when it goes wrong. It just means you'll throw out less when you find something did go wrong. In fact (you'll be surprised to discover on your own), you'll make fewer mistakes and have to discard fewer changes in the first place.

If you're looking for the right size of an increment of work, try "atomic". That is, try a slice of work that is so small it cannot possibly be divided into two smaller, complete efforts.

Failing that, get as close as you can by continuing to ask yourself this question:
How can I do less of this, now, and the rest of it, later?

Tuesday, November 20, 2018

For Any Pattern: Check to See if It Creates a More Needs-Oriented Interface

A person tells another person that his website, anything.biz, is so great. All you do is submit detailed manufacturing instructions and pay. The other person is not convinced.

Design patterns thinking tells us to design to interfaces. This has nothing to do with the keyword interface that is available in a lot of languages. It's about the English word "interface".

You know... the "I" in "GUI" or "API".

With few exceptions, a needs-oriented interface represents a better contract for a class than a capabilities-oriented interface would. The better-ness of this contract manifests in two ways:
  1. The coupling that forms will likely be long-lived and resilient to implementation-changes.
  2. It provides more context and drives better internal design decisions.
If you are considering whether or not a design pattern applies, try asking yourself if introducing the pattern will make the interfaces involved more about what should be accomplished or more about what should be done.

If the interfaces become more about what should be accomplished, that's a vote in favor.

If the interfaces trend toward a more imperative nature, you might want to reconsider.

Monday, November 19, 2018

Needs- and Capabilities-Oriented Interfaces

A mugger shouts "Gimme your wallet!" The victim replies "Sorry. I only carry a money-clip."

Among the many and varied ways to categorize interfaces is this one: needs-oriented and capabilities-oriented interfaces.

A needs-oriented interface is one that allows a client to ask for what they want. A real-world example of a needs-oriented interface is the mobile app for Lyft or Uber. You tell it where you want to go, negotiate and agree to terms such as cost and wait-time, and go there.

A capabilities-oriented interface is on that allows a client to ask for work to be done on its behalf. A real-world example of a capabilities-oriented interface a classic offset-barrel smoker. You control how much fire you have but adding wood, adjusting intake and exhaust vents, and leaving doors/hoods open or closed.

It's not that one is good and one is bad. They just serve different purposes.

An offset barrel smoker is part of an American tradition. There's an enormous amount of inertia around how it works. It's also very versatile. There are a lot of things you can do with an offset barrel smoker. Basically, an offset barrel smoker is part of the American Barbecue framework - it can be used in a lot of ways and it is okay - even expected - that it will not change.

Consider your programming language of choice. Can you think of a type that meets those requirements? It seems like the built-in collection types usually fit the bill.

Capabilities-oriented interfaces are really good for frameworks but they fall down when the fundamental assumption of a framework - mostly slow, primarily additive change - is violated.

Needs-oriented interfaces tend to withstand change a lot more readily. This is because a need doesn't usually transform into another need. It happens, but not often. Typically, a need either stays the same or goes away entirely.

Implementation details, on the other hand, can change on a daily basis.

What if the ride-sharing interfaces were focused on how you would arrange a ride rather than getting you where you want to go?

The moment something about fulfilling your need changed, the ride-sharing apps would have to change the interface to which you were coupled. If they brokered a sequence of text messages between you and potential drivers and suddenly text messaging was out of vogue, they'd have to change the interface and retrain a bunch of customers. If they get better technology, like driverless cars or single-passenger drones, they'd have to change the interface again.

Yet, by allowing you to express your need, the ride-sharing applications let themselves free to experiment with different processes and different means of conveyance.

The strength of a needs-oriented interface is that it will probably not change unless the associated need changes, which is rare. The weakness is that cannot typically be used by a wide audience in a large variety of ways.

If you are working on the .NET Core team or contributing to a broad-audience, low-level open source library, a capabilities-oriented interface might be the right choice. Otherwise, you probably want to focus on the needs being fulfilled when crafting a class, service, or application interface.

Saturday, November 17, 2018

Deja Vu and a Significant Number of "Why"s

The pattern seemed to repeat itself, possibly forever.

Again, Samantha sat in the darkness, with only the pale light of her laptop to illuminate her surroundings. Again, she was hunched over in concentration.

She leaned toward the computer and peered at the alien script through narrowed eyelids. It was a symbolic act, an expression of her focus more than an amplifier of it.

Kramer Code had struck again.

It had become a constant in her life.

On the phone, earlier that night her husband remarked that Kramer got more of her attention than he did. The back of her mind recognized he was only half joking.

Samantha had confirmed and rebutted in four words: "Attention? Yes. Affection? No."

The truth of it stung her, though.

Why should she have to stay late because he can't seem to get anything right?

Why did he always check in just before a release?

Why did none of the tests ever catch what he was doing?

The team had become so tired of it, that they turned on pull requests. The branching made things a lot slower but they hoped that requiring a certain number of approvals to merge might help.

Somehow Kramer always got around it.

Usually, the approvals came from another office in another part of the country or even on the other side of the world. Sometimes, Kramer bamboozled a manager into granting him a variance to let him merge something that was an emergency.

As with most of Kramer's code, the change was nearly irreversible. You could go forward, meaning fix what he had done, but you couldn't go backward.

In this case, as was most of the cases, the code misused some data fields, redefining their meaning in the process.

Reverting the Kramer Code would produce an application that was still broken because the old version of the application couldn't use the new data and there's no easy, automatic way to reverse the change to the data.

Kramer had left Samantha between a rock and a hard place: fix the code or fix the data.

There was no "go back to green". Not for the customers who failed to back up before updating, which is most of them. Not for the customers who want to keep any of the data they have collected since, which is the rest.

Kramer Code was usually just hard enough to deal with that she could crack it but, this time, she was at a loss. It looked, to her, like Kramer had created irreparable data loss.

The only thing Samantha could imagine was to fix the code, create a space for the lost data, and create some kind of migration utility that allowed customers to merge the data they had lost out of a backup.

That was the path of least destruction.

Samantha fired off a note to Fred. Without a body, the message read "Should we forcibly back up before every update?"

She let her mind relax and her focus slackened. Idly, she clicked around, bouncing from class to class. She was thinking but not really about what she saw.

Then she saw something that snagged her attention.

It was a little class called DataTransformMediator. Something kind of strange. Without drilling into the classes to which it delegated, it appeared to copy data out of some entity objects and into a malleable document which would be stored in a non-relational database.

What caught Samantha's eye was that the mediator in question seemed to be coordinating preservation of the exact fields she thought Kramer had destroyed.

She was already VPNed into a client's network, so she opened up their DocumentDB instance and searched for the records related to an affected entity.

"I'll be damned..." she said. "Gotcha."

She minimized the virtual desktop, exposing Visual Studio and started creating a new utility. One that would clean up the affected document databases, repair the affected structured databases, and rollback the Kramer-affected deployment all at one time.

A blinding glare flooded through the window from what appeared to be a yellow ball of hellfire snuggled between two gigantic pines.

"Morning," said Samantha. "Guess I'll get to it."

A parking lot with the sun peaking through between two pines.

Friday, November 16, 2018

New Barista

A manager shouting at one barista that all his drinks get sent back and the barista's defense being that he makes twice as many as another barista named "Rick". Nearby, rick carefully places a drink on a counter.

The other day, I ran into Starbucks to get something for my wife. She wanted a Brulee Latte.

It was the end of the day and the more seasoned baristas were letting the new guy make what appeared to be his very first drink.

I thought to myself. "Great. Lucky me."

The guy took a long time but I'm glad he did. The reason he took so long was that he was making sure he did everything exactly right.

He double-checked the mixture to make sure he had the right number of shots. He carefully distributed the whipped cream to make sure it was done correctly. He tried shaking the large-grain sprinkles on to three different ways before he found a technique that got the right amount out of the shaker.

By the end of watching him make the beverage, I thought to myself "This guy's going to be alright."

Sure, it took him a long time to make my drink but it would have taken even longer to make it a second time after I sent it back for not being done correctly. He avoided that extra cost immediately but there's an even more important benefit to the way he went about making that drink.

The next time he has to make a latte with sprinkles, he'll use the technique he learned making the one I bought. As a result, he'll be a little faster. He'll carefully apply the whipped cream in the same pattern but he'll be able to do that a little faster, too.

Maybe he'll keep double-checking the number of shots a few more times but, eventually, he won't need to do that, either.

Every time he makes a drink, he'll make it just as accurately as the first time but he'll be able to do it a little more quickly. Eventually, he'll be fast and good.

If he'd focused, instead, on getting some sloppy splash of liquid out the door, he probably would have taken longer in the short run and it's doubtful that he'd get any faster or more accurate in the long-run. Had he made that choice, he would have flunked out of Starbucks.

I doubt Starbucks is this guy's ultimate career path - although it may be. Yet, wherever he goes, I'm sure the kind of decision making he exhibited that night, making that first latte, will serve him well.

Bon chance, barista whose name I didn't think to catch.

Thursday, November 15, 2018

For Any Pattern: "Does This Allow More Objects to Each Deal with Fewer Things?"

An expert woodsman or carpenter is better than one person who does both...at least in code.

One of the principles of design patterns thinking is favoring delegation between objects over inheritance from one class to another.

I think we can actually expend that if we want to:
Favor delegation between objects over the same object doing two things.
Remember, when you inherit you end up with one object even though you wrote two classes. So the way I just wrote it still works for inheritance but it also works for, say, lumping everything together into a giant algorithm.

Note: Not more classes. More objects.

If you are considering a design pattern for your codebase and you're not certain if it applies, ask yourself this:
"Does this allow more objects to each deal with fewer things?"
If so, you may be headed in the right direction. If not, maybe consider a different approach.

Wednesday, November 14, 2018

For Any Pattern: "Does This Make Something Less Aware of a Kind of Variation?"

A car is on a road. There's a dirt road leading off to the left between some trees. A passenger says "They said turn left at the trees!" The driver says "I can't. I don't know how to turn left onto a dirt road."

If you have alternatives - different kinds of things that can be used to replace one another or, sometimes combined with one another - then you have variation.

Design patterns thinking tells us that we should encapsulate variation. That's the kind of thing that is obvious once you already understand it (the hallmark of a good idea) but turning the advice into action can be challenging for people at first.

The immediate goal isn't really to make code less aware of the fact that there is variation so much as making your code so it doesn't need to change when you add or subtract a variant.

So, it's not that we're trying to hide variation altogether. We just want to minimize its impact on most of the code. We are seeking to lessen awareness, not eliminate it altogether.

If you are considering a design pattern for your system, and you aren't really sure if it's the right way to go, ask yourself this:
"Does this make something less aware of a kind of variation?"
Or...
"Does this make something less aware of the variants in a kind of variation?"
If the answer is "no", you aren't attending to the fundamental value-proposition of design patterns thinking and there's a good chance you should be considering another path.

Tuesday, November 13, 2018

For Any Pattern: "Does This Help Me Couple to an Higher-Level Abstraction?"

A sign indicating the steps to use a gas pump: insert dinosaur, age 100,000,000 years, refine gas, fill car.

One of the things that design patterns thinking is supposed to help you do is elevate the level of abstraction in your code. That doesn't just mean "write more interfaces" or "use ore abstract classes/protocols".

What it means is try to move the points of coupling away from the metal. The more a coupling point is about implementation details, the less useful it is and the shorter is helpful life will be. That is especially true an high-traffic interface but, really, it's true for the surface area of any piece of code.

So, if you are considering a design pattern and aren't quite sure if it applies to your situation, ask yourself this question:
"Does this help me couple to an higher-level abstraction?"
If applying the design pattern will make the interfaces (not the keyword interface, the English word "interface") a little more about "what" and a little less about "how", you might be on to something. If it cuts the other way, you may want to reconsider.

Monday, November 12, 2018

Honesty

I think that most of the misleading information in the world stems from people not being honest with themselves. I don't know that I could prove it for the whole of mankind but I think it would be pretty easy to design an experiment that showed this to be true for businesses.

The someone asks you a question and your answer is self-congratulatory, take a beat and ask yourself if there are any other answers that might make sense.

A person looks in a mirror with an angry mob behind it and says "Look at the happy person!"

Friday, November 9, 2018

But Will it Work Here?

Above the earth. A pod is on its way to a space station. The Earth radios "We're sending up an emergency oxygen resupply while we prepare a rescue plan!" The space station answers "Yeah...but can we breathe it HERE?"

It happens with alarming regularity. Everywhere I go; almost every team I meet; with the majority of the people whom I have mentored, there is always this question: "Yeah...but will it work here?"

The implication is that this place is special. This place has a different set of circumstances which exempt it from needing to learn TDD, design patterns or refactoring.

Yet these techniques are established. They are proven beyond any reasonable doubt and on a broad scale. There might be something better coming in the future but it's not a resurgence of the old ways.

Those three disciplines work, largely, because they aren't sensitive to where they work. There's nothing special about any environment.

Your circumstances aren't special.

Test-driven development, design patterns, and refactoring are what software development is. If they don't work in your environment, it's because software development doesn't work in your environment.

Thursday, November 8, 2018

Design Patterns and Code Qualities

A friend of mine recently intimated that we don't need design patterns because all the principles and patterns can be derived from code qualities.

It's true. Patterns can be derived from the principles of code qualities...the same way aerodynamics can be derived from quantum mechanics.

Wednesday, November 7, 2018

Design Patterns Questions

Two people standing next to one another. The first says "How do I know if this is the right pattern?" The second says "All that matters is WHAT'S IN YOUR HEART". In large, red letters the word "wrong" sits between them with an arrow pointing to the second guy.

Like code qualities, I'm going to start sharing questions you can ask yourself to help sort through which design pattern applies where.

As I add questions to the set, I expect it to grow into a checklist someone can use to evaluate whether the pattern they are considering is the right one for their situation.

I'm not expecting to create a perfect result every time. I'm happy with better results some of the time.

There will be two categories of question: general and specific.

General questions apply to every pattern. For instance "What variation does this let me add without changing any existing code?" applies regardless of what pattern you are considering.

Specific questions apply to one pattern or a small group of patterns. For instance "Do I need to decouple when something happens from when the decision is made that it should happen?" applies primarily to the Command pattern.

The label for this post will also be on all such questions.

Tuesday, November 6, 2018

When All You Have Is an Hammer...

A lot of the time, when I come into an organization and look through their code, it's really easy to tell when one of the more gung-ho developers just learned their first design pattern.

Suddenly, there's an area of the code-base where everything looks like the Visitor pattern diagram or the Observer pattern drawing.

It's easy to fall into this kind of trap. Not everyone does but I haven't done the science to figure out what, if any, extrinsic factors affect whether or not this happens. I doubt anyone has.

I didn't have it happen and it's really easy to trace why. I had already "invented" the design patterns long before I was exposed to the book. Before the book was even written, really. My difficulty with patterns was "Why should I use these?" not "How can I make these useful?" I'm sure plenty of developers my age had that same experience.

I know a couple of people who were introduced to design patterns on my watch and who didn't seem to go through the "everything is this pattern I just learned" phase. Yet, I know a whole lot of people who went through that phase, regardless of who introduced them to patterns.

It's probably okay.

It's more important to find your way out of it than it is to avoid getting into it.

There is one defense I can imagine. I have no proof it will work but it probably can't hurt. Whenever you realize you are trying to bend a problem to fit a pattern, remind yourself that you should be finding the pattern that fits the problem, instead.

Monday, November 5, 2018

Cultural Momentum

Two panels with identical elements: A spaceship, an alien, and two cavemen. On the top, the alien says "So that's how plant use your sun's energy. Now let's talk about the speed of light." The cavemen shout "KILL IT!" The background is red. On the bottom, the alien says "Try digging ditches near streams to grow more food." One of the cavemen shouts "GREAT IDEA!" The background is blue.

I have a friend who is going through The Fountainhead. That's as of the time of this writing. He reads fast, so it probably won't be true when this post is published.

Without debating the merits of this book, there's a particular part that he was discussing with me, recently, which I think is relevant to everything.

Near the beginning, the main character (Howard Roark) is chastised by the dean of his college for not doing what has always been done. This is done in a very ham-fisted way where the dean basically explicitly states that we have to keep doing what our ancestors did.

My friend's objection to it was the fact that the conversation seemed hyperbolic (my words, not his), not to the point being made. Yet, the problem is actually a very common one.

Though it's typically presented more subtly, culture does exhibit inertial properties. This is as true for corporate cultures as it is for national ones.

What does that mean for us?

It means we have to slow down. A lot.

It's easy to know where we want a culture to go. It's possible to personally adopt skills, disciplines, or even a new mindset pretty quickly.

What's hard is to alter the culture of a large body of people faster than that population will accept.

If you chisel away at a culture, you can make a cumulative difference. If you try to be an iconoclast, you're more likely to be ousted or ignored than you are to make a real impact.