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.
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. 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. 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. Clean Code – Guidelines Proposal
Guidance Proposal
• Proposal
Start from the current LiveMon Guidance
(because I wrote it)
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. 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. 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. Clean Code – Guidelines Proposal
Guidance
• Ease maintainability and interoperability
don’t write for yourself
eventually help yourself
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. 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. 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. 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)
19. Clean Code – Guidelines Proposal
Compiler Target
• For which Compiler and OS (eventually)
Delphi
FPC
others (TMSWebCore, SMS, EWB…)
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. 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. 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. 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
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. 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. 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. 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. 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. 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. Clean Code – Guidelines Proposal
Source Code Repository
• Folders Hierarchy at LiveMon
data
daemon
ext
serv
test
tools
ui
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
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. 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. 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. 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. 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
51. Clean Code – Guidelines Proposal
Types Definitions
• No Hungarian Notation
TSomeCounterInteger
SOMEVALUE_KONST
ParameterInput
sounds like polluting the modelization
→ rather use the IDE features
53. Clean Code – Guidelines Proposal
Types Definitions
• Class definition
TMyClass = class(TOtherClass)
private
fSomeProperty: TSomeType;
function GetSomeProperty: TSomeType;
public
property SomeProperty: TSomeType read…
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. 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. 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. 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. 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. Clean Code – Guidelines Proposal
Types Definitions
• Naming is about grammar
method = SendEmail()
event or enumerate = eeEmailSent
variable = TEmailTitle, EmailWasSent
60. Clean Code – Guidelines Proposal
Types Definitions
• Naming is about grammar
method = Email()
event or enumerate = eeSuccess
variable = Text, ok
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. 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. Clean Code – Guidelines Proposal
Types Definitions
• Naming is about meaning
method = SMTPExecute()
event or enumerate = 200
variable = s, b
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. 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. 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. 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. 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. 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. Clean Code – Guidelines Proposal
Types Definitions
• Strongly-Typed Pascal
var a: integer;
begin
a := ‘text’;
end.
71. Clean Code – Guidelines Proposal
Types Definitions
• Strongly-Typed Pascal
var a: integer;
begin
a := ‘text’; // fails to compile
end.
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. Clean Code – Guidelines Proposal
Types Definitions
• Strongly-Typed Pascal
not only classes or records, but also
type
TDistanceMeters = type double;
TDistanceMiles = type double;
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. Clean Code – Guidelines Proposal
Types Definitions
• Strongly-Typed Pascal
type
TDistanceMeters = type double;
TDistanceMiles = type double;
Make the Implicit Explicit !
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. 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. 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. 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. 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. 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. 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. 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. 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. ….