The Reign of Quantity

or, Why Two are Better Than One

Matthew Weier O'Phinney
@mwop

Who and why?

Then

  • Project Lead, Zend Framework
  • Principal Engineer, Zend
Zend Framework Zend

Now

  • Project Lead, Laminas Project
  • Product Manager / Principal Engineer, Zend by Perforce
Laminas Project Perforce

What is Quality?

A metaphysical digression

Zentangle

Zentangle
  • Gratitude and Appreciation
  • Corner Dots
  • Border
  • String
  • Tangle
  • Shade
  • Initial and Sign
  • Appreciate

Competence and Expertise

A psycho-educational digression

The Dreyfus Model

Skill Level / Mental Function Novice Advanced Beginner Competence Proficient Expert
Recollection Non-Situational Situational Situational Situational Situational
Recognition Decomposed Decomposed Holistic Holistic Holistic
Decision Analytical Analytical Analytical Intuitive Intuitive
Awareness Monitoring Monitoring Monitoring Monitoring Absorbed
Rules-Based Big Picture

The Expert Beginner

Jack of All Trades

Master of None

Don't Miss the
Big Picture

But How Does This Relate to Software Quality?

Do you want to be a software craftsperson?

We Practice

What do we practice?

  • Coding Standards
  • Testing

Coding Standards

Just use one

  • Consistency
  • Readability

Testing and Making Testable Systems

A Value Object


final class Quantity
{
    private $value;

    public __construct(int $value)
    {
        $this->value = $value;
    }

    public function getValue(): int
    {
        return $this->value;
    }
}
                    

Covering Your Paths


class ValueOfSomeKind
{
    public function getParameter()
    {
        if (! $this->parameter) {
            $this->parameter = new ParameterValue();
        }
        return $this->parameter;
    }
}
                    

public function testGetter()
{
    $instance  = new ValueOfSomeKind();
    $parameter = new ParameterValue();
    $instance->setParameter($parameter);
    $this->assertSame($parameter, $instance->getParameter());
}
                    

public function testReturnsPreviouslyInjectedParameter()
{
    $instance  = new ValueOfSomeKind();
    $parameter = new ParameterValue();
    $instance->setParameter($parameter);
    $this->assertSame($parameter, $instance->getParameter());
}

public function testInitializesAParameterIfNoneInjected()
{
    $instance  = new ValueOfSomeKind();
    $parameter = $instance->getParameter();
    $this->assertInstanceOf(ParameterValue::class, $parameter);
}
                    

Parameter Overloading


/**
 * @param string|array|Emittable $name
 * @param null|object|Emittable $target
 * @param array|callable|Emittable $argv
 * @param null|callable $callback
 * @return mixed
 */
function emit(
    $name,
    $target = null,
    $argv = [],
    $callback = null
)
                    

How many behaviors does this have?


/**
 * @param string|array|Emittable $name
 * @param null|object|Emittable $target
 * @param array|callable|Emittable $argv
 * @param null|callable $callback
 */
function emit(
    $name,
    $target = null,
    $argv = [],
    $callback = null
): void
                    

/**
 * @param null|callable $callback
 * @return void
 */
function emit(
    Emittable $emittable,
    callable $callback = null
): void
                    

function emit(Emittable $emittable): void
{
}

function emitUntil(
    Emittable $emittable,
    callable $callback
): void
{
}

Behavioral Thinking

  • What is the matrix of possible arguments and the expected output from each combination?
  • What are the possible errors?

Other Things To Practice

SOLID

  • Single Responsibility Principle
  • Open-Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

Refactoring

  • Extract Method
  • Extract Class
  • Extract and Generalize Types

Code Calisthenics

  • Only One Level Of Indentation Per Method
  • Don’t Use The ELSE Keyword
  • Wrap All Primitives And Strings
  • First Class Collections
  • One Dot Per Line
  • Don’t Abbreviate
  • Keep All Entities Small
  • No Classes With More Than Two Instance Variables
  • No Getters/Setters/Properties

More info in The ThoughtWorks Anthology

...but they're just more rules.

It takes practice

and endless questioning.

Ask for peer review.

Collaborate