Technical Practices for Sustainable Code - Chicago Code Camp 2019

Technical Practices for Sustainable Code - Chicago Code Camp 2019

Slidedeck from presentation at Chicago Code Camp 2019

5b92c5ea42bc2c2ab28d973d5da63cd6?s=128

Quinn

May 11, 2019
Tweet

Transcript

  1. @TheQuinnGil https://QuinnGil.com with Technical Practices for Sustainable Code Feature Parity

    in 25% of the Dev Hours
  2. @TheQuinnGil https://QuinnGil.com Technical Practices for Sustainable Code

  3. @TheQuinnGil https://QuinnGil.com Quinn Gil Blog -- QuinnGil.com Twitter -- TheQuinnGil

    Github -- Fyzxs
  4. @TheQuinnGil https://QuinnGil.com This is for you.

  5. @TheQuinnGil https://QuinnGil.com Sustainable Code

  6. @TheQuinnGil https://QuinnGil.com Why? Sustainable Code

  7. @TheQuinnGil https://QuinnGil.com What’s Our Job? Sustainable Code - Why?

  8. @TheQuinnGil https://QuinnGil.com Sustainably grow the value of the company’s digital

    assets. Sustainable Code - What’s our job?
  9. @TheQuinnGil https://QuinnGil.com I’m Lazy Sustainable Code

  10. @TheQuinnGil https://QuinnGil.com How? Sustainable Code

  11. @TheQuinnGil https://QuinnGil.com Mindset Change Sustainable Code - How?

  12. @TheQuinnGil https://QuinnGil.com Technical Practices Sustainable Code - How?

  13. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices

  14. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  15. @TheQuinnGil https://QuinnGil.com But First!

  16. @TheQuinnGil https://QuinnGil.com Fully Test Behaviors Sustainable Code - Testing!

  17. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  18. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  19. @TheQuinnGil https://QuinnGil.com No Getters / No Setters Technical Practices

  20. @TheQuinnGil https://QuinnGil.com Technical Practices - No Getters / No Setters

    class FizzBuzzBag{ public int Input{ get; set; } public string Result{ get; set; } } class FizzBuzzBag: def __init__(self): self._result = None self._input = None @property def result(self): return self._result @result.setter def result(self, value): self._result = value @property def input(self): return self._input @input.setter def input(self, value): self._input = value class FizzBuzzBag{ private int input; private String result; public String getResult(){ return result; } public void setResult(String value){ result = value; } public int getInput(){ return input; } public void setInput(int value){ input = value; } } class FizzBuzzBag attr_accessor :input attr_accessor :result end
  21. @TheQuinnGil https://QuinnGil.com Technical Practices - No Getters / No Setters

    No Way
  22. @TheQuinnGil https://QuinnGil.com No Getters / No Setters Technical Practices

  23. @TheQuinnGil https://QuinnGil.com Technical Practices - No Getters Why?

  24. @TheQuinnGil https://QuinnGil.com Technical Practices - No Setters Why?

  25. @TheQuinnGil https://QuinnGil.com Technical Practices - No Getters / No Setters

    How?
  26. @TheQuinnGil https://QuinnGil.com No Getters / No Setters - How? The

    Class Does It
  27. @TheQuinnGil https://QuinnGil.com Technical Practices - No Getters / No Setters

    public class FizzBuzz{ public int Input { get; set; } public string Result { get; set; } } public static class FizzBuzzUtils{ public static void Calculate(FizzBuzz fb){ if (fb.Input % 3 == 0){ fb.Result = "Fizz"; } if (fb.Input % 5 == 0){ if (fb.Result == null){ fb.Result = "Buzz"; } else { fb.Result += "Buzz"; } } if (string.IsNullOrEmpty(fb.Result)){ fb.Result = fb.Input.ToString(); } } }
  28. @TheQuinnGil https://QuinnGil.com Technical Practices - No Getters / No Setters

    public class FizzBuzz{ private readonly int _input; public FizzBuzz(int input) => _input = input; public string Result(){ string result = null; if (_input % 3 == 0) result = "Fizz"; if (_input % 5 == 0){ if (result == null) result = "Buzz"; else result += "Buzz"; } if (string.IsNullOrEmpty(result)){ result = _input.ToString(); } return result; } } public class FizzBuzz{ public int Input { get; set; } public string Result { get; set; } } public static class FizzBuzzUtils{ public static void Calculate(FizzBuzz fb){ if (fb.Input % 3 == 0){ fb.Result = "Fizz"; } if (fb.Input % 5 == 0){ if (fb.Result == null){ fb.Result = "Buzz"; } else { fb.Result += "Buzz"; } } if (string.IsNullOrEmpty(fb.Result)){ fb.Result = fb.Input.ToString(); } } }
  29. @TheQuinnGil https://QuinnGil.com Technical Practices - No Setters Benefits

  30. @TheQuinnGil https://QuinnGil.com No Getters / No Setters Technical Practices

  31. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  32. @TheQuinnGil https://QuinnGil.com `if` Only As Guard Clause Technical Practices

  33. @TheQuinnGil https://QuinnGil.com Technical Practices - `if` Only As Guard Clause

    No Way
  34. @TheQuinnGil https://QuinnGil.com Technical Practices - `if` Only As Guard Clause

    Success Path
  35. @TheQuinnGil https://QuinnGil.com `if` Only As Guard Clause - Success Path

    public class FizzBuzz{ private readonly int _input; public FizzBuzz(int input) => _input = input; public string Result(){ string result = null; if (_input % 3 == 0) result = "Fizz"; if (_input % 5 == 0){ if (result == null) result = "Buzz"; else result += "Buzz"; } if (string.IsNullOrEmpty(result)){ result = _input.ToString(); } return result; } }
  36. @TheQuinnGil https://QuinnGil.com `if` Only As Guard Clause - Success Path

    public class FizzBuzz{ public string Result(){ if (_input % 15 == 0) return "FizzBuzz"; if (_input % 3 == 0) return "Fizz"; if (_input % 5 == 0) return "Buzz"; return _input.ToString(); } } public class FizzBuzz{ private readonly int _input; public FizzBuzz(int input) => _input = input; public string Result(){ string result = null; if (_input % 3 == 0) result = "Fizz"; if (_input % 5 == 0){ if (result == null) result = "Buzz"; else result += "Buzz"; } if (string.IsNullOrEmpty(result)){ result = _input.ToString(); } return result; } }
  37. @TheQuinnGil https://QuinnGil.com Technical Practices - `if` Only As Guard Clause

    Cascading Changes
  38. @TheQuinnGil https://QuinnGil.com Technical Practices - `if` Only As Guard Clause

    How?
  39. @TheQuinnGil https://QuinnGil.com Technical Practices - `if` Only As Guard Clause

    public class FizzBuzz{ public string Result(){ if (_input % 15 == 0) return "FizzBuzz"; if (_input % 3 == 0) return "Fizz"; if (_input % 5 == 0) return "Buzz"; return _input.ToString(); } }
  40. @TheQuinnGil https://QuinnGil.com Technical Practices - `if` Only As Guard Clause

    public class FizzBuzz{ public string Result(){ if (_input % 15 == 0) return "FizzBuzz"; if (_input % 3 == 0) return "Fizz"; if (_input % 5 == 0) return "Buzz"; return _input.ToString(); } } public class FizzBuzz{ public string Result(){ if (IsFizzBuzz()) return "FizzBuzz"; if (IsFizz()) return "Fizz"; if (IsBuzz()) return "Buzz"; return InputToString(); } }
  41. @TheQuinnGil https://QuinnGil.com `if` Only As Guard Clause Technical Practices

  42. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  43. @TheQuinnGil https://QuinnGil.com Isolate Their Code Technical Practices

  44. @TheQuinnGil https://QuinnGil.com Technical Practices - Isolate Their Code - 3rd

    Party public class FizzBuzz{ private readonly string _input; public FizzBuzz(string input) => _input = input; public string Result(){ JObject jObject = JObject.Parse(_input); int input = jObject.Value<int>("number"); if (IsFizzBuzz(input)) return "FizzBuzz"; if (IsFizz(input)) return "Fizz"; if (IsBuzz(input)) return "Buzz"; return input.ToString(); } }
  45. @TheQuinnGil https://QuinnGil.com Technical Practices - Isolate Their Code - 3rd

    Party public class FizzBuzz{ private readonly string _input; private readonly IParser _parser; public FizzBuzz(string input) => _input = input; public string Result(){ IParsedObject pObject = _parser.Parse(_input); int input = pObject.IntValue("input"); if (IsFizzBuzz(input)) return "FizzBuzz"; if (IsFizz(input)) return "Fizz"; if (IsBuzz(input)) return "Buzz"; return input.ToString(); } }
  46. @TheQuinnGil https://QuinnGil.com Isolate Their Code Technical Practices

  47. @TheQuinnGil https://QuinnGil.com Operating System Technical Practices - Isolate Their Code

  48. @TheQuinnGil https://QuinnGil.com How? Technical Practices - Isolate Their Code

  49. @TheQuinnGil https://QuinnGil.com Technical Practices - Isolate Their Code - How?

    internal class HttpClientBookEnd : IHttpClientBookEnd{ private static HttpClient _testClient; #if DEBUG public static void SetTestClient(HttpClient testClient) => _testClient = testClient; #endif private readonly HttpClient _httpClient; public HttpClientBookEnd() : this(new HttpClient()){} private HttpClientBookEnd(HttpClient httpClient) => _httpClient = httpClient; public void SendRequestAsync(HttpRequestMessage msg) => HttpClient().SendAsync(msg); private HttpClient HttpClient() => _testClient ?? _httpClient; }
  50. @TheQuinnGil https://QuinnGil.com User Interface Technical Practices - Isolate Their Code

  51. @TheQuinnGil https://QuinnGil.com Isolate Their Code Technical Practices

  52. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  53. @TheQuinnGil https://QuinnGil.com Never `null` Technical Practices

  54. @TheQuinnGil https://QuinnGil.com Why? Technical Practices - Never `null`

  55. @TheQuinnGil https://QuinnGil.com How? Technical Practices - Never `null`

  56. @TheQuinnGil https://QuinnGil.com Technical Practices - Never `null` public string CalculateThing(ICanBeNull

    canBeNull) { if (canBeNull == null) return "Default"; IAlsoNull alsoNull = canBeNull.Example(); if (alsoNull == null) return "Default"; string sample = alsoNull.Sample(); if (sample == null) return "Default"; return sample; }
  57. @TheQuinnGil https://QuinnGil.com Technical Practices - Never `null` public string CalculateThing(ICanNotBeNull

    canNotBeNull) { return canNotBeNull.Example().Sample(); } public string CalculateThing(ICanBeNull canBeNull) { if (canBeNull == null) return "Default"; IAlsoNull alsoNull = canBeNull.Example(); if (alsoNull == null) return "Default"; string sample = alsoNull.Sample(); if (sample == null) return "Default"; return sample; }
  58. @TheQuinnGil https://QuinnGil.com Technical Practices - Never `null` public string CalculateThing(ICanBeNull

    canBeNull) { if (canBeNull == null) return "Default"; IAlsoNull alsoNull = canBeNull.Example(); if (alsoNull == null) return "Default"; string sample = alsoNull.Sample(); if (sample == null) return "Default"; return sample; } public string CalculateThing(ICanNotBeNull canNotBeNull) { return canNotBeNull.Example().Sample(); } public void Foo(){ string thing = _bar.CalculateThing(_canBeNull); //Do something with `thing` }
  59. @TheQuinnGil https://QuinnGil.com Technical Practices - Never `null` public string CalculateThing(ICanBeNull

    canBeNull) { if (canBeNull == null) return "Default"; IAlsoNull alsoNull = canBeNull.Example(); if (alsoNull == null) return "Default"; string sample = alsoNull.Sample(); if (sample == null) return "Default"; return sample; } public string CalculateThing(ICanNotBeNull canNotBeNull) { return canNotBeNull.Example().Sample(); } public void Foo(){ string thing = _bar.CalculateThing(_canBeNull); //Do something with `thing` } public void Foo(){ string thing = _canNotBeNull.Example().Sample(); //Do something with `thing` }
  60. @TheQuinnGil https://QuinnGil.com Technical Practices - Never `null` public string CalculateThing(ICanBeNull

    canBeNull) { if (canBeNull == null) return "Default"; IAlsoNull alsoNull = canBeNull.Example(); if (alsoNull == null) return "Default"; string sample = alsoNull.Sample(); if (sample == null) return "Default"; return sample; } public string CalculateThing(ICanNotBeNull canNotBeNull) { return canNotBeNull.Example().Sample(); } public class NullObject : ICanNotBeNull{ public IAlsoNotNull Example() => new NullObjectAlso(); } public class NullObjectAlso : IAlsoNotNull{ public string Sample() => "Default"; }
  61. @TheQuinnGil https://QuinnGil.com Languages and Null

  62. @TheQuinnGil https://QuinnGil.com Never `null` Technical Practices

  63. @TheQuinnGil https://QuinnGil.com Sustainable Code through Technical Practices • No Getters

    / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • Limit Object Creation • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  64. @TheQuinnGil https://QuinnGil.com THANK YOU!