SlideShare ist ein Scribd-Unternehmen logo
1 von 57
Downloaden Sie, um offline zu lesen
BUILDING LITHIUM
 APPS LIKE A BOSS
Pace University, NYC · 10-19-2010
ARCHITECTURE
architecture
noun
! the complex or carefully designed structure of
! something
noun
! Orderly arrangement of parts; structure
noun
! the conceptual structure and logical organization of a computer
! or computer-based system
“ARCHITECTURE” IN PHP
“PROCEDURAL”
“OBJECT-ORIENTED”
Procedural   Object-Oriented
Procedural   Object-Oriented
Aspect-Oriented


Event-Driven                       Procedural

               PARADIGMS
Declarative                       Functional


                Object-Oriented
Aspect-Oriented


Event-Driven                     Procedural

               PARADIGMS
Declarative                      Functional


               Object-Oriented
Aspect-Oriented


 Event-Driven                     Procedural

                PARADIGMS
Declarative                       Functional


                Object-Oriented
Aspect-Oriented


Event-Driven                     Procedural

               PARADIGMS
 Declarative                     Functional


               Object-Oriented
BOOTSTRAP / DISPATCH
index.php?url=/posts




/posts
index.php?url=/posts

                  config/bootstrap.php

                       config/bootstrap/libraries.php

/posts                 config/bootstrap/cache.php

                       config/bootstrap/connections.php

                       config/bootstrap/action.php

                       ...
index.php?url=/posts

                  config/bootstrap.php

                       config/bootstrap/libraries.php

/posts                 config/bootstrap/cache.php

                       config/bootstrap/connections.php

                       config/bootstrap/action.php

                       ...

                  lithiumactionDispatcher::run(
                    new lithiumactionRequest()
                  )
config/bootstrap/cache.php



Cache::config(array(
    'local' => array(
        'adapter' => 'Apc'
    ),
    'distributed' => array(
        'adapter' => 'Memcached',
        'servers' => array(
            array('127.0.0.1', 11211, 100)
            array('127.0.0.2', 11211, 100)
        )
    )
));
config/bootstrap/connections.php

Connections::add('default', array(
    'development' => array(
        'type' => 'MongoDb',
        'host' => 'localhost',
        'database' => 'foo'
    ),
    'production' => array(
        'type' => 'MongoDb',
        'host' => 'db.host',
        'database' => 'foo.prod'
    )
));

Connections::add('cassandra', array(
    'type' => 'Cassandra',
    'keyspace' => 'foo'
));
STATICS & STATE
new lithiumactionRequest()


    $_GET   $_POST $_SERVER
CONFIGURATION


   REQUEST
FILTERS
A.K.A. ASPECT-ORIENTED
    PROGRAMMING
There are no routes here yet

lithiumactionDispatcher {
    //...

    public static function run($request, ...) {
        // Pass the request to the Router
        $params = $classes['router']::process($request);


        // Do some checking...

        // Get a controller...
        return static::call($controller);
    }
}
config/bootstrap/action.php



Dispatcher::applyFilter('run', function($self, $params, $chain) {

      foreach (Libraries::get() as $name => $config) {
          // Some sanity checking goes here...
          include "{$config['path']}/config/routes.php";
      }
      return $chain->next($self, $params, $chain);
});
lithiumactionDispatcher {
          //...

          public static function run($request, ...) {
              // Pass the request to the Router
               $params = $classes['router']::process($request);

               // Do some checking...

               // Get a controller...
               // $controller = ...
               return static::call($controller);
          }
      }




Dispatcher::applyFilter('run', function($self, $params, $chain) {

      foreach (Libraries::get() as $name => $config) {
          // Some sanity checking goes here...
          include "{$config['path']}/config/routes.php";
      }
      return $chain->next($self, $params, $chain);
});
CONTROLLERS
use appmodelsPosts;

appcontrollersPostsController {

    public function index() {
        $posts = Posts::all();
        return compact('posts');
    }
}
class WeblogController < ActionController::Base

  def index
    @posts = Post.find :all

    respond_to do |format|
      format.html
      format.xml { render :xml => @posts.to_xml }
      format.rss { render :action => "feed.rxml" }
    end
  end
end
class WeblogController < ActionController::Base

  def index
    @posts = Post.find :all

    respond_to do |format|
      format.html
      format.xml { render :xml => @posts.to_xml }
      format.rss { render :action => "feed.rxml" }
    end
  end
end
lithiumnethttpMedia {

                   $formats = array(
array(                 'html' => array(...),
  'posts' => ...       'json' => array(...),
)                      'xml' => array(...),
                       '...'
                   );
             }
new lithiumactionResponse()
Dispatcher   index.php


         Controller


new lithiumactionResponse()


          View
REQUEST / RESPONSE
Router::connect('/photos/{:id:[0-9a-f]{24}}.jpg', array(), function($request) {
    return new Response(array(
        'type' => 'jpg',
        'body' => Photo::first($request->id)->file->getBytes()
    ));
});
/**
 * This handles both the home page and the archives pages.
 */
Router::connect('/{:page}', array('page' => 1), array(
      'pattern' => '@^/?(?P<page>d+)$|^/?$@',
      'keys' => array('page' => true),
      'handler' => function($request) use ($render) {
            $page = intval($request->page);
            $posts = Posts::recent(compact('page'));


            return new Response(array(
                  'body' => $render('index', compact('posts'), compact('request'))
            ));
      })
);


/**
 * Handles adding new posts.
 */
Router::connect('/add', array(), function($request) use ($render) {
      $post = Posts::create();


      if (($request->data) && $post->save($request->data)) {
            return new Response(array('location' => '/'));
      }
      return new Response(array(
            'body' => $render('edit', compact('post'), compact('request'))
      ));
});


/**
 * Edits existing pages.
 */
Router::connect('/{:slug:[a-z0-9-]+}/edit', array('edit' => true), function($request) use ($render) {
      $conditions = array('slug' => $request->slug);
      $post = Posts::first(compact('conditions'));


      if (($request->data) && $post->save($request->data)) {
            return new Response(compact('request') + array('location' => array('slug' => $post->slug)));
      }
      return new Response(array(
            'body' => $render('edit', compact('post'), compact('request'))
      ));
});


/**
 * Handles single page views.
 */
Router::connect('/{:slug:[a-z0-9-]+}', array(), function($request) use ($render) {
      $conditions = array('slug' => $request->slug, 'published' => true);
      $post = Posts::first(compact('conditions'));


      return new Response(array(
            'status' => $post ? 200 : 404,
            'body' => $render($post ? 'view' : 'error', compact('post'), compact('request'))
      ));
});
WAX ON,
WAX OFF
DEPENDENCIES
class User {

    public function somethingUseful() {
        Logger::info("Something useful is happening");
        // ...
    }
}
FALE
class User {

    public function somethingUseful() {
        Logger::info("Something useful is happening");
        // ...
    }           b!!
}     Super dum
COUPLING   RELEVANCE
Post::applyFilter('save', function($self, $params, $chain) {
    $entity =& $params['entity'];

      if (!$entity->exists()) {
          $entity->created = time();
      }
      return $chain->next($self, $params, $chain);
});
FALE
Post::applyFilter('save', function($self, $params, $chain) {
    $entity =& $params['entity'];

      if (!$entity->exists()) {
          $entity->created = time();
      }
      return $chain->next($self, $params, $chain);
});
class WebService {

    protected $_classes = array(
        'socket' => 'lithiumnethttpsocketContext',
        'request' => 'lithiumnethttpRequest',
        'response' => 'lithiumnethttpResponse'
    );
}
use appmodelsPost;
use li3_elasticsearchextensionsdatabehaviorSearchable;

Post::applyFilter('save', function($self, $params, $chain) {
    $entity =& $params['entity'];
    $id = $entity->guid;
    Searchable::add('public_posts', 'stream', $id, $entity->to('array'));
    return $chain->next($self, $params, $chain);
});
REUSABILITY
config/bootstrap/libraries.php

                                                                               Make conditional
define('LITHIUM_APP_PATH', dirname(dirname(__DIR__)));
define('LITHIUM_LIBRARY_PATH', LITHIUM_APP_PATH . '/../libraries');




require   LITHIUM_LIBRARY_PATH   .   '/lithium/core/Object.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/core/StaticObject.php';

                                                                               Remove when
require   LITHIUM_LIBRARY_PATH   .   '/lithium/util/Collection.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/util/collection/Filters.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/util/Inflector.php';
require
require
          LITHIUM_LIBRARY_PATH
          LITHIUM_LIBRARY_PATH
                                 .
                                 .
                                     '/lithium/util/String.php';
                                     '/lithium/core/Adaptable.php';
                                                                                plugin-izing
require   LITHIUM_LIBRARY_PATH   .   '/lithium/core/Environment.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/net/Message.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/net/http/Message.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/net/http/Media.php';
require   LITHIUM_LIBRARY_PATH   .   '/lithium/net/http/Request.php';
require   ....
Libraries::add('my_application', array(
  'default' => true
));
my_awesome_plugin/
          config/
                 bootstrap.php                   Required
                 routes.php                  Optional
          anything_in_an_app/

                   Happens in the filter
                  we saw in action.php
                                             Unless you
Libraries::add('my_awesome_plugin', array(
    'bootstrap' => false                      disable it
));
DEMO...

Weitere ähnliche Inhalte

Was ist angesagt?

Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
Fabien Potencier
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Fabien Potencier
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
Fabien Potencier
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
Bill Chang
 

Was ist angesagt? (20)

Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Advanced Querying with CakePHP 3
Advanced Querying with CakePHP 3Advanced Querying with CakePHP 3
Advanced Querying with CakePHP 3
 
New in cakephp3
New in cakephp3New in cakephp3
New in cakephp3
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Future of HTTP in CakePHP
Future of HTTP in CakePHPFuture of HTTP in CakePHP
Future of HTTP in CakePHP
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
 
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
 

Ähnlich wie Building Lithium Apps

Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
Hari K T
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
Ben Lin
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
elliando dias
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
Yehuda Katz
 

Ähnlich wie Building Lithium Apps (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Aura Project for PHP
Aura Project for PHPAura Project for PHP
Aura Project for PHP
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Talkaboutlithium
TalkaboutlithiumTalkaboutlithium
Talkaboutlithium
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Nashvile Symfony Routes Presentation
Nashvile Symfony Routes PresentationNashvile Symfony Routes Presentation
Nashvile Symfony Routes Presentation
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Kürzlich hochgeladen (20)

Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 

Building Lithium Apps

  • 1. BUILDING LITHIUM APPS LIKE A BOSS Pace University, NYC · 10-19-2010
  • 3.
  • 5. noun ! the complex or carefully designed structure of ! something
  • 6. noun ! Orderly arrangement of parts; structure
  • 7. noun ! the conceptual structure and logical organization of a computer ! or computer-based system
  • 9.
  • 12. Procedural Object-Oriented
  • 13. Procedural Object-Oriented
  • 14. Aspect-Oriented Event-Driven Procedural PARADIGMS Declarative Functional Object-Oriented
  • 15. Aspect-Oriented Event-Driven Procedural PARADIGMS Declarative Functional Object-Oriented
  • 16. Aspect-Oriented Event-Driven Procedural PARADIGMS Declarative Functional Object-Oriented
  • 17. Aspect-Oriented Event-Driven Procedural PARADIGMS Declarative Functional Object-Oriented
  • 20. index.php?url=/posts config/bootstrap.php config/bootstrap/libraries.php /posts config/bootstrap/cache.php config/bootstrap/connections.php config/bootstrap/action.php ...
  • 21. index.php?url=/posts config/bootstrap.php config/bootstrap/libraries.php /posts config/bootstrap/cache.php config/bootstrap/connections.php config/bootstrap/action.php ... lithiumactionDispatcher::run( new lithiumactionRequest() )
  • 22. config/bootstrap/cache.php Cache::config(array( 'local' => array( 'adapter' => 'Apc' ), 'distributed' => array( 'adapter' => 'Memcached', 'servers' => array( array('127.0.0.1', 11211, 100) array('127.0.0.2', 11211, 100) ) ) ));
  • 23. config/bootstrap/connections.php Connections::add('default', array( 'development' => array( 'type' => 'MongoDb', 'host' => 'localhost', 'database' => 'foo' ), 'production' => array( 'type' => 'MongoDb', 'host' => 'db.host', 'database' => 'foo.prod' ) )); Connections::add('cassandra', array( 'type' => 'Cassandra', 'keyspace' => 'foo' ));
  • 25. new lithiumactionRequest() $_GET $_POST $_SERVER
  • 26. CONFIGURATION REQUEST
  • 28. A.K.A. ASPECT-ORIENTED PROGRAMMING
  • 29. There are no routes here yet lithiumactionDispatcher { //... public static function run($request, ...) { // Pass the request to the Router $params = $classes['router']::process($request); // Do some checking... // Get a controller... return static::call($controller); } }
  • 30. config/bootstrap/action.php Dispatcher::applyFilter('run', function($self, $params, $chain) { foreach (Libraries::get() as $name => $config) { // Some sanity checking goes here... include "{$config['path']}/config/routes.php"; } return $chain->next($self, $params, $chain); });
  • 31. lithiumactionDispatcher { //... public static function run($request, ...) { // Pass the request to the Router $params = $classes['router']::process($request); // Do some checking... // Get a controller... // $controller = ... return static::call($controller); } } Dispatcher::applyFilter('run', function($self, $params, $chain) { foreach (Libraries::get() as $name => $config) { // Some sanity checking goes here... include "{$config['path']}/config/routes.php"; } return $chain->next($self, $params, $chain); });
  • 33. use appmodelsPosts; appcontrollersPostsController { public function index() { $posts = Posts::all(); return compact('posts'); } }
  • 34. class WeblogController < ActionController::Base def index @posts = Post.find :all respond_to do |format| format.html format.xml { render :xml => @posts.to_xml } format.rss { render :action => "feed.rxml" } end end end
  • 35. class WeblogController < ActionController::Base def index @posts = Post.find :all respond_to do |format| format.html format.xml { render :xml => @posts.to_xml } format.rss { render :action => "feed.rxml" } end end end
  • 36. lithiumnethttpMedia { $formats = array( array( 'html' => array(...), 'posts' => ... 'json' => array(...), ) 'xml' => array(...), '...' ); }
  • 38. Dispatcher index.php Controller new lithiumactionResponse() View
  • 40. Router::connect('/photos/{:id:[0-9a-f]{24}}.jpg', array(), function($request) { return new Response(array( 'type' => 'jpg', 'body' => Photo::first($request->id)->file->getBytes() )); });
  • 41. /** * This handles both the home page and the archives pages. */ Router::connect('/{:page}', array('page' => 1), array( 'pattern' => '@^/?(?P<page>d+)$|^/?$@', 'keys' => array('page' => true), 'handler' => function($request) use ($render) { $page = intval($request->page); $posts = Posts::recent(compact('page')); return new Response(array( 'body' => $render('index', compact('posts'), compact('request')) )); }) ); /** * Handles adding new posts. */ Router::connect('/add', array(), function($request) use ($render) { $post = Posts::create(); if (($request->data) && $post->save($request->data)) { return new Response(array('location' => '/')); } return new Response(array( 'body' => $render('edit', compact('post'), compact('request')) )); }); /** * Edits existing pages. */ Router::connect('/{:slug:[a-z0-9-]+}/edit', array('edit' => true), function($request) use ($render) { $conditions = array('slug' => $request->slug); $post = Posts::first(compact('conditions')); if (($request->data) && $post->save($request->data)) { return new Response(compact('request') + array('location' => array('slug' => $post->slug))); } return new Response(array( 'body' => $render('edit', compact('post'), compact('request')) )); }); /** * Handles single page views. */ Router::connect('/{:slug:[a-z0-9-]+}', array(), function($request) use ($render) { $conditions = array('slug' => $request->slug, 'published' => true); $post = Posts::first(compact('conditions')); return new Response(array( 'status' => $post ? 200 : 404, 'body' => $render($post ? 'view' : 'error', compact('post'), compact('request')) )); });
  • 43.
  • 44.
  • 46. class User { public function somethingUseful() { Logger::info("Something useful is happening"); // ... } }
  • 47. FALE class User { public function somethingUseful() { Logger::info("Something useful is happening"); // ... } b!! } Super dum
  • 48. COUPLING RELEVANCE
  • 49. Post::applyFilter('save', function($self, $params, $chain) { $entity =& $params['entity']; if (!$entity->exists()) { $entity->created = time(); } return $chain->next($self, $params, $chain); });
  • 50. FALE Post::applyFilter('save', function($self, $params, $chain) { $entity =& $params['entity']; if (!$entity->exists()) { $entity->created = time(); } return $chain->next($self, $params, $chain); });
  • 51. class WebService { protected $_classes = array( 'socket' => 'lithiumnethttpsocketContext', 'request' => 'lithiumnethttpRequest', 'response' => 'lithiumnethttpResponse' ); }
  • 52. use appmodelsPost; use li3_elasticsearchextensionsdatabehaviorSearchable; Post::applyFilter('save', function($self, $params, $chain) { $entity =& $params['entity']; $id = $entity->guid; Searchable::add('public_posts', 'stream', $id, $entity->to('array')); return $chain->next($self, $params, $chain); });
  • 54. config/bootstrap/libraries.php Make conditional define('LITHIUM_APP_PATH', dirname(dirname(__DIR__))); define('LITHIUM_LIBRARY_PATH', LITHIUM_APP_PATH . '/../libraries'); require LITHIUM_LIBRARY_PATH . '/lithium/core/Object.php'; require LITHIUM_LIBRARY_PATH . '/lithium/core/StaticObject.php'; Remove when require LITHIUM_LIBRARY_PATH . '/lithium/util/Collection.php'; require LITHIUM_LIBRARY_PATH . '/lithium/util/collection/Filters.php'; require LITHIUM_LIBRARY_PATH . '/lithium/util/Inflector.php'; require require LITHIUM_LIBRARY_PATH LITHIUM_LIBRARY_PATH . . '/lithium/util/String.php'; '/lithium/core/Adaptable.php'; plugin-izing require LITHIUM_LIBRARY_PATH . '/lithium/core/Environment.php'; require LITHIUM_LIBRARY_PATH . '/lithium/net/Message.php'; require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Message.php'; require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Media.php'; require LITHIUM_LIBRARY_PATH . '/lithium/net/http/Request.php'; require ....
  • 56. my_awesome_plugin/ config/ bootstrap.php Required routes.php Optional anything_in_an_app/ Happens in the filter we saw in action.php Unless you Libraries::add('my_awesome_plugin', array( 'bootstrap' => false disable it ));