You are not logged in.

Dear visitor, welcome to WoltLab Bugtracker. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

  • Alexander Ebert

    WoltLab Developer

    You have to register first, to connect to this user.

31

Decorator objects in Community Framework 2.0

Rating:

by Alexander Ebert, Friday, February 17th 2012, 11:42pm

This article is primarly intended for developers, describing some techniques behind a new feature of our upcoming version of Community Framework.

Starting with Community Framework 2.0 we will provide a clear and consistent API to access all database tables, this includes editors, listings and even centralized actions, furthermore we implemented decorators to add specific data on the fly without polluting the original object.

The next step was to increase the abstraction on each object to massively reduce redundant code found in almost every DatabaseObject derivations and editor classes - using late static binding we can gather all necessary data at runtime.

Decorators encapsule the original object and extend it with additional data and methods for accessing those without polluting the object and making it reusable everywhere. Okay, I have to admit this might not be that clear and it sounds like rocket science, but it is not! Please bear in mind that the editor classes are actually decorators, even though they’re not explicitly called this way.

Imagine you have a thread with 20 posts within and you want to track how often each post is displayed. With WCF 1.1 you would have to create a PostEditor object for each post individually (causing 20 additional SQL queries!) or by writing a manual query which updates all posts at once. On the one hand you gain poor performance (but can work with a nice object) or feel the pain of writing plain SQL queries for something the framework should handle on itself. Doesn’t sound smart? You’re right and that’s the reason we implemented decorators.

Let’s go one step back and think of what is already provided: We have a thread object and a post list which holds an object for each post. Each time you create a new instance of PostEditor you fire up a query which fetches all this stuff you already have, that’s weird. With WCF 2.0 you can simply take each Post object and wrap it within a PostEditor object enabling you to edit the object without querying anything.

PHP Source code

1
2
3
4
foreach ($posts as $post) {
    $postEditor = new PostEditor($post);
    $postEditor->update(array('views' => $postEditor->views 1));
}


This looks clearly better, but you might wonder how the PostEditor knows which post he should edit – remember we’ve never told him. Sure, we could write a few lines of code which directly fetches the ID using something among $post->postID, but this would force a developer to write additional code. Instead we just implemented a few methods on the DatabaseObject which tells anyone how it’s database table is called, what’s his primary index name (e.g. postID).

Now take a look at the (working!) implementation of EventListenerEditor and you will realize that you will waste most of your time writing comments ;)

PHP Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
namespace wcf\data\event\listener;
use wcf\data\DatabaseObjectEditor;

/**
 * (stripped the comment)
 */
class EventListenerEditor extends DatabaseObjectEditor {
    /**
     * @see    wcf\data\DatabaseObjectDecorator::$baseClass
     */
    protected static $baseClass 'wcf\data\event\listener\EventListener';
}


This works because we already told the DatabaseObject everything we need to know about our table. Sounds like you have to write tons of code for the original object? You’re wrong again, take a look at the EventListener class:

PHP Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
namespace wcf\data\event\listener;
use wcf\data\DatabaseObject;

/**
 * (stripped the comment)
 */
class EventListener extends DatabaseObject {
    /**
     * @see    wcf\data\DatabaseObject::$databaseTableName
     */
    protected static $databaseTableName 'event_listener';

    /**
     * @see    wcf\data\DatabaseObject::$databaseTableIndexName
     */
    protected static $databaseTableIndexName 'listenerID';
}

This article has been read 3,095 times.

Categories: Community Framework, Entwicklung


Comments (3)

  • 3

    by helga (Wednesday, February 29th 2012, 2:24pm)

    schön wenn du englische Inhalte für deutsche Sprache hier postest. Harald hat seine Inhalte für englische Sprache gepostet, sodass diese für "nur" deutsche nicht sichtbar sind.
    Vieleicht gibt es diese Infos ja auch mal auf deutsch hier im Blog.

  • 2

    by TimWolla (Saturday, February 18th 2012, 11:53am)

    “create a PostEditor object for each post individually (causing 20 additional SQL queries!)”???

    You can create a PostEditor-Object from a database row like any database object else.

  • 1

    by Hawkes (Saturday, February 18th 2012, 9:49am)

    Am I wrong, or does your foreach loop still trigger 20 SQL queries after all?

Blog navigation

Next article

Object actions in Community Framework 2.0

by Alexander Ebert (Saturday, February 18th 2012, 3:44pm)

Previous article

Plugin-Entwicklung: Abhängigkeiten richtig setzen

by Alexander Ebert (Tuesday, April 5th 2011, 2:52pm)