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

Technical Practices for Sustainable Code - Chicago Code Camp 2019

Technical Practices for Sustainable Code - Chicago Code Camp 2019

Slidedeck from presentation at Chicago Code Camp 2019

Quinn

May 11, 2019
Tweet

More Decks by Quinn

Other Decks in Programming

Transcript

  1. @TheQuinnGil https://QuinnGil.com
    with
    Technical Practices for
    Sustainable Code
    Feature Parity in
    25% of the Dev Hours

    View Slide

  2. @TheQuinnGil https://QuinnGil.com
    Technical Practices for
    Sustainable Code

    View Slide

  3. @TheQuinnGil https://QuinnGil.com
    Quinn Gil
    Blog -- QuinnGil.com
    Twitter -- TheQuinnGil
    Github -- Fyzxs

    View Slide

  4. @TheQuinnGil https://QuinnGil.com
    This is for you.

    View Slide

  5. @TheQuinnGil https://QuinnGil.com
    Sustainable Code

    View Slide

  6. @TheQuinnGil https://QuinnGil.com
    Why?
    Sustainable Code

    View Slide

  7. @TheQuinnGil https://QuinnGil.com
    What’s Our Job?
    Sustainable Code - Why?

    View Slide

  8. @TheQuinnGil https://QuinnGil.com
    Sustainably grow the value of
    the company’s digital assets.
    Sustainable Code - What’s our job?

    View Slide

  9. @TheQuinnGil https://QuinnGil.com
    I’m Lazy
    Sustainable Code

    View Slide

  10. @TheQuinnGil https://QuinnGil.com
    How?
    Sustainable Code

    View Slide

  11. @TheQuinnGil https://QuinnGil.com
    Mindset Change
    Sustainable Code - How?

    View Slide

  12. @TheQuinnGil https://QuinnGil.com
    Technical Practices
    Sustainable Code - How?

    View Slide

  13. @TheQuinnGil https://QuinnGil.com
    Sustainable Code
    through
    Technical Practices

    View Slide

  14. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  15. @TheQuinnGil https://QuinnGil.com
    But First!

    View Slide

  16. @TheQuinnGil https://QuinnGil.com
    Fully Test Behaviors
    Sustainable Code - Testing!

    View Slide

  17. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  18. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  19. @TheQuinnGil https://QuinnGil.com
    No Getters / No Setters
    Technical Practices

    View Slide

  20. @TheQuinnGil https://QuinnGil.com
    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

  21. @TheQuinnGil https://QuinnGil.com
    Technical Practices - No Getters / No Setters
    No Way

    View Slide

  22. @TheQuinnGil https://QuinnGil.com
    No Getters / No Setters
    Technical Practices

    View Slide

  23. @TheQuinnGil https://QuinnGil.com
    Technical Practices - No Getters
    Why?

    View Slide

  24. @TheQuinnGil https://QuinnGil.com
    Technical Practices - No Setters
    Why?

    View Slide

  25. @TheQuinnGil https://QuinnGil.com
    Technical Practices - No Getters / No Setters
    How?

    View Slide

  26. @TheQuinnGil https://QuinnGil.com
    No Getters / No Setters - How?
    The Class Does It

    View Slide

  27. @TheQuinnGil https://QuinnGil.com
    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

  28. @TheQuinnGil https://QuinnGil.com
    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

  29. @TheQuinnGil https://QuinnGil.com
    Technical Practices - No Setters
    Benefits

    View Slide

  30. @TheQuinnGil https://QuinnGil.com
    No Getters / No Setters
    Technical Practices

    View Slide

  31. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  32. @TheQuinnGil https://QuinnGil.com
    `if` Only As Guard Clause
    Technical Practices

    View Slide

  33. @TheQuinnGil https://QuinnGil.com
    Technical Practices - `if` Only As Guard Clause
    No Way

    View Slide

  34. @TheQuinnGil https://QuinnGil.com
    Technical Practices - `if` Only As Guard Clause
    Success Path

    View Slide

  35. @TheQuinnGil https://QuinnGil.com
    `if` Only As Guard Clause - Success 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

  36. @TheQuinnGil https://QuinnGil.com
    `if` Only As Guard Clause - Success Path
    public class FizzBuzz{
    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

  37. @TheQuinnGil https://QuinnGil.com
    Technical Practices - `if` Only As Guard Clause
    Cascading Changes

    View Slide

  38. @TheQuinnGil https://QuinnGil.com
    Technical Practices - `if` Only As Guard Clause
    How?

    View Slide

  39. @TheQuinnGil https://QuinnGil.com
    Technical Practices - `if` Only As Guard Clause
    public class FizzBuzz{
    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

  40. @TheQuinnGil https://QuinnGil.com
    Technical Practices - `if` Only As Guard Clause
    public class FizzBuzz{
    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{
    public string Result(){
    if (IsFizzBuzz()) return "FizzBuzz";
    if (IsFizz()) return "Fizz";
    if (IsBuzz()) return "Buzz";
    return InputToString();
    }
    }

    View Slide

  41. @TheQuinnGil https://QuinnGil.com
    `if` Only As Guard Clause
    Technical Practices

    View Slide

  42. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  43. @TheQuinnGil https://QuinnGil.com
    Isolate Their Code
    Technical Practices

    View Slide

  44. @TheQuinnGil https://QuinnGil.com
    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

  45. @TheQuinnGil https://QuinnGil.com
    Technical Practices - Isolate Their Code - 3rd Party
    public class FizzBuzz{
    private readonly string _input;
    private readonly IParser _parser;
    public FizzBuzz(string input) => _input = input;
    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

  46. @TheQuinnGil https://QuinnGil.com
    Isolate Their Code
    Technical Practices

    View Slide

  47. @TheQuinnGil https://QuinnGil.com
    Operating System
    Technical Practices - Isolate Their Code

    View Slide

  48. @TheQuinnGil https://QuinnGil.com
    How?
    Technical Practices - Isolate Their Code

    View Slide

  49. @TheQuinnGil https://QuinnGil.com
    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

  50. @TheQuinnGil https://QuinnGil.com
    User Interface
    Technical Practices - Isolate Their Code

    View Slide

  51. @TheQuinnGil https://QuinnGil.com
    Isolate Their Code
    Technical Practices

    View Slide

  52. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  53. @TheQuinnGil https://QuinnGil.com
    Never `null`
    Technical Practices

    View Slide

  54. @TheQuinnGil https://QuinnGil.com
    Why?
    Technical Practices - Never `null`

    View Slide

  55. @TheQuinnGil https://QuinnGil.com
    How?
    Technical Practices - Never `null`

    View Slide

  56. @TheQuinnGil https://QuinnGil.com
    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

  57. @TheQuinnGil https://QuinnGil.com
    Technical Practices - Never `null`
    public string CalculateThing(ICanNotBeNull canNotBeNull)
    {
    return canNotBeNull.Example().Sample();
    }
    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

  58. @TheQuinnGil https://QuinnGil.com
    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(ICanNotBeNull canNotBeNull)
    {
    return canNotBeNull.Example().Sample();
    }
    public void Foo(){
    string thing = _bar.CalculateThing(_canBeNull);
    //Do something with `thing`
    }

    View Slide

  59. @TheQuinnGil https://QuinnGil.com
    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(ICanNotBeNull canNotBeNull)
    {
    return canNotBeNull.Example().Sample();
    }
    public void Foo(){
    string thing = _bar.CalculateThing(_canBeNull);
    //Do something with `thing`
    }
    public void Foo(){
    string thing = _canNotBeNull.Example().Sample();
    //Do something with `thing`
    }

    View Slide

  60. @TheQuinnGil https://QuinnGil.com
    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(ICanNotBeNull canNotBeNull)
    {
    return canNotBeNull.Example().Sample();
    }
    public class NullObject : ICanNotBeNull{
    public IAlsoNotNull Example() => new NullObjectAlso();
    }
    public class NullObjectAlso : IAlsoNotNull{
    public string Sample() => "Default";
    }

    View Slide

  61. @TheQuinnGil https://QuinnGil.com
    Languages and Null

    View Slide

  62. @TheQuinnGil https://QuinnGil.com
    Never `null`
    Technical Practices

    View Slide

  63. @TheQuinnGil https://QuinnGil.com
    Sustainable Code through Technical Practices
    ● No Getters / No Setters
    ● `if` Only As Guard Clause
    ● Isolate Their Code
    ● Never `null`
    ● Limit Object Creation
    ● Composition, Not Inheritance

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

    View Slide

  64. @TheQuinnGil https://QuinnGil.com
    THANK YOU!

    View Slide