Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Object Pascal Clean Code Guidelines Proposal (at EKON 22)

637 views

Published on

This EKON 22 conference was not about the code formatting - where we put the “begin” keyword is mostly a matter of taste and convention. But it shows how the object pascal strong typing system, and its language expressiveness may help writing clean(er) code. Abstract SOLID principles could help define the class and services hierarchy. After years of server-side coding, we propose some practical guidelines for cleaner object pascal programming, to reduce technical debt, and allow cross-platform/cross-compiler support.

Published in: Software
  • Be the first to comment

Object Pascal Clean Code Guidelines Proposal (at EKON 22)

  1. 1. Clean Code – Guidelines Proposal Arnaud Bouchez – Synopse / LiveMon CLEAN CODE Guidelines Proposal
  2. 2. Clean Code – Guidelines Proposal Arnaud Bouchez – Delphi / FPC • Various solutions (from Vatican to gaming industry) • IoT solution (RSI) • Real-time Monitoring solution (LiveMon) – Open Source • mORMot (SOA ORM MVC framework) • SynPDF SynMustache SynDB SynCrypto – Training and consultancy • Synopse one-man company
  3. 3. Clean Code – Guidelines Proposal
  4. 4. Clean Code – Guidelines Proposal Clean Code Guidelines Proposal • Guidance • Target • Repository • Code Formatting • Types definition
  5. 5. Clean Code – Guidelines Proposal Clean Code Guidelines Proposal • Guidance • Target • Repository • Code Formatting • Types definition
  6. 6. Clean Code – Guidelines Proposal Guidance Proposal • We focus on Server-Side code Client side is more expandable • We wonder not only HOW but WHY Even if coding is an art form, it is sadly not yet in the modern art market so most employers don’t care about code
  7. 7. Clean Code – Guidelines Proposal Guidance Proposal • Proposal There is no single policy to rule them all This session should be interactive Some proposals may not fit your needs Some proposals may hurt you
  8. 8. Clean Code – Guidelines Proposal Guidance Proposal • Proposal There is no single policy to rule them all This session should be interactive Some proposals may not fit your needs Some proposals may hurt you - at least let’s try to understand each one point of view
  9. 9. Clean Code – Guidelines Proposal Guidance Proposal • Proposal Start from the current LiveMon Guidance (because I wrote it)
  10. 10. Clean Code – Guidelines Proposal Guidance Proposal • Proposal Start from the current LiveMon Guidance (because I wrote it and because you will help me improve it)
  11. 11. Clean Code – Guidelines Proposal Guidance Proposal • Proposal Start from the current LiveMon Guidance but this is a work-in-progress → make yourself your idea!
  12. 12. Clean Code – Guidelines Proposal Guidance • Team work needs some rules especially for our most valuable asset: use the source, Luke! - your padawans will thank you
  13. 13. Clean Code – Guidelines Proposal Guidance • Ease maintainability and interoperability don’t write for yourself eventually help yourself
  14. 14. Clean Code – Guidelines Proposal Guidance • Ease maintainability and interoperability as if the final maintainer of your code would be a psychopath knowing your personal address
  15. 15. Clean Code – Guidelines Proposal Guidance • Goal: fails at compile time or fails at code peer review to avoid (some/most) errors at runtime Runtime errors are the worse to fix • Test-Driven Design Testing is (the main/worse) part of writing
  16. 16. Clean Code – Guidelines Proposal Guidance • Up to Domain-Driven Design The Domain code is isolated from all dependencies (e.g. DB or applications) → non technical domain experts should be able to read, understand and validate the Domain source code
  17. 17. Clean Code – Guidelines Proposal Guidance • SOLID Principles Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle are Out Of Scope of this presentation (but worth a full session or workshop)
  18. 18. Clean Code – Guidelines Proposal Clean Code Guidelines Proposal • Guidance • Target • Repository • Code Formatting • Types definition
  19. 19. Clean Code – Guidelines Proposal Compiler Target • For which Compiler and OS (eventually) Delphi FPC others (TMSWebCore, SMS, EWB…)
  20. 20. Clean Code – Guidelines Proposal Compiler Target • Isolate OS and compiler specific code don’t abuse of {$ifdef…} use a leading {$I conditionals.inc} file isolate in specific units
  21. 21. Clean Code – Guidelines Proposal Compiler Target • Isolate OS and compiler specific code use third party libraries use shared syntax e.g. FPC {$mode Delphi} with automated testing on all targets
  22. 22. Clean Code – Guidelines Proposal Compiler Target • Third Parties Well identified and chosen Documented as such Part of the source code tree (or as external) Stability in the long term Cross-OS and Cross-compilers support
  23. 23. Clean Code – Guidelines Proposal Compiler Target • Static linked C code or raw asm Sometimes needed for performance Always with “pure pascal” fallback Includes documentation Includes script to rebuild from C sources
  24. 24. Clean Code – Guidelines Proposal Clean Code Guidelines Proposal • Guidance • Target • Repository • Code Formatting • Types definition
  25. 25. Clean Code – Guidelines Proposal Source Code Repository • As part of the Code requirements Where and how we maintain the source code is part of daily development work but also of the whole solution design
  26. 26. Clean Code – Guidelines Proposal Source Code Repository • Git / Mercurial / Bazar / Fossil / SVN … Centralized or Distributed Local copy or Fork/Branch In-house hosted or Cloud PaaS • Linked with other tools Documentation, Project management, Issues, Support, CRM…
  27. 27. Clean Code – Guidelines Proposal Source Code Repository • As part of the Code requirements main branch should always compile and pass the regression tests on all supported platforms • Continuous Integration Automated Commit – Build – Test cycle
  28. 28. Clean Code – Guidelines Proposal Source Code Repository • Branches and Forks Per-feature branches on distributed SCM e.g. git/fossil/bazar Pull requests with explicit review before merge by team leaders Continuous Integration from branches
  29. 29. Clean Code – Guidelines Proposal Source Code Repository • Folders Hierarchy Source code may be project-oriented: one folder per project + “common” units (this is a typical layout)
  30. 30. Clean Code – Guidelines Proposal Source Code Repository • Folders Hierarchy Why not use them to uncouple the logic and avoid dependencies? e.g. split data, logic, tests and UI
  31. 31. Clean Code – Guidelines Proposal Source Code Repository • Folders Hierarchy at LiveMon data daemon ext serv test tools ui
  32. 32. Clean Code – Guidelines Proposal Source Code Repository • Folders Hierarchy at LiveMon data daemon ext serv test tools ui Unit names follow the folder name e.g. DataMetrics.pas is located in Data TestAll.dpr is located in Test DaemonShopMain.pas is located in Daemon
  33. 33. Clean Code – Guidelines Proposal Source Code Repository • Sensitive code and files (private keys, default passwords…) are better stored outside the repository (especially on PaaS like github)
  34. 34. Clean Code – Guidelines Proposal Source Code Repository • Dependencies are hosted in several repositories External dependencies for 3rd parties Internal dependencies for cross-teams work
  35. 35. Clean Code – Guidelines Proposal Source Code Repository • Test-Driven Design are part of the source Unit tests & Integration tests to avoid regressions and enhance agility as part of the integration, or stand-alone on staging/pre-prod environment
  36. 36. Clean Code – Guidelines Proposal Source Code Repository • Test-Driven Design are part of the source Performance / load stressing tests if it matters on customer side as part of the integration, or stand-alone on staging/pre-prod environment
  37. 37. Clean Code – Guidelines Proposal Source Code Repository • Documentation as Code Reference material as .md files maintained in synch with the source complementary to comments sometimes generated from source (e.g. mORMOt SOA API via Mustache template)
  38. 38. Clean Code – Guidelines Proposal Source Code Repository • Documentation as Code Reference material as .md files duplicated in a semi-public “doc” repo (e.g. for support people, or front-end dev)
  39. 39. Clean Code – Guidelines Proposal Source Code Repository • Infrastructure as Code Automate Containers – virtualized cloud-based hosting – containers defined as code – work with IT to generate (or host) scripts
  40. 40. Clean Code – Guidelines Proposal Source Code Repository • Infrastructure as Code at LiveMon Daemons services endpoints (IP, ports, URI) are all defined in shared pascal code – favor convention over configuration – favor logical over physical – pascal as expressive script language
  41. 41. Clean Code – Guidelines Proposal Source Code Repository • Infrastructure as Code at LiveMon Daemons services endpoints (IP, ports, URI) are all defined in shared pascal code
  42. 42. Clean Code – Guidelines Proposal Source Code Repository • Infrastructure as Code at LiveMon Daemons services endpoints (IP, ports, URI) are all defined in shared pascal code – auto-configuration even on barebones servers – ease scaling and testing – work with IT to generate (or host) scripts e.g. with Mustache templates, or internal REST services
  43. 43. Clean Code – Guidelines Proposal Clean Code Guidelines Proposal • Guidance • Target • Repository • Code Formatting • Types definition
  44. 44. Clean Code – Guidelines Proposal Code Formatting • Define some canonical rules The most sensitive: begin … end blocks, nested if … then, naming conventions Avoid blank lines (refactor in methods)
  45. 45. Clean Code – Guidelines Proposal Code Formatting • Define some canonical rules Use some reformatting tool CnPack, Castalia, … will make all team members aware of it As part of review step (or commit?)
  46. 46. Clean Code – Guidelines Proposal Code Formatting • Define some canonical rules https://blog.golang.org/go-fmt-your-code “easier to write, read and maintain and uncontroversial”
  47. 47. Clean Code – Guidelines Proposal Code Formatting • Define some canonical rules Comments not revision history – use a SCM not (****) – use regions as specs = as valuable as code
  48. 48. Clean Code – Guidelines Proposal Code Formatting • Define some canonical rules But this is not the main point, since formatting is a matter of convention, not logic
  49. 49. Clean Code – Guidelines Proposal Clean Code Guidelines Proposal • Guidance • Target • Repository • Code Formatting • Types definition
  50. 50. Clean Code – Guidelines Proposal Types Definitions • Follow Common Delphi Convention TCamelCase ISomeInterface TSomeEnum = (seOne, seTwo…); TOnSomeEvent = procedure of object; CONSTANT_NUMBER
  51. 51. Clean Code – Guidelines Proposal Types Definitions • No Hungarian Notation TSomeCounterInteger SOMEVALUE_KONST ParameterInput sounds like polluting the modelization → rather use the IDE features
  52. 52. Clean Code – Guidelines Proposal Types Definitions • Class definition TMyClass = class(TOtherClass) private fSomeProperty: TSomeType; public property SomeProperty: TSomeType read…
  53. 53. Clean Code – Guidelines Proposal Types Definitions • Class definition TMyClass = class(TOtherClass) private fSomeProperty: TSomeType; function GetSomeProperty: TSomeType; public property SomeProperty: TSomeType read…
  54. 54. Clean Code – Guidelines Proposal Types Definitions • Class definition use myclassvar.fSomeProperty or myclassvar.GetSomeProperty myclassvar.SetSomeProperty() to make method calls explicit for internal calls
  55. 55. Clean Code – Guidelines Proposal Types Definitions • Class definition TMyClass = class(TOtherClass) private fSomeProperty: TSomeType; published property someproperty: TSomeType read… (when JSON serialized for JS API)
  56. 56. Clean Code – Guidelines Proposal Types Definitions • Class definition follow SOLID principles, mainly: smaller dedicated classes favor composition over inheritance abstraction via interfaces as few unit dependency as possible
  57. 57. Clean Code – Guidelines Proposal Types Definitions • Naming is modelizing Follows the modelized reality, not the tech cf. DDD Ubiquitous Language e.g. TInvoiceTotalValue not double not TSQLSumResult
  58. 58. Clean Code – Guidelines Proposal Types Definitions • Naming is about grammar method = verb in infinitive form event or enumerate = verb in past form variable = reality name (or verb in past form for counts/boolean)
  59. 59. Clean Code – Guidelines Proposal Types Definitions • Naming is about grammar method = SendEmail() event or enumerate = eeEmailSent variable = TEmailTitle, EmailWasSent
  60. 60. Clean Code – Guidelines Proposal Types Definitions • Naming is about grammar method = Email() event or enumerate = eeSuccess variable = Text, ok
  61. 61. Clean Code – Guidelines Proposal Types Definitions • Naming is about meaning i.e. reading the code should be as close as reading the logic in plain English → avoid technical or anemic model
  62. 62. Clean Code – Guidelines Proposal Types Definitions • Naming is about meaning i.e. reading the code should be as close as reading the logic in plain German → avoid technical or anemic model
  63. 63. Clean Code – Guidelines Proposal Types Definitions • Naming is about meaning method = SMTPExecute() event or enumerate = 200 variable = s, b
  64. 64. Clean Code – Guidelines Proposal Types Definitions • Enumerations are a very powerful feature of pascal convenient way to modelize state or errors you could use RTTI to retrieve text (logs)
  65. 65. Clean Code – Guidelines Proposal Types Definitions • Enumerations are a very powerful feature of pascal by convention, first (=0) item is success especially with stubs/mocks
  66. 66. Clean Code – Guidelines Proposal Types Definitions • Enumerations are a very powerful feature of pascal convenient way for compile-time errors e.g. when defining DTOs const CONV: array[TDomainEnum] of TAppEnum = (….);
  67. 67. Clean Code – Guidelines Proposal Types Definitions • Naming is about consistency once you defined some rules, stick to them procedure MyMethod(param: integer); procedure MyMethod(Param: integer); procedure MyMethod(aParam: integer);
  68. 68. Clean Code – Guidelines Proposal Types Definitions • Naming is about consistency once you defined some rules, stick to them var Current: TEmailSender; var current: TEmailSender;
  69. 69. Clean Code – Guidelines Proposal Types Definitions • Naming is absolute in public but it won’t hurt to use i,j,k for local loops (or the for item in items do syntax) local variables may be named according to the technical implementation context
  70. 70. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal var a: integer; begin a := ‘text’; end.
  71. 71. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal var a: integer; begin a := ‘text’; // fails to compile end.
  72. 72. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal JavaScript is (was) not so TypeScript, Dart, Flow, … appeared to write and maintain big projects
  73. 73. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal not only classes or records, but also type TDistanceMeters = type double; TDistanceMiles = type double;
  74. 74. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal type TDistanceMeters = type double; TDistanceMiles = type double; it won’t be slower, but could be much safer!
  75. 75. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal type TDistanceMeters = type double; TDistanceMiles = type double; Make the Implicit Explicit !
  76. 76. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal function CalculateTrajectory( altitude: double): TTrajectory; Make the Implicit Explicit ! Avoid another Mars Climate Orbiter failure!
  77. 77. Clean Code – Guidelines Proposal Types Definitions • Strongly-Typed Pascal function CalculateTrajectory( altitude: TDistanceMeters): TTrajectory; Make the Implicit Explicit ! Avoid another Mars Climate Orbiter failure!
  78. 78. Clean Code – Guidelines Proposal Types Definitions • Exceptions should be exceptional Some languages don’t implement them https://golang.org/doc/faq#exceptions use Exception in “panic” mode when DB or network is down, disk is full, dead branch is reached in code…
  79. 79. Clean Code – Guidelines Proposal Types Definitions • Exceptions should be exceptional Severity is hidden Is it an user input entry error, or a DB failure? Not easy to transmit remotely Exceptions are classes with no persistence and sometimes some pointers to context
  80. 80. Clean Code – Guidelines Proposal Types Definitions • Exceptions should be exceptional Performance cost On all platforms Not debugger-friendly Did you try to debug Indy calls in the IDE?
  81. 81. Clean Code – Guidelines Proposal Types Definitions • Exceptions should be exceptional Rely on Error Codes Dedicated Enumerations Optionally with some text for UI Complex errors may return a class/record But not the same class as on success
  82. 82. Clean Code – Guidelines Proposal Types Definitions • Exceptions should be exceptional Don’t rely on HTTP status codes Logic should be uncoupled from HTTP What if you execute the code locally? Only if you really need it e.g. when implementing a standard
  83. 83. Clean Code – Guidelines Proposal Types Definitions • Exceptions should be exceptional Log and transmit all exceptions On heavily loaded servers, it would save you a lot of time filtering real problems Too much notification is killing the notification!
  84. 84. Clean Code – Guidelines Proposal Clean Code i. From consensus comes success ii. Don’t pollute your code – hide technical iii. Naming is everything iv. Code should be like natural language v. Make the implicit explicit vi. Exceptions should be exceptional vii. ….
  85. 85. Clean Code – Guidelines Proposal • Questions? Clean Code Guidelines Proposal

×