The Dirty Dozen

Dirty Dozen

Kuba Werłos


Software House Innovative Technologies


by
E corp

KICK ME

Chuck Norris

Keep It Complicated Keep Me Employed

One good programmer can easily create two new jobs a year.

KICK ME


  • I am having trouble understanding this code.
  • Let's take a look.
  • Do you see this function? It calls these 13 other functions and has roughly 1000 lines of commented out code in it.
  • Ah yes, that is the Job Security Design Pattern in action!

Hundred responsibilities principle

God
the more the merrier

knows very much or does very much

knows very much LOC, properties, methods
does very much cyclomatic complexity

Hundred responsibilities principle

LOC CC
1.
giggsey/libphonenumber-for-php/geocoding/data/en/61.php
42 571
1
2.
Mpdf\Mpdf
27 208
7 007
3.
TCPDF
24 578
4 379
4.
voku\helper\UTF8
14 013
1 426
5.
TYPO3\CMS\Core\DataHandling\DataHandler
9 586
1 457
6.
PhpOffice\PhpSpreadsheet\Reader\Xls
7 947
1 011
7.
ScssPhp\ScssPhp\Compiler
7 709
1 197
8.
WordPress/wp-includes/functions.php
7 403
737

Untestability

Profits of not having tests:

  • not doing work no one pays for
  • no problems with failing build on Jenkins
  • increase need for manual testing
  • more thrilling changes to the code
  • make it harder to change the code without worrying that anything will get broken
  • deprive us from having documentation for what the code is actually meant to do

Untestability


open/closed principle


A module should be open for modification.

A module should be closed for extension.

Redefine the functionality


reinventing the wheel

re-implementing (limited) PHP functions

prefer implementing custom solutions over using open source library

overriding methods

Really big interfaces


big ⟶ complicated

complicated ⟶ advanced

advanced ⟶ smart

Really big interfaces

Methods
1.
Carbon\CarbonInterface
348
2.
Magento\Sales\Api\Data\OrderInterface
274
3.
Illuminate\Support\Enumerable
112
4.
Drupal\Core\Form\FormStateInterface
91
5.
Knp\Menu\ItemInterface
58
6.
Doctrine\ORM\Query\TreeWalker
50
7.
Zend\Barcode\Object\ObjectInterface
47
8.
Symfony\Component\Form\FormInterface
35

You should rely on others


Extend third party libraries directly

                            class InvoicePdf extends FPDF
                            {
                            }
                        

Use third party libraries directly

                            new Symfony\Component\Process\Process(/* ... */);
                        
Hundred responsibilities principle
Untestability
Redefine the functionality
Really big interfaces
You should rely on others

Bus factor

Bus

Bus factor

Bus

Bus factor

Bus

Bus factor

Bus

Bus factor


The number of team members who, if run over by a bus, would put the project in jeopardy.


The bigger the number is, more people are inreprecable in the procject.


Our goal is to descrease the bus factor.

Early Optimization

Lack of optimization is the root of all evil.

It is not difficult to know what will be the bottleneck.

Prefer efficiency over simplicity.

Try to cache everything you can.

Inheritance over composition

Magento\Backend\Block\System\Store\Edit\Form\Store
extends Magento\Backend\Block\System\Store\Edit\AbstractForm
extends Magento\Backend\Block\Widget\Form\Generic
extends Magento\Backend\Block\Widget\Form
extends Magento\Backend\Block\Widget
extends Magento\Backend\Block\Template
extends Magento\Framework\View\Element\Template
extends Magento\Framework\View\Element\AbstractBlock
extends Magento\Framework\DataObject

Inheritance over composition

Constructor

WET

We Enjoy Typing

Typing

Weeks of programming can save you hours of planning

Meetings

Weeks of programming can save you hours of planning

meetings = waste of time

Analysis Paralysis

Death By Planning

E-mail Is Dangerous

Naming

Hungarian notation:

                            $bCorrect;
                            $iCount;
                            $sName;
                        
Commonly known names:

                            class DatabaseUtil {}
                            class UserHelper {}
                            class PasswordManager {}
                            class AccountFunctions {}
                        

Naming

Use short names and describe more in comment:


                        // This function returns random item
                        // for matching name and category
                        function get2($name, $category) { /* ...*/ }
                    

Do abbreviate


                        $w; // this is username
                    

Magic numbers and strings



                        class PasswordManager
                        {
                            public function setPassword($password) {
                                if (strlen($password) < 8) {
                                    throw new Exception('Password must me longer than 8 characters!');
                                }
                                // ...
                            }
                        }
                    

Magic numbers and strings

Wizard

Anemic domain model


Contains little or no business logic (validations, calculations, business rules etc.).


  • You can claim it's a domain model and brag to your developer friends and put it on your resume.
  • It's easy to generate automagically from database tables.
  • It maps to Data Transfer Objects surprisingly well.

Anemic domain model

The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design.
Martin Fowler

Gypsy wagon

(Poltergeist)

(Big DoIt Controller Class)

When we anticipate the need for a more complex architecture.

Limited responsibilities and roles.

Effective life cycle is short.

Improbability factor


A problem exists in a system.

We are not going to fix the problem,

because chances of the problem ever surfacing are small.

Cargo cult programming

SODD

Stack Overflow Driven Development

Cargo cult

We are ready now!

Success kid
KICK ME
KISS
Hundred responsibilities principle
Single responsibility principle
Untestability
Open–closed principle
Redefine the functionality
Liskov substitution principle
Really big interfaces
Interface segregation principle
You should rely on others
Dependency inversion principle
Bus factor
Increasing the bus factor
Early Optimization
Forget about small efficiencies
Inheritance over composition
Composition over inheritance
WET
DRY
Weeks of programming can save you hours of planning
Hours of planning can save you weeks of programming
Naming
Descriptive, meaningful naming
Magic numbers and strings
Named constants
Anemic domain model
Rich Domain Model
Gypsy wagon
Single responsibility principle
Improbability factor
Test-first approach
Cargo cult programming
Cargo cult used responsibly

Clarification

One good programmer can easily create two new jobs a year.

One bad programmer can easily create two new jobs a year.
David Parnas

Lack of optimization is the root of all evil.

Premature optimization is the root of all evil.
Donald Knuth

Clarification


A module should be open for modification.

A module will be said to be open if it is still available for extension.

A module should be closed for extension.

A module will be said to be closed if it is available for use by other modules.

Sources

Questions?

Thanks


werlos@gmail.com


kubawerlos

https://kubawerlos.github.io/slides