Skip to content

Instantly share code, notes, and snippets.

@gweakliem
Last active August 13, 2019 02:23
Show Gist options
  • Save gweakliem/ca9beebb6f036a00f89f3a7dacfcbac3 to your computer and use it in GitHub Desktop.
Save gweakliem/ca9beebb6f036a00f89f3a7dacfcbac3 to your computer and use it in GitHub Desktop.
Venkat S Don't walk from complexity, run!

Don't Walk Away From Complexity, Run

August 12, 2019

"If only management gave me the opportunity" Only constant is change. Point of Agile the ability to adapt to change.

"I've set the wedding date. I've not asked her out yet." -- how software projects are managed @venkat_s https://twitter.com/venkat_s/status/617052918491918336

Complexity makes it hard to adapt to change

System design is complicated by nature.

Complexity comes from

  1. Problem domain
  2. Solution space - maybe we made the solution more difficult than necessary?

We're victims of our own complexity. We create solutions for problems we don't have. So what makes systems complex?

  • Too many moving parts - if you require a plotter to print system diagram, you're in trouble.
    • We can become unable to respond to change because of the complexity.
    • Brittle, error prone, hard to deploy, hard to test, hard to reason
  • Invisible changes
    • 2 kinds of frustrating code: code that doesn't work, and code that works but shouldn't
    • Don't sneak around and change state
    • Shared mutability is the devil's playground
    • Look at Java Runnable - run() takes no input and gives no output, the only way to work with it is shared mutability.
    • "Mutability needs company, so it hangs around with bugs"
    • State transition causes brain damage. It's like trying to write code and having someone interrupt you.
  • Lack of cohesion - cohesion leads to building blocks.
    • Excessive dependencies - things quit working because of things not under your control.
    • There is a benefit to using someone else's code, but there's also a cost in the long run.
    • Dependencies are hard - they go obsolete quickly, they become incompatible.
    • As a dev, an architect, a tech lead, part of our responsibility is to learn new things, try them out on toy projects, and have the wisdom not to use them in production.
    • Reversibility - the ability to back out of design & architectural decisions. Also, just because it's possible doesn't mean it's realistic.
    • Library vs. Framework - Framework is a much bigger commitment. The use of a library is easier to reverse than the use of a framework.
    • Pace of adoption has increased so much, it's really hard to stay on top of it.
  • Accidental Complexity: see "Java Concurrency in Practice".
    • Ex: Java concurrency requires stating when the process crosses the memory barrier.
    • i.e. Java concurrency is like the Horcruxes from Harry Potter, you don't know what they look like or where to find them.
    • Imperative style is packed w/ accidental complexity.
    • "Let me figure it out" - means the code is loaded w/ complexity.
  • Entwinement
    • finalize() should have been named badIdea() because it may never be called. Simple to demonstrate, create an object with a finalizer and exit main immediately. finalize() is now deprecated.
    • Ask yourself if you're entwining things that don't belong together.

Summary:

  1. Too many moving parts
  2. Invisible changes
  3. Uncontrolled Mutability
  4. Lack of Cohesion
  5. Excessive Dependencies
  6. Technology Infatuation
  7. Low level concurrency
  8. Imperative Style
  9. Accidental Complexity

Maintainable code is a gift we give ourselves for the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment