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

    View Slide

  2. Feature Parity in
    25% of the Dev Hours
    @TheQuinnGil QuinnGil.com

    View Slide

  3. @TheQuinnGil QuinnGil.com
    Technical Practices for
    Sustainable Code

    View Slide

  4. Quinn Gil
    Blog -- QuinnGil.com
    Twitter -- TheQuinnGil
    Github -- Fyzxs
    @TheQuinnGil QuinnGil.com

    View Slide

  5. This is for you.

    View Slide

  6. Sustainable Code
    through
    Technical Practices
    @TheQuinnGil QuinnGil.com

    View Slide

  7. Sustainable Code
    through
    Technical Practices
    @TheQuinnGil QuinnGil.com

    View Slide

  8. Sustainable Code
    through
    Technical Practices
    @TheQuinnGil QuinnGil.com

    View Slide

  9. Tests

    View Slide

  10. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    @TheQuinnGil QuinnGil.com

    View Slide

  11. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    No Getters / No Setters
    @TheQuinnGil QuinnGil.com

    View Slide

  12. 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

    View Slide

  13. Technical Practices - No Getters / No Setters
    No Way

    View Slide

  14. No Getters / No Setters
    Technical Practices

    View Slide

  15. Technical Practices - No Getters
    Why No Getters?

    View Slide

  16. Technical Practices - No Setters
    Why No Setters?

    View Slide

  17. Technical Practices - No Getters / No Setters
    How?

    View Slide

  18. No Getters / No Setters - How?
    The Class Does It

    View Slide

  19. 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();
    }
    }
    }

    View Slide

  20. 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();
    }
    }
    }

    View Slide

  21. Technical Practices - No Getters / No Setters
    Benefits

    View Slide

  22. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection

    View Slide

  23. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    `if` Only As Guard Clause
    @TheQuinnGil QuinnGil.com

    View Slide

  24. Technical Practices - `if` Only As Guard Clause
    No Way

    View Slide

  25. Technical Practices - `if` Only As Guard Clause
    Default Path

    View Slide

  26. `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;
    }
    }

    View Slide

  27. 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();
    }
    }

    View Slide

  28. Technical Practices - `if` Only As Guard Clause
    Cascading Changes

    View Slide

  29. Technical Practices - `if` Only As Guard Clause
    Cascading Changes
    switch and else - always evil

    View Slide

  30. Technical Practices - `if` Only As Guard Clause
    How?

    View Slide

  31. `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;
    }
    }

    View Slide

  32. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection

    View Slide

  33. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    Isolate Their Code
    @TheQuinnGil QuinnGil.com

    View Slide

  34. 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("number");
    if (IsFizzBuzz(input)) return "FizzBuzz";
    if (IsFizz(input)) return "Fizz";
    if (IsBuzz(input)) return "Buzz";
    return input.ToString();
    }
    }

    View Slide

  35. 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();
    }
    }

    View Slide

  36. What Else?
    Technical Practices - Isolate Their Code

    View Slide

  37. Operating System
    Technical Practices - Isolate Their Code

    View Slide

  38. How?
    Technical Practices - Isolate Their Code

    View Slide

  39. 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;
    }

    View Slide

  40. User Interface
    Technical Practices - Isolate Their Code

    View Slide

  41. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection

    View Slide

  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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    Never `null`
    @TheQuinnGil QuinnGil.com

    View Slide

  43. Why?
    Technical Practices - Never `null`

    View Slide

  44. How?
    Technical Practices - Never `null`

    View Slide

  45. 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;
    }

    View Slide

  46. 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";
    }

    View Slide

  47. 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();
    }

    View Slide

  48. 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);
    //...
    }

    View Slide

  49. 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();
    //...
    }

    View Slide

  50. 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();
    //...
    }

    View Slide

  51. Languages and Null

    View Slide

  52. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection

    View Slide

  53. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    No `new` inline
    @TheQuinnGil QuinnGil.com

    View Slide

  54. 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();
    }
    }

    View Slide

  55. 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);
    }

    View Slide

  56. 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);
    }

    View Slide

  57. Where DO we Create?
    Technical Practices

    View Slide

  58. 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();
    }
    }

    View Slide

  59. 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();
    }
    }

    View Slide

  60. 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);
    }
    }

    View Slide

  61. Just Two Places
    No `new` inline

    View Slide

  62. Why?
    No `new` inline

    View Slide

  63. Testability
    No `new` inline - Why?

    View Slide

  64. 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();
    }
    }

    View Slide

  65. 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();
    }
    }

    View Slide

  66. Expose Existing Cohesion
    No `new` inline - Why?

    View Slide

  67. 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();
    }
    }

    View Slide

  68. 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();
    }
    }

    View Slide

  69. 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();
    }
    }

    View Slide

  70. 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();
    }
    }

    View Slide

  71. 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();
    }
    }

    View Slide

  72. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    No `new` inline
    @TheQuinnGil QuinnGil.com

    View Slide

  73. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    @TheQuinnGil QuinnGil.com

    View Slide

  74. Feature Parity in
    25% of the Dev Hours
    @TheQuinnGil QuinnGil.com

    View Slide

  75. THANK YOU!
    @TheQuinnGil QuinnGil.com

    View Slide

  76. 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

    ● Be Immutable
    ● No Primitives
    ● Extract Cohesion
    ● No Public Statics
    ● Never Reflection
    @TheQuinnGil QuinnGil.com

    View Slide