/usr/portage

Polite Exceptions – Fixing the stepchild of API design 2

Every API has an visible, an invisibile and a hidden part. The visible part is obvious: public methods and properties but also constants and parameter values. That’s the most visible part to any client (read: user) of your API. The invisible part is everything private, you can’t really see it and – more important – you can’t use it (except if you resort to reflection). The hidden part consists of all the protected symbols, as you can’t really see them until you extend a class. The other hidden part are Exceptions. You can’t really see them and there is no common expectation what methods throw what kind of exception. Yes, throws@-docblocks help, but that’s mostly all we have.

Exceptions handling: the problem

The usability of hidden parts of an API is all about expectations: people love languages like Ruby because once you learned a certain set of API (e.g. the string API), you can instinctively infer a large part of other APIs. This is good and keeps learning costs down. PHP, on the other hand, with its historically grown standard extension is on the opposite site of the fence: various parameter order the naming scheme is unreliable at best.
The future is multi-lingual, you need to know more than one programming language and speed of learning matters. Like, a lot. Because “X programmers”, for any value of X, are weak players. What type of exception a class might throw should be defined by clear expectations for the general case. If you use a preconceived HTTP client httpFoo, call method request() and want to handle exception cases, what exactly do you catch?

Talent borrows, genius steals

Zend Framework 2 has a lot of problems but there are two things they did particularly well: naming of abstract classes and interfaces and how they treat exceptions. Every component (see, component is a lie here, as they aren’t really stand alone components but I digress) has its own exception subpackage which has extension specific exceptions. Those exception all implement a single marker interface called ExceptionInterface. If you use Zend\Something and want to handle all exceptions, just catch Zend\Something\Exception\ExceptionInterface.

Programming transaction costs

Time to relevant data is the new time to market. We no longer optimize for feature-complete products shipping on a certain date but relevant changes generating relevant data as soon as possible. Therefore programmer round-trips matter. I consider everything that is not core domain or core UI a round trip:

These steps aren’t worthless, they are worth less from a business perspective as they don’t generate revenue very soon. However they are needed to keep revenue over time. So let’s make those things cheaper.

When dealing with Exceptions in Symfony 2 projects, two steps are particularly expensive:

Especially the latter can be simplified quite dramatically.

Simplifying

To simplify Exception handling, we just open sourced a bundle we developed at InterNations. Let’s create a few custom exceptions:

php app/console exception:generate app/src/MyVendor/MyBundle "MyVendor\MyBundle" \
 ExceptionInterface RuntimeException DomainException RuntimeException:SpecificRuntimeException
Create directory app/src/MyVendor/MyBundle/Exception
Writing app/src/MyVendor/MyBundle/Exception/ExceptionInterface.php
Writing app/src/MyVendor/MyBundle/Exception/RuntimeException.php
Writing app/src/MyVendor/MyBundle/Exception/SpecificRuntimeException.php
Writing app/src/MyVendor/MyBundle/Exception/DomainException.php

Let’s rewrite an existing bundle to use custom exceptions:

php app/console exception:rewrite app/src/MyVendor/MyBundle "MyVendor\MyBundle"
Found bundle specific exception class BadFunctionCallException
Found bundle specific exception class BadMethodCallException
Found bundle specific exception class DomainException
Found bundle specific exception class InvalidArgumentException
Found bundle specific exception class LengthException
Found bundle specific exception class LogicException
Found bundle specific exception class OutOfBoundsException
Found bundle specific exception class OutOfRangeException
Found bundle specific exception class OverflowException
Found bundle specific exception class RangeException
Found bundle specific exception class RuntimeException
Found bundle specific exception class UnderflowException
Found bundle specific exception class UnexpectedValueException
...............
------------------------------------------------------------
------------------------------------------------------------
SUMMARY
------------------------------------------------------------
------------------------------------------------------------
Files analyzed:               15
Files changed:                1
------------------------------------------------------------
"throw" statements found:     2
"throw" statements rewritten: 1
------------------------------------------------------------
"use" statements found:       1
"use" statements rewritten:   1
"use" statements added:       1
------------------------------------------------------------
"catch" statements found:     0

You’ll find the ExceptionBundle over at github. It uses PHP Parser to rewrite code which proves again to be a wonderful project.

Filed on 20-12-2012, 10:10 under , , , , & two comments & no trackbacks

Antipattern: the verbose constructor 48

Constructors are often used to shortcut dependency injection and parameter passing on instantiation. This is a valid practice and often leads to shorter code. Consider the following example (a simple value object, often used to not mess around with floats and to keep currency and amount together):

class Money
{
    protected $_amount;
    protected $_currency;
    protected $_divisor;
    public function __construct(
        $amount = null, $currency = null, $divisor = null)
    {
        if ($amount !== null)
            $this->setAmount($amount);
        if ($current !== null)
            $this->setCurrency($currency);
        if ($divisor !== null)
            $this->setDivisor($divisor);
    }
    ... setter and getter ...
}

Now consider instantiating this object. Instead of creating a new instance of “Money” and calling three setter, everything can be done compactly in the constructor.

bc . $money = new Money(13200, ‘EUR’, 100);

So for the money object this works pretty well. The code is easy to read, but wait, the first argument can be grasped easily, the second too, but the third? It is not too obvious that it is a divisor is passed. An alternative would be changing the constructor to accept an array. This is a replacement for true named arguments, as e.g. Python supports. Solar uses that a lot, as well as the Zend Framework.

$money = new Money(
    array(
        'amount' => 13200,
        'currency' => 'EUR',
        'divisor' => 100
    )
);

Much better readable but does your IDE code completion works? And what happens if you pass “amoµnt”, because your fingers are as clumsy as mine? Exactly, the parameter will be silently ignored.
But look at this:

$money = new Money();
$money->setAmount(13200);
$money->setCurrency('EUR');
$money->setDivisor(100);

It is at least equally short, readable, your IDE works and if you have problems with the dimensions of your keys on your keyboard (they are too small, it has nothing to do with your fingers) you will be warned. But we could even have an even shorter example while maintaining the readability. With fluent interfaces we would get the following:

$money = new Money();
$money->setAmount(13200)->setCurrency('EUR')->setDivisor(100);

Wonderful! If you want, you can add a newline between each object operator and you would have the same amount of lines but less dense code (sad that we don’t have fluent constructors, isn’t it?). Sometimes setters are so elegant.

So until know one thing should be clear: it is not just about easily writing the code, but about the next guy understanding it too. Because you never write code for yourself. Never. But let’s investigate some real live example. I work with a framework that allows me to define really nifty business logic by just sticking together a bunch of fields and every field having a bunch of validators and filters attached.

class User extends Model
{
    protected function _define(Definition $definition)
    {
        $definition->addField(new StringField('username', true, null, true));
    }
    protected function _getStorageClass()
    {
        return 'UserStorage';
    }
}

All the time I write such a definition, I need to look into the code to check the order of the parameters. I can remember the first parameter, but the rest is too similar. To explain it: the second parameter specifies whether the field is required, the third expects a default parameter and the fourth indicates whether the value can be changed after it has been set once. I’ve talked about filters and validators, right?

class User extends Model
{
    protected function _define(Definition $definition)
    {
        $definition->addField(new StringField('username', true, null, true))
            ->addValidator(new UniqueUserValidator())
            ->addFilter(new LowercaseFilter())
            ->addValidator(new RegexValidator('/^[a-z]+$/'));
    }
}

Definition::addField() returns the passed field object to allow adding validators and filters. What works for validators and filters, should work for the rest too, shouldn’t it?

class User extends Model
{
    protected function _define(Definition $definition)
    {
        $definition->addField(new StringField('username'))
            ->setRequired(true)
            ->setReadonly(true);
    }
}

I admit, a bit more code to write, but a huge improvement in readability and therefore in maintainability. Other variants, where setter are not a good solution is to create an expressive factory. We e.g. have a Criteria object that creates and orders Criterion objects internally. Because we don’t have a fluent constructor, we have a static create-method for the Criteria object.

$criteria = Criteria::create('User')->field('id')->equal(1);

The alternative with just utilizing the constructor would be horribly to read and would have limitations regarding the parameter parsing capabilities (except if func_get_args() is used, which is totally the opposite of the paradigm of strict APIs). But back to the constructor only example:

$criteria = new Criteria('User', array('id' => 1));

And how would you express “id not equal 1” with it? So that’s where expressive factories are an alternative.

Constructors, as like any other method, should have as less parameters as possible but as much as needed. Obvious. The constructor should only allow setting vital information for the object (if the object has a name, there is a good chance, that the name is the parameter of the class’ constructor because it is considered vital). And the ease of use depends heavily whether the parameters passed can be intuitively distinguished by looking at there values. As well when the code is written first time as for maintaining it for the rest of your life.

(There are a bunch of other tricks to make parameters more readable, like using class constants as parameters, but this is out of scope of this article).

Filed on 31-07-2008, 01:01 under , , & 48 comments & no trackbacks

Relational data 0

I concede that the relational model is the worst form of DBMS except for all those other forms that have been tried from time to time.
Bill Karvin – In Support of the Relational Model

I can’t agree more with that statement. Also I find software like CouchDb really interesting, it will not be the way to go. Beneath modeling, the main advantage of relational models is the flexible question startpoint (in terms of SQL it means the basic information you have beforehand to get the rest of what you need). If you know just a little about tree structure, the start point problem will be self-explaining. Accessing an upper node from a sub node just can’t be implemented as fast as accessing a flat structure and there relations.

Filed on 30-11-2007, 07:07 under , , & no comments & no trackbacks

Preventing cross site scripting by design 4

This is more or less a reply to Dynamic global functions in PHP. My main problems with delegating escaping in the template is the fact, that the people who normally work with templates, are frontend developers and designers. Those who do not and should not care about web security. That is a programmers/architects field. Nobody of the frontend developers should have the possibility to create security level artefacts by accident. So, when a value arrives the template, everything should be done. No special escape-calls should be necessary. I will show you how we do escaping and template value sanitizing at Neu.de. But let’s step through all common models in order to explain, why they are bad. I assume you know the basic MVC-terms, I will use here mostlye view and controller action. First of all, the most common approach. Just assigning variables as-is to the view component:

The second – much better approach – is to escape values before accessing them in the template. This is fine as long as you do not use objects in your templates.

If you have complex, nested objects encapsulating complex business rules, you do not want to convert them to an array to make it possible to escape them afterwards because of speed concerns. So if you pass an object with a method which returns fragile user input, your escaping logic is bypassed. See:

The solution is to wrap assign objects in mock objects. You can easily implement a mock object builder using PHP5s reflection features and create a simple proxy which escapes the return values of every call – or – if an object is returned – wrappes this return object in another mock object. And so on and so on:

Once you implemented that, a) your developers must not care about XSS anymore, they just use the framework and b) you can sleep better at night, because it is not likely probable, that your site is vulnarable against XSS. Sometimes you want to allow HTML-code passing to the template. That’s ok, just give the developer a chance to avoid mocking or escaping. If you want to audit your code for XSS security problems, just grep for the method signature.

Filed on 22-10-2007, 14:02 under , , , , , & four comments & no trackbacks

Interaktionszeug 11

Also, heute mal zum Mitmachen: was hielten die Leser davon, wenn es hier bald so aussähe?

Update:
Nachdem hier so viel gemeckert wurde, hier eine geänderte Variante mit weniger klassischer Fraktura und anderem Farbenset.

Filed on 12-01-2007, 01:01 under , , & eleven comments & no trackbacks

Migration allenthalben erledigt 0

Was Hanno und Stefan schon zu berichten wussten, gibt es nun auch hier zu lesen: Schokokeks.org ist umgezogen.


Continue reading "Migration allenthalben erledigt"

Filed on 28-03-2006, 11:11 under , , , , , , , , & no comments & no trackbacks

22C3: Technological art off the trodden tracks 0

Quite fine talk. Régine Débatty (Weblog, read it!) and Jussi Ängeslevä are currently talking about »Technological art off the trodden tracks«. They’re focusing on the use of »bad« techniques, e.g. RFID-tags, CCTVs and so on, for funny and artistic issues. There thesis are to combine hacking and artistical work.
A good idea, as I think (nevertheless I want to abolish arts) to combine different kinds of »hacking«. Use hacking as a term for creative work on and with different techniques. Constructing a gap between hacking and arts is quite synthetic or do you really argue that all the thing the hackers are doing makes sense?

Filed on 28-12-2005, 21:09 under , , , , , , , & no comments & no trackbacks

New Clearlooks-Theme and Tango-Icons 7

To win the verbal pissing contest (german alias: »Schwanzvergleich«), just a nice screenshot with the cairo-based »Clearlooks 2«–Theme and Tango-Icons

Filed on 19-12-2005, 01:01 under , , , , , , , , , , & seven comments & no trackbacks

Lars’ Wahrheiten 0

Heute ist »Tag der Lars’schen Wahrheiten«. Sätze die mit »was ich schon immer sage …« beginnen und in diesem Falle enden mit »Linus Torvalds hat einen unübersehbaren Schatten«.
Mehr dazu gibt‘s bei Bernd, der sich gerne in den selbigen stellt und die entsprechenden Hintergrundinformationen bei Golem.

Filed on 13-12-2005, 16:04 under , , , , , , , & no comments & no trackbacks

Freie Software und Kommunismus 2

Ich sag’s doch schon immer, beides wird sich durchsetzen. Was zuerst passiert kann ich nicht sagen aber das dem nu2m-Designer GIMP gefällt ist ja schonmal ein Anfang …

Filed on 13-12-2005, 15:03 under , , , & two comments & no trackbacks