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

MicroObjects - Chicago Code Camp 2018

Quinn
June 09, 2018

MicroObjects - Chicago Code Camp 2018

Writing highly maintainable code is hard. Without being able to maintain the code it rots and eventually must be replaced. Some very simple constraints can produce highly maintainable code. Highly maintainable code allows quicker delivery of new features. Let's explore the practices that allow quick deliver of highly maintainable software.

Quinn

June 09, 2018
Tweet

More Decks by Quinn

Other Decks in Programming

Transcript

  1. Feature Parity in 25% of the Dev Hours MicroObjects: OOP

    to the Extreme @TheQuinnGil https://QuinnGil.com
  2. Technical Practices… • No Getters / No Setters • Always

    Immutable • No ‘new’ Inline • No Primitive Obsession • Encapsulate Relationships • ‘if’ Only as Guard Clause • ‘switch’ & ‘else’ Always Evil • Composition Over Inheritance • Interface Everything • Isolate Their Code • No Statics • No nulls
  3. Technical Practices… Drive Single Responsibility • No Getters / No

    Setters • Always Immutable • No ‘new’ Inline • No Primitive Obsession • Encapsulate Relationships • ‘if’ Only as Guard Clause • ‘switch’ & ‘else’ Always Evil • Composition Over Inheritance • Interface Everything • No Statics • No nulls • Isolate Their Code
  4. 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. No Getters / No Setters class FizzBuzzBag{ public int Input{

    get; set; } public string Result{ get; set; } } private void CalcFizzBuzzResult(FizzBuzzBag fb){ var sb = new StringBuilder(); if(ShouldIncludeFizz(fb.Input)){ sb.Append("Fizz"); } if(ShouldIncludeBuzz(fb.Input)){ sb.Append("Buzz"); } fb.Result = sb.Length != 0 ? sb.ToString() : fb.Input.ToString(); }
  6. No Getters / No Setters - Encapsulated Behavior class FizzBuzz{

    private readonly int input; public FizzBuzz(int input){ this.input = input; } public string Result(){ var sb = new StringBuilder(); if(ShouldIncludeFizz(input)){ sb.Append("Fizz"); } if(ShouldIncludeBuzz(input)){ sb.Append("Buzz"); } return sb.Length != 0 ? sb.ToString() : input.ToString(); } }
  7. ‘if’s Only as a Guard Clause - Success Path class

    FizzBuzz{ private readonly int input; public FizzBuzz(int input){ this.input = input; } public string Result(){ var sb = new StringBuilder(); if(ShouldIncludeFizz(input)){ sb.Append("Fizz"); } if(ShouldIncludeBuzz(input)){ sb.Append("Buzz"); } return sb.Length != 0 ? sb.ToString() : input.ToString(); } }
  8. ‘if’s Only as a Guard Clause - Success Path class

    FizzBuzz{ private readonly int input; public FizzBuzz(int input){ this.input = input; } public string Result(){ var sb = new StringBuilder(); if(ShouldIncludeFizz(input)){ sb.Append("Fizz"); } if(ShouldIncludeBuzz(input)){ sb.Append("Buzz"); } return sb.Length != 0 ? sb.ToString() : input.ToString(); } } class FizzBuzz{ private readonly int input; public FizzBuzz(int input){ this.input = input; } public string Result(){ if(ShouldBeFizzBuzz(input)) return "FizzBuzz"; if(ShouldBeFizz(input)) return "Fizz"; if(ShouldBeBuzz(input)) return "Buzz"; return input.ToString(); } }
  9. Isolate Their Code - OOP Practices class FizzBuzz{ private readonly

    string json; public string Result(){ JObject jObject = JObject.Parse(json); int input = jObject.Value<int>("input"); if(ShouldBeFizzBuzz(input)) return "FizzBuzz"; if(ShouldBeFizz(input)) return "Fizz"; if(ShouldBeBuzz(input)) return "Buzz"; return input.ToString(); } }
  10. Isolate Their Code - Single Behavior class FizzBuzz{ private readonly

    string json; private readonly IParser parser; public string Result(){ IParsedObject pObject = parser.Parse(json); int input = pObject.IntValue("input"); if(ShouldBeFizzBuzz(input)) return "FizzBuzz"; if(ShouldBeFizz(input)) return "Fizz"; if(ShouldBeBuzz(input)) return "Buzz"; return input.ToString(); } }
  11. Isolate Their Code - Single Behavior class FizzBuzz{ private readonly

    IFizzBuzzInput input; public FizzBuzz(IFizzBuzzInput input){ this.input = input; } public string Result(){ if(ShouldBeFizzBuzz(input)) return "FizzBuzz"; if(ShouldBeFizz(input)) return "Fizz"; if(ShouldBeBuzz(input)) return "Buzz"; return input.AsString(); } } class FizzBuzz{ private readonly string json; private readonly IParser parser; public string Result(){ IParsedObject pObject = parser.Parse(json); int input = pObject.IntValue("input"); if(ShouldBeFizzBuzz(input)) return "FizzBuzz"; if(ShouldBeFizz(input)) return "Fizz"; if(ShouldBeBuzz(input)) return "Buzz"; return input.ToString(); } }
  12. • No Getters / No Setters • Always Immutable •

    No ‘new’ Inline • No Primitive Obsession • Encapsulate Relationships • ‘if’ Only as Guard Clause • ‘switch’ & ‘else’ Always Evil • Composition Over Inheritance • Interface Everything • Isolate Their Code • No Statics • No nulls