Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Solid code isn't flexible

Solid code isn't flexible

Chris Keathley

September 02, 2022
Tweet

More Decks by Chris Keathley

Other Decks in Programming

Transcript

  1. How do we make it easy to change software? How

    do we add new functionality without changing any existing code?
  2. Lets Talk About: Fundamental Ideals Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  3. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  4. HTTP Client Socket Management SSL Connection Pooling h1.1 vs h2

    Parsing http payloads Essential C om pl ex ity
  5. Premise 2 All code has a cost. Anything we add

    to the system should add significant value.
  6. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  7. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  8. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  9. HTTP Client TCP Y ou sh ou ld on ly

    have to see this stuff Not this…
  10. Red Flags Excessive passthrough or defdelegates Layered modules that share

    similar apis or functions Changes impacting multiple dependencies Pushing specific details into lower levels decreases reuse
  11. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  12. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  13. Handler Ecto Cache Are we g oi ng to need

    to tune this? Background Task
  14. def get_posts(id) do case :fuse.check(:service) do :ok -> case call_service(id)

    do {:ok, result} -> :ok = Cache.put(id, result) {:ok, result} {:error, error} -> :fuse.melt(:service) {:error, error} end :blown -> cached = Cache.get(id) if cached do {:ok, result} else {:error, error} end end end
  15. def get_posts(id) do case :fuse.check(:service) do :ok -> case call_service(id)

    do {:ok, result} -> :ok = Cache.put(id, result) {:ok, result} {:error, error} -> :fuse.melt(:service) {:error, error} end :blown -> cached = Cache.get(id) if cached do {:ok, result} else {:error, error} end end end H ow does this s er vice int er act with the cache?
  16. def get_posts(id) do case :fuse.check(:service) do :ok -> case call_service(id)

    do {:ok, result} -> :ok = Cache.put(id, result) {:ok, result} {:error, error} -> :fuse.melt(:service) {:error, error} end :blown -> cached = Cache.get(id) if cached do {:ok, result} else {:error, error} end end end Finding a bug means reading the functi o
  17. def get_posts(id) do case :fuse.check(:service) do :ok -> case call_service(id)

    do {:ok, result} -> :ok = Cache.put(id, result) {:ok, result} {:error, error} -> :fuse.melt(:service) {:error, error} end :blown -> cached = Cache.get(id) if cached do {:ok, result} else {:error, error} end end end This is a “C om plete” Functi o
  18. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  19. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension
  20. defmodule Animal do def speak(f) do f.() end end dog

    = fn -> "bark" end cat = fn -> "Worship me you lowly human" end Animal.speak(dog) Animal.speak(cat)
  21. Mentat.fetch(:posts_cache, :key, fn key -> case Service.get_posts(key) do {:ok, resp}

    -> {:commit, resp} {:error, e} -> {:ignore, e} end end)
  22. defprotocol MyService do def get_posts(impl) end defmodule MyService.HTTP do defstruct

    :url, :fuse defimpl MyService do def get_posts(%{url: url, fuse: fuse}) do case :fuse.check(fuse) do :ok -> Req.get(url) :blown -> {:error, Error.unavailable("Service is down")} end end end end
  23. defprotocol MyService do def get_posts(impl) end defmodule MyService.Mock do defstruct

    fake_response: %{} defimpl MyService do def get_posts(%{fake_response: fake_response}) do fake_response end end end
  24. Machinery Behaviour Behavi ou rs ar e g oo d

    when y ou c on tr ol the machin er y arou nd them
  25. Lets Talk About: Fundamental Ideas Deep Layers vs Shallow Layers

    Things are better together Allowing for extension