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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  5. This is for you.

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  9. 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 full-size 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
    No Getters / No Setters
    @TheQuinnGil QuinnGil.com

    View full-size slide

  11. 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 full-size slide

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

    View full-size slide

  13. No Getters / No Setters
    Technical Practices

    View full-size slide

  14. Technical Practices - No Getters
    Why No Getters?

    View full-size slide

  15. Technical Practices - No Setters
    Why No Setters?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  18. 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 full-size slide

  19. 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 full-size slide

  20. Technical Practices - No Getters / No Setters
    Benefits

    View full-size slide

  21. 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 full-size slide

  22. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  25. `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 full-size slide

  26. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  30. `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 full-size slide

  31. 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 full-size slide

  32. 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 full-size slide

  33. 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 full-size slide

  34. 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 full-size slide

  35. What Else?
    Technical Practices - Isolate Their Code

    View full-size slide

  36. Operating System
    Technical Practices - Isolate Their Code

    View full-size slide

  37. How?
    Technical Practices - Isolate Their Code

    View full-size slide

  38. 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 full-size slide

  39. User Interface
    Technical Practices - Isolate Their Code

    View full-size slide

  40. 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 full-size slide

  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

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

    View full-size slide

  42. Why?
    Technical Practices - Never `null`

    View full-size slide

  43. How?
    Technical Practices - Never `null`

    View full-size slide

  44. 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 full-size 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;
    }
    public string CalculateThing(ICanBeNull canBeNull)
    {
    return canBeNull?.Example()?.Sample() ?? "Default";
    }

    View full-size 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";
    }
    public string CalculateThing(ICanNotBeNull canNotBeNull)
    {
    return canNotBeNull.Example().Sample();
    }

    View full-size 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();
    }
    public void Foo()
    {
    string thing = _bar.CalculateThing(_canBeNull);
    //...
    }

    View full-size 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);
    //...
    }
    public void Foo()
    {
    string thing = _canNotBeNull.Example().Sample();
    //...
    }

    View full-size slide

  49. 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 full-size slide

  50. Languages and Null

    View full-size slide

  51. 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 full-size slide

  52. 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 full-size slide

  53. 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 full-size slide

  54. 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 full-size slide

  55. 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 full-size slide

  56. Where DO we Create?
    Technical Practices

    View full-size slide

  57. 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 full-size slide

  58. 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 full-size slide

  59. 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 full-size slide

  60. Just Two Places
    No `new` inline

    View full-size slide

  61. Why?
    No `new` inline

    View full-size slide

  62. Testability
    No `new` inline - Why?

    View full-size slide

  63. 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 full-size 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();
    }
    }
    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 full-size slide

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

    View full-size slide

  66. 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 full-size slide

  67. 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 full-size slide

  68. 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 full-size 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 _mod15.Value();
    if (_mod3.IsMultipleOf()) return _mod3.Value();
    if (_mod5.IsMultipleOf()) return _mod5.Value();
    return _toString.Value();
    }
    }

    View full-size slide

  70. 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 full-size slide

  71. 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 full-size 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
    @TheQuinnGil QuinnGil.com

    View full-size slide

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

    View full-size slide

  74. THANK YOU!
    @TheQuinnGil QuinnGil.com

    View full-size slide

  75. 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 full-size slide