Aphorisms of API Design
by Larry Garfield (crell)
http://chicago2011.drupal.org/sessions/aphorisms-api-design
Application Programming Interface
code for which the intended user is ... more code.
aphorism: subjective truth or observation
not fixed rules. guidelines
Garfield's Law:
One is a special case of many.
Pointed out in reference to CCK fields in http://groups.drupal.org/node/8001
Similarly, in Drupal 7, node_load() is now a simple wrapper around node_load_multiple().
machine names are better than constants
You can arbitrarily add new ones when based on machine names, whereas if people try to extend based on constants they are more likely to conflict.
Boolean is the exception. It is true or not true.
Aphorism 1: N is the only number.
All other numbers are a special case of N.
"Fail fast, fail cheap, be lazy." — Rasmus Lerdurf
Don't plan for everything. Plan for how you will break.
Instead of silently failing, generate a watchdog message.
Fail early, fail often:
- Constrain input
-
Good APIs are picky.
If there is something other than an array handed in where there should be an array, trigger a fatal error immediately. You know exactly on what line the problem was. This is much better than an error message four function calls later.
A good programmer is someone who looks both ways before crossing a one-way street.
-- Douglas ..
If you are not developing under E_ALL|E_STRICT, you are doing it wrong.
2: Fail fast... fail usefully.
Don't use undocumented APIs
Don't privilege your own code. Use your API yourself. You will know where the pain points are, because you will run into them.
You're not done until you have 3 implementations.
3: Play by your own rules.
4: A UI is not an API.
A user is not a program.
A UI is a client of your API.
A website uses an API.
An API does not need
Do your three implementations in this form:
- Simpletest
- Drush
- Web-based form
This allows you to build a better UI as well
4
You know that saying about standing on the shoulders of giants?
Drupal is standing on a huge pile of midgets.
--Jeff Eaton
Try not to write an API. We have enough!
Views, Fields, JQuery, Drupal queue, CTools,
If you do have to implement a new API, do it in the same way as everyone else.
Mimicry is the highest form of flattery. It's less work. [It works better.]
Learn this pattern once, and you know how all these other APIs work.
hook_menu, hook_theme, etc.
an array of information, and a drupal_alter()
The best API is API you didn't have to write.
Don't make decisions if you don't have to.
If you can punt until later, do so. You'll have more information then.
Make changing your mind cheap.
Esp. when the client is going to change their mind.
You can only change what is encapsulated.
Caching, prime example. Don't decide how caching is going to be done.
instead, in Drupal 7, we have a caching interface: DrupalCacheInterface
Same with logging.
Need an explicit interface, boundary between
Separate business logic from data.
Separation of concerns
- interface-driven development
- context-free logic
- dependency injection: allow yourself flexibility
6: You cannot delegate what you cannot separate.
Once you have separated
Delegation adds indirection.
Indirection requires abstraction.
Abstraction hides complexity.
[this complexity] Abstraction is not free.
call_user_func_array is three times as slow as calling a function directly.
Every hook uses this :-(
db_select at least 30% slower than db_query
Complexity:
FAPI - confused on a daily basis
Rules 1 - could not comprehend
Panels
Div-itis
What the heck is going on under the hood?
No-one knows all, except chx, and not even him.
The unavoidable price of reliability is simplicity.
7 There is no problem that cannot be solved by adding another layer of abstraction, except abstraction.
Drupal has idiosycrasies, but it's not special.
The code is not that cool.
No one understands all Drupalisms.
No matter how cool you are, John Resig knows more Javascript than you do.
This is why we use JQuery in Drupal.
filter_xss()
began life as kses - took it from third-party project called kses originally. It's crazy hard problem spaces.
We fixed a bug in kses! but someone else took care of most of them for us.
We use a fork of the Simpletest library, mostly gutted and rewritten.
But we started from Simpletest, which means we started form the same model...
someone who knows unit testing will find the way you write unite tests is the same.
Entities/Fields
i take partial blame for this
"Because no one has ever tried to solve that problem before, ever..."
We probably should have looked first.
Age of Drupal: 10 pears
Age of PHP: 16 years
Age of 3rd gen languages: 54 years
There are decades of experience in software.
Do your homework:
PECL
jQuery
Zend Framework
Kohana
Symfony
Wordpress
Design patterns
Java
3rd party benchmarks
Feature Drupal does not need: Ego.
8 You are not a beautiful or unique snowflake
Grand Unified:
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
Assume that in six months, some one will need to do something you never thought of with your code and will not be able to edit it.
That will be you.
Plan accordingly.
Further Reading:
97 Things Every Software Architect Should Know. Richard Monson-Haefel
http://The DailyWTF.com
Design Patterns: Elements of Reusable Object-Oriented Sofware - Gamma, Helm, Johnson, Vlissides
http://www.SoftwareQuotes.com
http://www.planet-php.net
Community is Drupal's real advantage, not the code, not the architecture.
We don't want to live in our little bubble.
look at Django, some other language or framework.
My PHP code got better after spending a day reading the documentation for Erlang.
Are your aphorisms contradictory?
Yes.
All software design is balance.
Built to spec, built cheap, or built quickly.
Taking something from somewhere else, doing things yourself. You have to choose.
Comments
Post new comment