Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Design Without Types

45 visualizaciones

Publicado el

An experiment in minimalism in software design

Publicado en: Software
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Design Without Types

  1. 1. Design without types Alex Bolboacă,  @alexboly,  alex.bolboaca@mozaicworks.com May 2019
  2. 2. Introduction(s) Why This Talk? Experiment in minimalism: optional types Deep questions Conclusion
  3. 3. Introduction(s)
  4. 4. Slides Slides published: https://www.slideshare.net/alexboly/design-without-types
  5. 5. I’m Alex
  6. 6. I’m helping customers Digital Transformation (mostly for banks recently)
  7. 7. I’m writing a book (publish date in June)
  8. 8. The topic I love the most is software design “Alex Boly on Design” youtube playlist http://bit.ly/alex-on-design
  9. 9. Why This Talk?
  10. 10. Personal History Beginner enthusiast (10 - 21 years old): • BASIC (ZX80 Clone) • Turbo Pascal • C • C++ Stance on types: what are types?
  11. 11. Personal History Early professional (21 - 30 years old) • C++ • Java • C# Stance on types: probably great.
  12. 12. Personal History OMG, this book is mindblowing!
  13. 13. Personal History Software Crafter (30 - 40 years old) • C++ • python • groovy Stance on types: Get out of my comfort zone!
  14. 14. Personal History Raising the Bar
  15. 15. Personal History Code Designer (40 - now) • what can I use to solve problems as quickly as possible? Stance on types: optional types have distinct advantages
  16. 16. Code Designer Minimalism
  17. 17. Minimalism in Code - Reasoning • Custom code is expensive: to build, to test, to change, to refine until it works, to run, to maintain • The more lines of code, the higher the probability to have bugs • Less code => smaller cognitive pressure
  18. 18. Experiment in minimalism: optional types
  19. 19. Rules • Type not specified unless it’s important • No casting • No thinking about the types used, only about their capabilities
  20. 20. What I’ve expected • bugs • weird problems • need to write more tests • code that’s more difficult to understand
  21. 21. What I’ve got from optional types • cleaner & smaller code • easier to change • fewer tests than I expected • fewer bugs than I expected NB: Some things were enabled by the language (groovy + grails), others are strongly related to the idea of optional types
  22. 22. Project • eventrix.co • web platform for conference organizers • groovy on grails (JVM language) Not perfect! • too much custom code - learned the hard way
  23. 23. Cleaner and smaller code // Typical Java version User user = new User(); // Duplication: 3 * User + ';'!!! var user = new User(); // Optional type: 2 * User + ';' // Groovy version def user = new User() // 2 * User // GORM def user = User.get(userId)
  24. 24. Cleaner and smaller code // Functional programming // C++ lambda auto increment = [](int value){ return first + 1;}; // C++ lambda with optional type auto increment = [](auto value){ return first + 1;};
  25. 25. Cleaner and smaller code // Functional programming // C++ lambda auto increment = [](int value){ return first + 1;}; // C++ lambda with optional type auto increment = [](auto value){ return first + 1;}; // Simplest Groovy lambda def increment = {it + 1} // optional type // also some magic: what is 'it'?
  26. 26. Cleaner and smaller code // C++ get list of names of users auto names = transform( users.begin(), users.end(), [](auto user){ return user.getName(); } );
  27. 27. Cleaner and smaller code // C++ get list of names of users auto names = transform( users.begin(), users.end(), [](auto user){ return user.getName(); } ); // groovy get list of names of users def names = users*.name
  28. 28. Cleaner and smaller code // Do the same, assuming User class has firstName and lastName // C++ auto names = transform(users.begin(), users.end(), [](auto user){ return user.getFirstName() + ” ” + users.getLastName(); } );
  29. 29. Cleaner and smaller code // Do the same, assuming User class has firstName and lastName // C++ auto names = transform(users.begin(), users.end(), [](auto user){ return user.getFirstName() + ” ” + users.getLastName(); } ); // groovy def names = users.collect{it.firstName + ” ” + it.lastName}
  30. 30. A taste of optional types • Tests using Spock • Query • Controller • Command
  31. 31. Deep questions
  32. 32. Q1: Is the cognitive cost of abstractions worth it? Salvador Dali - The melting watch
  33. 33. Q2: Is strong typing a form of strong coupling? Strong Coupling = “when I change X I also need to change Y”.
  34. 34. Example class UserDbService { boolean confirmEmail(int userId) { def user = User.get(userId) user.emailConfirmed = true user.save() } ... } class User{ int userId; ... }
  35. 35. Example What should be the type of userId? • int • long • GUID • UserID
  36. 36. Strong Coupling What if I change the type from int to UserID? (e.g. my company buys another company and we need to merge the systems) • change User • change UserDbService • and change everywhere where int userId is used
  37. 37. Optional Type => looser coupling class UserDbService { boolean confirmEmail(userId) { def user = User.get(userId) user.emailConfirmed = true user.save() } ... } class User{ int userId; ... }
  38. 38. Q3: How Important Are Names? // a design pattern we use for // transactional classes that // interact with database class UserDbService { def confirmEmail(userId) { def user = User.get(userId) user.emailConfirmed = true user.save() } ... }
  39. 39. Q4: How Important Are Contracts? TEST_CASE(”X wins”){ Board board = { {'X', 'X', 'X'}, {' ', 'O', ' '}, {' ', ' ', 'O'} }; CHECK(xWins(board)); }
  40. 40. Let’s see the code! Contract: Coordinates have two values
  41. 41. Contracts? With minimal types, you need to be very aware of the contracts
  42. 42. Beyond Types: Design Entities We use clear, well defined design entities: • Model: class defining the entity structure and mapping to database
  43. 43. Beyond Types: Design Entities We use clear, well defined design entities: • Model: class defining the entity structure and mapping to database • Query: class that encapsulates database queries
  44. 44. Beyond Types: Design Entities We use clear, well defined design entities: • Model: class defining the entity structure and mapping to database • Query: class that encapsulates database queries • DbCommand: class that saves data to the database
  45. 45. Beyond Types: Design Entities We use clear, well defined design entities: • Model: class defining the entity structure and mapping to database • Query: class that encapsulates database queries • DbCommand: class that saves data to the database • DbService: class that is called by Command or BusinessService to make multiple operations in the database, usually with the help of DbCommands
  46. 46. Beyond Types: Design Entities We use clear, well defined design entities: • Model: class defining the entity structure and mapping to database • Query: class that encapsulates database queries • DbCommand: class that saves data to the database • DbService: class that is called by Command or BusinessService to make multiple operations in the database, usually with the help of DbCommands • BusinessService: class that is called by Command to facilitate a business process
  47. 47. Beyond Types: Design Entities We use clear, well defined design entities: • Model: class defining the entity structure and mapping to database • Query: class that encapsulates database queries • DbCommand: class that saves data to the database • DbService: class that is called by Command or BusinessService to make multiple operations in the database, usually with the help of DbCommands • BusinessService: class that is called by Command to facilitate a business process • Command: class that is called by Controller to validate specific HTTP requests and delegate to the right Services the execution.
  48. 48. Conclusion
  49. 49. Minimalism exerts a positive pressure on design We still need to understand the code. Without types, how do we understand it? • smaller code
  50. 50. Minimalism exerts a positive pressure on design We still need to understand the code. Without types, how do we understand it? • smaller code • better names
  51. 51. Minimalism exerts a positive pressure on design We still need to understand the code. Without types, how do we understand it? • smaller code • better names • clear responsibilities
  52. 52. Minimalism exerts a positive pressure on design We still need to understand the code. Without types, how do we understand it? • smaller code • better names • clear responsibilities • clear contracts
  53. 53. Minimalism exerts a positive pressure on design We still need to understand the code. Without types, how do we understand it? • smaller code • better names • clear responsibilities • clear contracts • clear tests
  54. 54. Always Optional Types? NO Clear problem domain, clear solution, not expecting change, used by specialists => strong types, validation at compile time Expecting change, evolving problem and solution domain => minimalism, changeable code, fewer constraints
  55. 55. Let’s think differently! “I want the compiler to do as much checking for me as possible”
  56. 56. Let’s think differently! “I want the compiler to do as much checking for me as possible” vs. “I want to write the code that makes sense, and the compiler / interpreter to figure it out”
  57. 57. Thank you! Come talk to me later and get nice stickers!
  58. 58. Q&A Q&A

×