Recent Posts (page 22 / 65)

by Leon Rosenshein

Mutators and Accessors

That’s often how they’re taught, but really, they’re just another name for getters and setters. They’re a great way to encapsulate things. After all, you don’t want folks depending on the internal implementation of things. You want high coherence and low coupling, right? 

Or, are they a code smell, otherwise known as Accessors are Evil? Consider the lowly Rectangle class. Does a getter really give you isolation? Instead of declaring a public member Foo of type int you have a private foo and a public method Foo. Is that really any different? You’re exposing the internal structure with your getter. The only difference is some extra typing. Setters are just as bad. But what’s a poor developer to do?

The first thing to do is change how you think about it. Instead of mutators and accessors, think of the interface of your object as a set of commands and queries. You’re not changing the properties of the object, you’re telling it what to do itself, or asking it questions about itself. That’s isolation and encapsulation.

Sure, under the covers it might look the same. Ask the rectangle what it’s height is and you get back the height. Which might be stored as a member variable. Or it might not. But it doesn’t matter because you’re not asking the rectangle for internal data, you’re asking for it’s external property.

The same thing applies on the setter side. Don’t double the height and width bindly. Send the rectangle a command. Tell it to be twice as tall and twice as wide. Again, for a simple rectangle it might look like a setter, but it’s not. It’s an interaction with an object, A verb. A command.

It’s the difference between Object Oriented Programming and Programming with Classes. Superficially they’re the same thing. Especially in school. But when your objects get more complicated than rectangles, triangles, and circles it starts to matter.

So the next time you’re looking at the public API for your class/library/service/tool, think about how you’re thinking about it. Are you just putting some static sugar around the internal state, or are you presenting an API that drives users towards the domains and isolations your system is built on. And think about which one is going to be better for you and your users next week, next month, and next year.

by Leon Rosenshein

Another 4 Questions

Not those 4 questions, but the 4 variations of one very specific question, Why are we building this?

Why are we building this?
Why are we building this?
Why are we building this?
Why are we building this?

Because until you answer the 4 variants, you haven’t answered the question. There are lots of things we can/should build. Assuming there are some form of constraints, we can’t build them all. So which one(s) should we build?

Start with the first variant, “Why are we building this?” What’s the value proposition? To the customer and the company. If it’s cool, but not something the customer wants (or a step on the path to get there), why?

“Why are we building this?” Are we the right team to build this? We might need it, but should we be building it? Does our team have the right knowledge/experience? Are there other teams or platforms that are a better fit?

“Why are we building this?” The classic build or buy question. Are we looking for a capability that is easy to buy on the open market, or is this part of the special sauce needed? There are costs both ways. Buying has a clear cost, and developing a solution has a cost that can be measured, but maybe not predicted. Even free open source software has a real operating cost.

“Why are we building this?” Should we be building something else first? And here, I mean first from a sequencing standpoint, not priority. If A depends on B, which depends on C, you should probably start with C, or at least as much of it as you know. If you build A first you’ll either need to change it significantly when you finish C or you’ll severely limit your options when it comes to C. Going the other direction lets you build on things, reacting to new information as it comes.

Which brings to Wardley Mapping. A way to use the answers to those questions, as applied to the various things you need to do, to help you figure out how to allocate your precious resources. The classic Wardley map is a simple 2D plot of linked components. The Y axis represents the customer/user value, which higher value being higher on the plot. The X axis represents the “maturity” of the component, with “No one’s ever tried this before” on the left, and commodities (cheap to buy exactly the right thing) on the right, and the ability to outsource it somewhere in the middle. The things at the top left are the most important to the customer and hardest to obtain. The things at the bottom right are mostly invisible to the user/customer and easy to buy.

Then, you link the components by direct dependency. What other things do you need to get the most important thing done? The further to the left the more likely it’s worth using internal resources for. The further to the right the more likely the right answer is to buy the solution.

Or, to put it simply, if you need a ½ inch hex bolt, buy one, don’t build a foundry. But if you need a fiberglass layup with compound curves around an assembly you’re still designing do it yourself.

by Leon Rosenshein

Simple Fixes

So I’ll need you to replace the cat-3 cable from port AA-825 with a new cat-5 cable to desktop SPA-251. And I need it for a demo in 10 minutes. What do you do? And for context, here’s the current status

A tangled mess of cables

If you really need to do it in 10 minutes what you’re probably going to do is unplug the cable in port AA-825 and run a new cable around that lump and route it to SPA-251. If you get it done in 9 minutes, you might write down that port AA-825 is connected to SPA-251. If you’re really fast and get done in 8 minutes you might even do something about the cable you just unplugged. But you probably won’t have time.

Instead you get what happened to me last week. The house my daughter and her roommates live in has a laundry room on the main floor. It’s got a laundry chute from the 2nd floor, hot and cold water, a drain line, and 120V and 240V outlets ready to go. But a previous renter wanted more pantry space near the kitchen, so they moved the laundry room to the basement and put in shelves.

My daughter and her roommates decided they wanted to have the laundry back on the main floor, so I took the shelves out and hauled the washer and dryer back upstairs. Hooked up the washer and all was well. Brought the dryer up and plugged it in. No workee. No electricity. Checked the circuit breakers. All on. Checked the sub-panel. All on. But somewhere between the breaker panel and the laundry room the electricity disappeared.

It’s someone else’s property, so I call the electrician. $100 later he confirms that there’s no electricity and gives us an estimate. $3K to run a new line. Because there’s no way of knowing where the problem is, or if it’s fixable. My guess is that somewhere in the basement ceiling, hidden behind a nice new piece of drywall, is a splice that comes off the old dryer line and goes to the new one. But there’s no way of finding it without removing lots of drywall. In this case the fix is going to be to haul the washer/dryer back to the basement.

There were at least 2 better solutions when they moved the dryer to the basement. Put the splice in an accessible junction box or run a new line from the basement sub-panel. If either of those two solutions had been used I could have fixed things, and for minimal cost. No cost if they ran a new line, and probably $10 if they had the exposed junction box. Running a new line would probably have cost a few hundred more at the time, so not doing that makes sense. An exposed junction box might have cost $10 more. Even less if there’s an unexposed junction box behind the drywall.

But they took neither of those routes. Instead, I’m out $100 and it would cost $3K to fix the outlet. So now there are extra loose wires hanging inside the walls, and the dryer stays in the basement. I lost money and I lost options.

That’s the real cost of cost control.

by Leon Rosenshein

Synergy

Synergy - 

the interaction of elements that when combined produce a total effect that is greater than the sum of the individual elements, contributions, etc.; synergism.

Or, put another way, emergent behavior. Put a bunch of simple things or rules together and see what happens. DNA is only 4 base pairs, and the combinations are limited, but somehow, when they combine in the right ways you get people. Or viruses. And everything in between. Logic gates, whether they’re vacuum tubes or solid state, are either open or closed, 0 or 1, but put them together the right way and you have a computer. Or a self driving truck.

Another classic example of emergent behavior is Conway’s Game Of Life. Three simple rules, but endless possibilities. From static images to glider guns. And to top it off, small changes to the rules or initial conditions produce radically different results.

It’s about how observable phenomena emerge from the well defined and understandable interactions of entities. It can be seen at all levels. From DNA base pairs to societies. At each step along the way entity interaction becomes phenomena, where are then the entities that interact at the next level.

Which leads to Conway’s Law. It’s the same Conway, and another example of emergence.

But things can go both ways. Software can look like the organization, but the way the software is built and put together can also drive the shape and culture of the organization. The strength (or openness) of the walls between parts of your code can drive the org. Simple, reliable, straightforward APIs encourage others to find new and better ways to use them. Ways that you aren’t thinking about when you build them, Ways that only become apparent when you look at them not as phenomena to be used, but as part of the set of entities and interactions at the next level.

Just something to think about as you build your APIs/interfaces. So that the synergy can emerge.

by Leon Rosenshein

Tenure

Today’s rant. How do you stay in the same job for more than 2 years?. According to the article, the answer is, you shouldn’t. That’s definitely an answer. And depending on your goal, it might work for you. But the cynicism and self-centered nature of it rubs me the wrong way.

I mean, objectively the statements are mostly true, but it’s the intent behind them I don’t like. Especially #4. 

You need to leave before the decisions you made bite you in the ass.

If you’re not around to experience the impact of your decisions then you don’t have to deal with the consequences. You also don’t get to learn from them.

Version 1 of something is easy. A green field, no expectations, and a clear problem to solve. So you solve some of it and release. People are thrilled to have something.

Version 2 is almost as easy. You add the things you wanted to add, but ran out of time for. You might fix some bugs along the way, really, it’s about finishing what you started. No significant changes, so no issues with earlier decisions.

Version 3 on the other hand, is a whole different kettle of fish. Your users have had time to get used to what you built, and find the ways it doesn’t work for them. And give you feedback about it. Of course, you have multiple users, so the feedback is conflicting. Some of the new requests say do more X, and others say do less X. A group of users think Y would be wonderful, and you agree, but you’ve never thought about that.

This is where the decisions you made before you knew better really stand out. How do you maintain compatibility with what you did, while doing the new thing? That’s where the learnings are. That’s where the personal growth is. That’s where the impact is. And you can’t get that if you change companies every 2 years.

If you were to ask me, I’d say if you’re a developer doing the exact same thing, trying to solve the exact same problem the same way, for 2 years it’s time to rethink things. Are you growing? Learning? Having an impact? Probably not. It might be time for a move.

On the other hand, if you’re learning, growing, and having an impact and want to keep doing that then what you probably want is a scope or role change. That will let you grow even more. And learn from your decisions, not run away from them.

by Leon Rosenshein

Autonomy != Anarchy

Autonomy is more than a car or truck driving itself. According to dictionary.com it’s

independence or freedom, as of the will or one's actions

But what does it really mean? Especially to a team, working with other teams?

Autonomy is power. The power to decide, for yourself or your team, what the right answer is. The power to decide how to achieve that result, The power to decide how to present and share that result,

By that definition the difference between autonomy and anarchy isn’t that big. It could be argued that they’re the same thing. Certainly if you have anarchy then you have autonomy, But I’m pretty sure that anarchy isn’t the best way for a group of developers to get something done.

While autonomy can mean the freedom to choose to do whatever you want, in this context it doesn’t. It means understanding the end goals and constraints and having the freedom, the autonomy to act within those constraints to achieve the goals.

It also means that you have a bunch of responsibilities. Of course you’re responsible for meeting the agreements you’ve made. But you’re also responsible to communicate. To communicate status. To communicate when expectations change. To communicate when your needs change. Again, autonomy doesn’t mean do what you want when you want and don’t think about the consequences.

The key is to balance the power and the responsibility. To maintain alignment between your autonomous decisions and everyone else’s autonomous decisions and the shared goals. To understand that while you have the power to do what you want, you’re working towards a shared vision and what’s best for you isn’t necessarily best for the vision. It’s easy to confuse a personal maximum for a team maximum. Especially if all you look at is speed. Just because you’re moving as fast as you can doesn’t mean you’re adding the most value. 

Or, as Uncle Ben said, “With great power comes great responsibility.”

by Leon Rosenshein

Perspective

You’ve probably seen this before, maybe you’re one of today’s lucky 10000.

What’s the number of the covered parking spot in this image?

Parking spot numbers 16, 06, 68, 88, ?? 98

When I first saw this I had no idea. Eventually I decided it had to be 128. Because pairwise, 16 - 6 = 10, 68 - 88 = -20, so x - 98 = 30. That’s a stretch, but it made some sense.

Of course, for parking spot numbers that makes no sense. Who would number parking spots like that? You’d never find your parking spot, and there would be duplicates. Really bad idea.

On the other hand, it’s all a matter of perspective. If you look at it this way, it seems pretty obvious.

Parking spot numbers 86, ?? 87, 88, 89, 90, 91

In this case it’s clearly 87. And that makes sense from a real-world parking lot perspective as well.

So what do we learn from this? We learn that our perspective, our biases, can change how we solve problems. 

Back in my aerial imagery days we had to deal with lens distortion. We needed to minimize it to get the most accurate images possible. Lots of effort went into multi-part lens design and construction. Managing thermal deformation, both during lens grinding and after installation was important. Things had to be just right. And we still couldn’t get rid of the distortion.

So we cheated. Or rather we looked at the problem from the other direction. Given a perfect test image, in our case a grid of points, and an actual image, what kind of post-capture transformation did we need to do, at the pixel level, to get the correct image. We couldn’t calculate it before hand, but we could easily measure the deltas. So we did. Then we inverted the direction. And then we applied them to all of the raw images. Which removed (almost) all of the distortion.

So what are currently you doing at one end of a pipeline that you could do more easily at the other?

by Leon Rosenshein

Inspect And Adapt

Agile. XP, Scrum, SAFe. Software development methods. Agile software development methods. They all have their trademarks. Processes and artifacts that you should do and produce that will lead you to high performance. Just follow the rules and it will happen for you.

There’s a basic assumption in there that may or may not be correct though. As Tolstoy put it, 

All happy (high performing) families (teams) are alike; each unhappy (low performing) family (team) is unhappy (low performing) in it’s own way.

It’s that assumption that drives the methods. All high performing teams are the same, so if you do those things you’ll be a high performing team.

But is that really true? It Depends. It depends on how you look at it. From the outside all the happy families/high performing teams look the same. They get things done. They exceed expectations. Meanwhile, at the other end of the spectrum you might see internal fights, distrust, lack of direction/purpose, sullenness, or just plain anger.

If you look a little deeper though, you might have some different insights. The highest performing teams have figured out what works best for them. The right balance of collaboration, autonomy, agency, and direction. It’s going to be different for every team. Because teams are made up of individuals. And every individual is different. And the combination of those different individuals is even more unique.

On the other hand, many (most? all?) low performing teams have a lot in common. The biggest is that they’re often not a team, but a collection of individuals. Without common purpose and goals. Without a shared vision. So while the specific, outwardly visible signs might be different for each of them, the internal issues that are the root cause of the low performance are the same.

It seems to me that if you want to end up at that high performing state, what it really comes down to is the way the team operates being agile. That means some variation of the “inspect and adapt” principle. Look at what you did. Think about what you want. Adjust things to be closer to what you want.

Not closer to some externally defined process/norm/ideal, but closer to what the team (and the customer) defines as ideal.

by Leon Rosenshein

Obligations

api

When we talk about incident management there are lots of things to keep in mind, and priority is important. My formative years were in aviation so to keep the priorities in order I always think of it as aviate, navigate, communicate.

Something bad happened. First and foremost, keep the airplane flying, don’t make or let it get worse. Find someplace safe to land. Figure out how to mitigate the problem. Call ATC and declare an emergency and keep them informed. Open an incident and update your customers. That’s the priority, and in the heat of the moment it’s important to keep your priorities straight.

But that’s the priority order. Just because something is lower priority, it doesn’t mean it’s less important. In fact, over the long term the last part, communication, can be more important than the others. Because properly communicating the experience and following through on the learnings can keep the problem from happening again.

Consider this. One of the things that often happens during an incident is that a quick fix is put in place to alleviate the symptoms. You find that suddenly your service is taking twice as much memory and crashing. So as a mitigation you allocate 2x the memory and things are working again. You’re done, right. Time to head home and celebrate.

It might be time to celebrate, but you’re not done. That quick fix is a pressure cooker, quietly sitting there until the next time it explodes and takes out your service again. You might even be able to keep turning up the allocation a few times, but you haven’t solved the problem. It will come back and bite you later. At some point you’ll need more memory than you can get. What are you going to do then?

In reality, that quick, brittle fix is an obligation you’ve taken on. An obligation to yourself, your team, and the business. An obligation to take the time to fix things the right way. The forever fix that identifies why it happened and keeps it from happening again. Because incidents happen. What’s important is how we deal with them.

by Leon Rosenshein

Keeping Your Balance

Macro vs Micro. Explicit vs Implicit. Small functions vs Big Functions. Up front design vs YAGNI. Like many things software, It Depends. It’s a question of balance.

But what are you balancing? In most cases, when you get down to it, what you’re balancing are the perceived/expected needs of the future against the needs of the moment. In conjunction with the known cost now compared to the potential cost later.

The needs of the moment are clear. Your customers are talking to you about them daily. You’re looking at metrics and error rates and other real-time feedback. You’ve committed to delivering something specific to solve a specific user problem.

Then there are future needs. Some are easier to predict/quantify than others. Someone, likely you, will need to maintain the code you write today. Usage will probably go up. Computers will get faster. Data rates will almost certainly increase. You can count on those things. You should design and code for those changes. It might cost a little more now, but it will pay off tomorrow.

Other future needs aren’t as easily knowable/quantifiable. Will you need microservices next year? Will your domains change, and if so, how? How will market changes impact business goals? What’s your vision and mission, how might they change, and what impact will that have on your plans? And if you don’t know the changes, how can you know the cost of those changes?

Which leaves you to balance the two timelines. You need to think enough about the macro/long timescale side of things to keep from painting yourself into a corner. You need to move quickly and solve today’s problems today. You can’t spend so much time thinking about the future that you don’t take care of the immediate. You can’t spend so much time working on the immediate that you never plan for the future.

You need to keep the two in balance.