From 5ccba6c54a26d408dc6f0730a0a7e68d54b70025 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 9 Oct 2018 11:20:37 +0000 Subject: [PATCH] [IMP] doc: add guidelines about extandability If the code is well written from the start, won't get so many hook requests closes odoo/odoo#27570 --- doc/reference/guidelines.rst | 44 ++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/doc/reference/guidelines.rst b/doc/reference/guidelines.rst index 1ee0c1ac92f..10bd221a51e 100644 --- a/doc/reference/guidelines.rst +++ b/doc/reference/guidelines.rst @@ -622,17 +622,47 @@ online documentation of pyscopg2 to learn of to use it properly: - Advanced parameter types (http://initd.org/psycopg/docs/usage.html#adaptation-of-python-values-to-sql-types) -Keep your methods short/simple when possible -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Think extendable +~~~~~~~~~~~~~~~~ Functions and methods should not contain too much logic: having a lot of small and simple methods is more advisable than having few large and complex methods. -A good rule of thumb is to split a method as soon as: -- it has more than one responsibility (see http://en.wikipedia.org/wiki/Single_responsibility_principle) -- it is too big to fit on one screen. +A good rule of thumb is to split a method as soon as it has more than one +responsibility (see http://en.wikipedia.org/wiki/Single_responsibility_principle). -Also, name your functions accordingly: small and properly named functions are the starting point of readable/maintainable code and tighter documentation. +Hardcoding a business logic in a method should be avoided as it prevents to be +easily extended by a submodule. -This recommendation is also relevant for classes, files, modules and packages. (See also http://en.wikipedia.org/wiki/Cyclomatic_complexity) +.. code-block:: python + + # do not do this + # modifying the domain or criteria implies overriding whole method + def action(self): + ... # long method + partners = self.env['res.partner'].search(complex_domain) + emails = partners.filtered(lambda r: arbitrary_criteria).mapped('email') + + # better but do not do this either + # modifying the logic forces to duplicate some parts of the code + def action(self): + ... + partners = self._get_partners() + emails = partners._get_emails() + + # better + # minimum override + def action(self): + ... + partners = self.env['res.partner'].search(self._get_partner_domain()) + emails = partners.filtered(lambda r: r._filter_partners()).mapped('email') + +The above code is over extendable for the sake of example but the readability +must be taken into account and a tradeoff must be made. + +Also, name your functions accordingly: small and properly named functions are +the starting point of readable/maintainable code and tighter documentation. + +This recommendation is also relevant for classes, files, modules and packages. +(See also http://en.wikipedia.org/wiki/Cyclomatic_complexity) Never commit the transaction