Reinventing the wheel

This is what most PHP developer do, most of the time. Most PHP devs don’t like to reuse, they think their case is unique, those who don’t… well, they don’t call themselves php developers, they call themselves drupal devs or wordpress devs or symfony devs or whatever cms/framework dev.

But the real (sarcasm) php dev will create an acl from scratch at every job he have. he will create countless media manager, db layer, session manager, etc. Don’t get me wrong, I think you can’t be a good php developer if you haven’t gone through this stage, but please, for the sake of your coworker sanity, keep you’re “learning process” outside of the workplace and don’t forget that you should stick to “learn-and-throw-away”.

Some bad reason to reinvent the wheel that I hear all the time:

Existing solution does not apply to us

Yeah right, you feel better when you think you are unique, good for you, but unfortunately it’s probably not true. I agree on one thing though, you’re different, everybody is different, that’s why the solution will need to be adapted, but surely not written from scratch.

It’s gonna be faster to create our own solution rather than adapting or learning something else

Yeah right, it’s gonna be faster for the guy doing it this time, but for everybody else trying to use/modify/understand it in the future it’s gonna be a pain in the ass because your solution will be half documented (probably not documented at all) and with no community support. By the time somebody needs help from the original developer, he will probably be working somewhere else, reinventing the wheel again…

There is nothing in the whole universe that remotely resemble what we’re trying to do

Yeah right, again, the “I’m unique” power trip. There’s billion of people on the planet, that have met and fixed billions and billions of problems, a lot of them have written about their solution in books, blogs, code, tweet….

Leave the first comment

Design Patterns from DDD

I’ve mentionned DDD in the previous post, this post is me drafting publicly my thought on the design patterns generally associated with it. this is a work in progress.

Even if not doing Domain Driven Development, the design patterns usually used by the DDD people are something that can benefit a lot of project. To start learning more about design pattern, “Patterns of Enterprise Application Architecture” by Martin Fowler 1 is a must read. If you can’t afford the book, then go steal some money (just kidding) or start by reading the free short summary of each patterns available on the author’s website 2.

Domain Models are a representation of the data, they represent nouns in you domain, such as User or Invoice. As the domain model contain the business logic, it should be the most important part of the code, thus it need to be easy to understand, easy to modify and easy to test. That’s why they should have no external requirement, no knowledge of the external world, avoid tight coupling at all cost.

Domain models contains the business logic (verbs), mainly in the Entity and Repository, and some in the service layer (if, and only if the functionality does not apply to an entity in particular, reference others object of the system, and is stateless. (ex1: $shippingService->calculateShippingCost($zipcode). this does not belong in the Cart Entity because of the dependency on external object such as shipping company API).

Entities should be totally standalone, they should not be aware of repository or anything else.

Entities and Repositories does not write directly to a database or web service, a database layer is usually used such as ActiveRecord or DataMapper. But, writing an activeRecord of dataMapper layer is a long and difficult job, and it’s generally a better choice to use an existing one, especially because of the fact that this layer contain no business logic, there is not a big Return On Investment on building our own.

Some part of the application might seems like Entity but are in fact Aggregate. Some object can’t exist by themselves, such as OrderDetails, they are Aggregate that are connected to an Aggregate Root Order. This mean that the Aggregate don’t have a repository and if you want to add a row to an order you need to go thru the Order Entity. ex: $order->addDetail(…)


  1. http://www.martinfowler.com/books.html#eaa 

  2. http://martinfowler.com/eaaCatalog/ 

Leave the first comment

Domain Driven Design

Domain Driven Design is a development methodology, the term have been coined by Eric Evans 1.

Domain Driven Design (DDD) being a complete development methodology, that means that you can’t learn DDD simply by reading code sample, and a few things are necessary for his success, such as:

  • Developers who understand design patterns
  • Access to a Domain Expert and close relationship with the client

The domain expert requirement is a big one, you actually need someone from the domain, ie: if you are in the banking industry, you need a banker to have this role, not a developer or an architect who is a self proclaimed domain expert. DDD involve a lot of communication with the domain expert to define the ubiquitous language 2 and integrate them in the domain models. To keep using our banking example, a developer who knows absolutely nothing about banking should learn an awful lot about the domain (banking) just by looking at the code for the domain model.

A DDD team will probably be using a bunch of design pattern such as:

  • Domain Model
  • Service Layer
  • ActiveRecord or DataMapper
  • LazyLoad
  • Repository & Query Object

But the sole fact of using these patterns does not mean you have a DDD team. I can’t find the orignal source, but apparently 3 Eric Evans almost regrets having mentioned these design pattern in the book because they can lead to that false conclusion that DDD is just ‘using some specific design pattern’ when if fact it is so much more and involve discussion and collaboration with clients and domain experts. We can see the same feeling about design patterns and lack of domain expert expressed in the excellent video “7 Reasons Why DDD projects #FAIL” 4 by Greg Young.

DDD is not for everybody, if your app is mainly retrieving data from the database to display with some fancy design, DDD would just be adding a layer of complexity on something really simple, ActiveRecord or DataMapper is probably a better solution for your need. Such an example where DDD is overkill, and e-commerce website for Mom & Pop’s shop, as there is little logic, lots or database reading and some cool graphics… But complex subscription plan and pricing and discount model is a good candidate for DDD.

I won’t go deeper into the world of DDD as I have no experience with it and I’m not currently working on any team that can switch to this methodology easily.

I’ll close this part with a great quote from “DDD Step By Step” 5

[...] I view Domain Driven Design firstly as a design methodology, secondly as an architectural style, and lastly as some great software patterns.

More Reading

Stack Overflow have some good links to get you started with DDD

http://stackoverflow.com/questions/493068/best-resources-on-the-web-for-learning-domain-driven-design-ddd-in-depth

(my favorite being the InfoQ miniBook, a quick read that give just enough information to get you interested)


  1. http://domaindrivendesign.org/books/evans_2003 

  2. http://domaindrivendesign.org/node/132 

  3. http://thecodersbreakfast.net/index.php?post/2009/06/16/Paris-JUG-%22Domain-driven-design%22-%3A-compte-rendu 

  4. http://vimeo.com/13824218 

  5. http://thinkddd.com/assets/2/Domain_Driven_Design_-_Step_by_Step.pdf 

Leave the first comment

how to be a better developer

Or at least not suck as a developer/coworker

change job

If you have only worked for one company, using only one style of coding and project management, and have seen only your code / your friends code, then do everybody a favor (including you) and get out of there, go see how things happens “in the wild”.

share

Write, mentor someone, or contribute to an opensource project, you need to learn to explain clearly and and easily your ideas and what your code is doing. If you can’t you either:

  • don’t really understand what you’re doing
  • have sucky communication skills

Both issues are worth working on, as they will improve your life and those of people surrounding you.

read

Read lots of books, blogs, essay on programming, etc that expose different concept and point of view.

code

aka don’t read too much

You should code at least as much as you read, or you risk becoming somebody living in Utopia city, the type of guys who abuse design patterns for hypothetical reasons. Once again, to achieve this you can work on a pet project, contribute to an opensource project (better), or turn to code kata, code dojo or somethings like the EdgeCase Ruby Koans that have been ported for many programming language.

plagiate

and throw away (very important)

Yes, it’s still writing code, but writing code is a really important thing to do while learning. Re-implement existing things as a learning exercise. It’s easy to do because you don’t have to spec the project, you already know the desired outcome and you don’t need to find a killer idea (waiting for inspiration is a good way to kill a learning session). But be careful, do this as a learning exercice only, everybody hates a coworker who constantly reinvent the wheel. You need to throw away this code once it’s done. Learning to let go your code is as important as learning to code, a good developer will delete a lot code in his career…

note:

If you really want to read more than you code, you risk becoming one of these pattern abusers I’ve just mentioned. Please, go read this old blog post right now: Head First Design Patterns

3 comments so far, add yours

Ottawa PHP

PHP devs in or around Ottawa should check out the brand new Ottawa PHP google group and #ottawaphp freenode channel (and of course my very own Ottawa PHP Community aggregator).

update: both projects killed due to total lack of interest and/or php developers in Ottawa

Comments Off

Propaganda

confoo.ca Web Techno Conference

Comments Off

PHP Standards Working Group

It’s great to see that PHP is gaining maturity lately. After the release of version 5.3 that have introduced namespaces, it’s now time for some of the biggest php projects to get together to discuss and agree on a common autoloader standard. This really nice project would allow interoperability between frameworks/projects.

Take a look at the proposal PSR-0 and try the autoloader on your new project. The more people using it, the easier our life will be as a PHP developer.

Note: if you want to give feedback to the group about the proposed standard, you’d better do it on twitter or on your blog, because there seem to be some not so clearly defined rules to be able to join the group… update 2009-11-11: thanks to Nate Abel there is now a public Project Acceptance Guidelines posted so this comment doesn’t hold true anymore. Thanks Nate.

Note 2:: if you’re wondering how nice your code could look by using namespaces in php, check out the lithium framework (#li3) for a good example.

One comment so far, add another

Doctrine 1.2 is Zend Framework friendly

Deprecated: This code uses an old version of Doctrine and Zend Framework, there is now an semi-official way of integrating Doctrine and Zend Framework, see the announcement of the zf-doctrine project and checkout my plugin for ZFDebug to have access to the Doctrine Profiler: http://github.com/danceric/zfdebugdoctrine

I’ve talked about that before on this blog. Using Doctrine 1.1 with ZendFramework 1.8 and using both with ZFDebug. Now things will only get better as both project will officially play nice together. Here’s the announcement on the Zend Framework mailing list.

This is some pretty good news, the other good news is that you don’t have to wait until the integration is ready to start playing with both. I’ve been testing out the alpha3 release of Doctrine 1.2 and I’m pleased to see that it’s really PEAR friendly, which make it a breeze to use it with the Zend Framework (that wasn’t as easy with Doctrine 1.1).

you can follow along with the code on github of my demo app: github.com/danceric/zfdebugdoctrine

First thing, the base doctrine class have been moved from /Doctrine.php to /Doctrine/Core.php, which mean that the Zend autoloader can now find it without special config/hack, just add Doctrine_ as a namespace and let ZF do the magic. This can be done in your application.ini with this single line

autoloaderNamespaces[] = "Doctrine_"

Second thing, which is the nice part, is that there is now a PEAR Style Model Loading and Generation, which means that the Doctrine cli can now generate models that can be autoloaded by ZF too. To generate your model from a yaml file (in ./doctrine/schema/schema.yaml`, you can run the doctrine-cli script like this

php ./scripts/doctrine-cli generate-models-yaml

and they will be generated in ./application/models. Note the generate_models_options array of options that define how the model classes will be named. Now, If you wish, you can move the models around to put them in a module by prefixing the classname with modulename_ as you would normally do. If you love spending more time in php land, you can build your model directly in php instead of the yaml file, just by extending the Doctrine_Record class. Check out the Doctrine Documentation, it’s really easy to do.

One thing to keep in mind, just as your web pages read the environment setting (APPLICATION_ENV) from ./public/.htaccess or ./public/index.php, the command line script for doctrine have to be set to use the expected environment too (3rd line of the script).

Once again, here’s the link to the working application that use Doctrine 1.2alpha3, Zend Framework 1.9.5 and ZFDebug 1.5

github.com/danceric/zfdebugdoctrine

Short ‘n Sweet Version

  • start a ZF project
  • add the doctrine namespace to your autoloader in your application.ini

    autoloaderNamespaces[] = "Doctrine_"
  • connect to a database in your boostrap as

    $manager = Doctrine_Manager::getInstance();
    $manager->openConnection('your-connection-dsn');
  • Create your models in the application/models folder by having class that extends Doctrine_Record

    class Model_Base_Post extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->setTableName('post');
            $this->hasColumn('id', 'integer', 4, array(
                 'primary' => true,
                 'autoincrement' => true,
                 'type' => 'integer',
                 'length' => '4',
            ));
            $this->hasColumn('content', 'string');
        }
     
        public function setUp()
        {
            parent::setUp();
            $timestampable0 = new Doctrine_Template_Timestampable();
            $this->actAs($timestampable0);
        }
    } 
27 comments so far, add yours