Slide 1

Slide 1 text

Feature Parity in 25% of the Dev Hours With MicroObjects @TheQuinnGil https://QuinnGil.com

Slide 2

Slide 2 text

MicroObjects Object Oriented Practices to the Extreme

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Primary Philosophy

Slide 5

Slide 5 text

Primary Philosophy Single Responsibility

Slide 6

Slide 6 text

Single Responsibility What’s its job?

Slide 7

Slide 7 text

Single Responsibility Single Behavior

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Driving Single Responsibility No Getters / No Setters ‘if’s Only as a Guard Clause Isolate Their Code

Slide 11

Slide 11 text

Driving Single Responsibility No Getters / No Setters

Slide 12

Slide 12 text

No Getters / No Setters My Definition

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

No Getters / No Setters No Way

Slide 15

Slide 15 text

No Getters / No Setters

Slide 16

Slide 16 text

No Getters Why?

Slide 17

Slide 17 text

No Getters Behavior

Slide 18

Slide 18 text

No Getters / No Setters

Slide 19

Slide 19 text

No Getters / No Setters

Slide 20

Slide 20 text

No Setters Why?

Slide 21

Slide 21 text

No Setters Behavior

Slide 22

Slide 22 text

No Setters Clear Usage

Slide 23

Slide 23 text

No Getters / No Setters

Slide 24

Slide 24 text

No Getters / No Setters

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Driving Single Responsibility No Getters / No Setters ‘if’s Only as a Guard Clause Isolate Their Code

Slide 28

Slide 28 text

‘if’s Only as a Guard Clause Driving Single Responsibility

Slide 29

Slide 29 text

‘if’s Only as a Guard Clause No Way

Slide 30

Slide 30 text

‘if’s Only as a Guard Clause Cascading Effect

Slide 31

Slide 31 text

‘if’s Only as a Guard Clause Success Path

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

FizzBuzz?

Slide 35

Slide 35 text

Driving Single Responsibility No Getters / No Setters ‘if’s Only as a Guard Clause Isolate Their Code

Slide 36

Slide 36 text

Driving Single Responsibility Isolate Their Code

Slide 37

Slide 37 text

Isolate Their Code OOP Practices

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Isolate Their Code Coupling

Slide 40

Slide 40 text

Isolate Their Code Commonality

Slide 41

Slide 41 text

Isolate Their Code Single Behavior

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Asymmetric Marriage

Slide 45

Slide 45 text

Driving Single Responsibility No Getters / No Setters ‘if’s Only as a Guard Clause Isolate Their Code

Slide 46

Slide 46 text

25% of the Dev Hours

Slide 47

Slide 47 text

● No Getters / No Setters ● Always Immutable ● No ‘new’ Inline ● No Enum ● No Primitive Obsession ● Encapsulate Relationships ● ‘if’ Only as Guard Clause ● ‘switch’ & ‘else’ Always Evil ● Composition Over Inheritance ● Interface Everything ● No Public Statics ● No nulls ● Isolate Their Code

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

MicroObjects Single Responsibility to the Extreme @TheQuinnGil https://QuinnGil.com