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

Technical Practices for Sustainable Code

Technical Practices for Sustainable Code

Highly maintainable code is hard to produce.
Without maintainability we can not have sustainable code, it will rot and have to be re-written. As an industry we're often given principles to follow which sound FANTASTIC... but don't layout the "how" of reaching these ideals.
We'll go into detail of four technical practices that have the biggest impact towards improving maintainability of the code we write.
As agile developers, what we want to do is deliver value to the customer quickly and consistently. As an agile developer and team, coding technical practices are the only way to develop code to quickly and consistently deliver value to the customer for the life of the product.
These technical practices produce simple, understandable, testable code which results in extremely maintainable code that we'll be able to enjoy working on for a long time.

Quinn

May 23, 2019
Tweet

More Decks by Quinn

Other Decks in Programming

Transcript

  1. Feature Parity in 25% of the Dev Hours with Technical

    Practices for Sustainable Code @TheQuinnGil QuinnGil.com
  2. Sustainable Code through Technical Practices • No Getters / No

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

    Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection No Getters / No Setters @TheQuinnGil QuinnGil.com
  4. 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
  5. 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(); } } }
  6. 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(); } } }
  7. Sustainable Code through Technical Practices No Getters / No Setters

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

    Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection `if` Only As Guard Clause @TheQuinnGil QuinnGil.com
  9. `if` Only As Guard Clause - Default 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; } }
  10. 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; } } `if` Only As Guard Clause - Default Path public class FizzBuzz{ private int _input; public FizzBuzz(int input) => _input = input; public string Result(){ if (_input % 15 == 0) return "FizzBuzz"; if (_input % 3 == 0) return "Fizz"; if (_input % 5 == 0) return "Buzz"; return _input.ToString(); } }
  11. `if` Only As Guard Clause - Default Path public class

    FizzBuzz{ private int _input; public FizzBuzz(int input) => _input = input; 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; } }
  12. Sustainable Code through Technical Practices `if` Only As Guard Clause

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

    Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection Isolate Their Code @TheQuinnGil QuinnGil.com
  14. 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(); } }
  15. Technical Practices - Isolate Their Code - 3rd Party public

    class FizzBuzz{ private readonly string _input; private readonly IParser _parser; 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(); } }
  16. 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; }
  17. Sustainable Code through Technical Practices Isolate Their Code @TheQuinnGil QuinnGil.com

    • No Getters / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  18. Sustainable Code through Technical Practices • No Getters / No

    Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection Never `null` @TheQuinnGil QuinnGil.com
  19. 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; }
  20. 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(ICanBeNull canBeNull) { return canBeNull?.Example()?.Sample() ?? "Default"; }
  21. 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(ICanBeNull canBeNull) { return canBeNull?.Example()?.Sample() ?? "Default"; } public string CalculateThing(ICanNotBeNull canNotBeNull) { return canNotBeNull.Example().Sample(); }
  22. 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(ICanBeNull canBeNull) { return canBeNull?.Example()?.Sample() ?? "Default"; } public string CalculateThing(ICanNotBeNull canNotBeNull) { return canNotBeNull.Example().Sample(); } public void Foo() { string thing = _bar.CalculateThing(_canBeNull); //... }
  23. 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(ICanBeNull canBeNull) { return canBeNull?.Example()?.Sample() ?? "Default"; } public string CalculateThing(ICanNotBeNull canNotBeNull) { return canNotBeNull.Example().Sample(); } public void Foo() { string thing = _bar.CalculateThing(_canBeNull); //... } public void Foo() { string thing = _canNotBeNull.Example().Sample(); //... }
  24. Technical Practices - Never `null` public class NullObject : ICanNotBeNull

    { public IAlsoNotNull Example() => new NullObjectAlso(); } public class NullObjectAlso : IAlsoNotNull { public string Sample() => "Default"; } 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 void Foo() { string thing = _canNotBeNull.Example().Sample(); //... }
  25. Sustainable Code through Technical Practices Never `null` @TheQuinnGil QuinnGil.com •

    No Getters / No Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection
  26. Sustainable Code through Technical Practices • No Getters / No

    Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection No `new` inline @TheQuinnGil QuinnGil.com
  27. Technical Practices - No `new` inline public class FizzBuzz{ private

    readonly int _input; public FizzBuzz(int input) => _input = input; public string Result(){ if (new Mod15(_input).Remainder() == 0) return "FizzBuzz"; if (new Mod3(_input).Remainder() == 0) return "Fizz"; if (new Mod5(_input).Remainder() == 0) return "Buzz"; return _input.ToString(); } }
  28. Technical Practices - No `new` inline public class FizzBuzz{ private

    readonly int _input; public FizzBuzz(int input) => _input = input; public string Result(){ if (Mod15().Remainder() == 0) return "FizzBuzz"; if (Mod3().Remainder() == 0) return "Fizz"; if (Mod5().Remainder() == 0) return "Buzz"; return _input.ToString(); } private IRemainder Mod15() => new Mod15(_input); private IRemainder Mod3() => new Mod3(_input); private IRemainder Mod5() => new Mod5(_input); }
  29. Technical Practices - No `new` inline public class FizzBuzz{ private

    readonly int _input; private readonly ModFactory factory; public FizzBuzz(int input) => _input = input; public string Result(){ if (factory.Mod15(_input).Remainder() == 0) return "FizzBuzz"; if (factory.Mod3(_input).Remainder() == 0) return "Fizz"; if (factory.Mod5(_input).Remainder() == 0) return "Buzz"; return _input.ToString(); } } public class ModFactory{ public IRemainder Mod15(int input) => new Mod15(input); public IRemainder Mod3(int input) => new Mod3(input); public IRemainder Mod5(int input) => new Mod5(input); }
  30. No `new` inline - Where DO We Create? public class

    FizzBuzz{ public string Result(){ IFizzBuzzInput input = new FizzBuzzInput(); if (input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (input.EvenlyDivisibleBy(3)) return "Fizz"; if (input.EvenlyDivisibleBy(5)) return "Buzz"; return input.ToString(); } }
  31. No `new` inline - Where DO We Create? public class

    FizzBuzz{ private readonly IFizzBuzzInput _input; public FizzBuzz() : this(new FizzBuzzInput()) { } private FizzBuzz(IFizzBuzzInput fizzBuzzInput) => _input = fizzBuzzInput; public string Result(){ if (_input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (_input.EvenlyDivisibleBy(3)) return "Fizz"; if (_input.EvenlyDivisibleBy(5)) return "Buzz"; return _input.ToString(); } } public class FizzBuzz{ public string Result(){ IFizzBuzzInput input = new FizzBuzzInput(); if (input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (input.EvenlyDivisibleBy(3)) return "Fizz"; if (input.EvenlyDivisibleBy(5)) return "Buzz"; return input.ToString(); } }
  32. No `new` inline - Where DO We Create? public class

    FizzBuzz{ private readonly IFizzBuzzService _service; public FizzBuzz() : this(new FizzBuzzService()) { } private FizzBuzz(IFizzBuzzService fizzBuzzService) => _service = fizzBuzzService; public string Result(){ IFizzBuzzInput input = _service.FizzBuzzInput(); if (input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (input.EvenlyDivisibleBy(3)) return "Fizz"; if (input.EvenlyDivisibleBy(5)) return "Buzz"; return input.ToString(); } } public class FizzBuzzService : IFizzBuzzService { public IFizzBuzzInput FizzBuzzInput() { return new FizzBuzzInputFromNetwork(_foo); } }
  33. No `new` inline - Why? - Testability public class FizzBuzz{

    private readonly IFizzBuzzInput _input; public FizzBuzz() : this(new FizzBuzzInput()) { } private FizzBuzz(IFizzBuzzInput fizzBuzzInput) => _input = fizzBuzzInput; public string Result(){ if (_input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (_input.EvenlyDivisibleBy(3)) return "Fizz"; if (_input.EvenlyDivisibleBy(5)) return "Buzz"; return _input.ToString(); } }
  34. No `new` inline - Why? - Testability public class FizzBuzz{

    private readonly IFizzBuzzInput _input; public FizzBuzz() : this(new FizzBuzzInput()) { } private FizzBuzz(IFizzBuzzInput fizzBuzzInput) => _input = fizzBuzzInput; public string Result(){ if (_input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (_input.EvenlyDivisibleBy(3)) return "Fizz"; if (_input.EvenlyDivisibleBy(5)) return "Buzz"; return _input.ToString(); } } public class FizzBuzz{ private readonly IFizzBuzzService _service; public FizzBuzz() : this(new FizzBuzzService()) { } private FizzBuzz(IFizzBuzzService fizzBuzzService) => _service = fizzBuzzService; public string Result(){ IFizzBuzzInput input = _service.FizzBuzzInput(); if (input.EvenlyDivisibleBy(15)) return "FizzBuzz"; if (input.EvenlyDivisibleBy(3)) return "Fizz"; if (input.EvenlyDivisibleBy(5)) return "Buzz"; return input.ToString(); } }
  35. No `new` inline - Why? - Expose Existing Cohesion public

    class FizzBuzz{ private readonly int _input; public FizzBuzz(int input) => _input = input; public string Result(){ if (new Mod15(_input).IsMultipleOf()) return "FizzBuzz"; if (new Mod3(_input).IsMultipleOf()) return "Fizz"; if (new Mod5(_input).IsMultipleOf()) return "Buzz"; return _input.ToString(); } }
  36. No `new` inline - Why? - Expose Existing Cohesion public

    class FizzBuzz{ public FizzBuzz(int input):this(input, new Mod15(input), new Mod3(input), new Mod5(input)) public string Result(){ if (_mod15.IsMultipleOf()) return "FizzBuzz"; if (_mod3.IsMultipleOf()) return "Fizz"; if (_mod5.IsMultipleOf()) return "Buzz"; return _input.ToString(); } }
  37. No `new` inline - Why? - Expose Existing Cohesion public

    class FizzBuzz{ public FizzBuzz(int input):this(new IntToString(input), new Mod15(input), new Mod3(input), new Mod5(input)) public string Result(){ if (_mod15.IsMultipleOf()) return "FizzBuzz"; if (_mod3.IsMultipleOf()) return "Fizz"; if (_mod5.IsMultipleOf()) return "Buzz"; return _toString.Value(); } }
  38. No `new` inline - Why? - Expose Existing Cohesion public

    class FizzBuzz{ public FizzBuzz(int input):this(new IntToString(input), new Mod15(input), new Mod3(input), new Mod5(input)) public string Result(){ if (_mod15.IsMultipleOf()) return _mod15.Value(); if (_mod3.IsMultipleOf()) return _mod3.Value(); if (_mod5.IsMultipleOf()) return _mod5.Value(); return _toString.Value(); } }
  39. No `new` inline - Why? - Expose Existing Cohesion public

    class FizzBuzz{ public FizzBuzz(int input):this(new ToStringResult(input), new FizzBuzzResult(input), new FizzResult(input), new BuzzResult(input)) public string Result(){ if (_fizzBuzz.ShouldReturn()) return _fizzBuzz.Value(); if (_buzz.ShouldReturn()) return _buzz.Value(); if (_fizz.ShouldReturn()) return _fizz.Value(); return _toString.Value(); } }
  40. Sustainable Code through Technical Practices • No Getters / No

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

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

    Setters • `if` Only As Guard Clause • Isolate Their Code • Never `null` • No `new` inline • Composition, Not Inheritance • <Strong opinions loosely held> • Be Immutable • No Primitives • Extract Cohesion • No Public Statics • Never Reflection @TheQuinnGil QuinnGil.com