Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BEAR.Sunday (2017)

BEAR.Sunday (2017)

A resource orientated framework using the DI /AOP/REST Triangle

Akihito Koriyama

October 17, 2016
Tweet

More Decks by Akihito Koriyama

Other Decks in Technology

Transcript

  1. DIP • Code should depend on things that are at

    the same or higher level of abstraction • High level policy should not depend on low level details
  2. “The principle of dependency inversion is at the root of

    many of the benefits claimed for object- oriented technology. Its proper application is necessary for the creation of reusable frameworks”
  3. /** * @Inject */ public function setRenderer(RenderInterface $renderer) { ...

    1.annotate at injection point class RendererModule extends AbstractModule { protected function configure() { $this->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON); } $injector = new Injector(new RendererModule); 2 bind abstraction to concretion 3.create an injector
  4. /** * @Inject */ public function setRenderer(RenderInterface $renderer) { ...

    1.annotate at injection point class RendererModule extends AbstractModule { protected function configure() { $this->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON); } $injector = new Injector(new RendererModule); 2. bind abstraction to concretion 3.create an injector
  5. $injector = new Injector(new HalRendererModule); /** * @Inject */ public

    function setRenderer(RenderInterface $renderer) { ... 1.annotate at injection point class RendererModule extends AbstractModule { protected function configure() { $this->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON); } 2 bind abstraction to concretion 3.create an injector
  6. class RendererModule extends AbstractModule { protected function configure() { $this

    ->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON); } } Use concrete class only in compile
  7. DI Best practice “Your code should deal directly with the

    Injector as little as possible. Instead, you want to bootstrap your application by injecting one root object.”
  8. You get a application object graph. huge, but can be

    stored one single root value $app
  9. $app Object i/f i/f Object i/f i/f Object Router Response

    JSON XM L 1st framework: DI Framework • DI framework w/ binding DSL • compile / runtime separation • use only “socket” in runtime • application is single big one value • implement structure, not behavior
  10. What is AOP? Cache Log Auth A programming paradigm that

    aims to increase modularity by allowing the separation of cross-cutting concerns
  11. /** * @Cacheable */
 class Post { public function onGet($id)

    { // ... $this->body = $stmt->fetchAll(PDO::FETCH_ASSOC); return $this; } class Post extends AppModel { public function newest() { $result = Cache::read('newest_posts', 'longterm'); if (!$result) { $result = $this->find('all'); Cache::write('newest_posts', $result, 'longterm'); } return $result; } }
  12. M C Cache Cache is called by method invocation,
 If

    the cache is warm the model is never called. $obj->read(2); Miss !
  13. class Transactional implements MethodInterceptor { public function invoke(MethodInvocation $invocation) {

    $object = $invocation->getThis(); $ref = new ReflectionProperty($object, 'db'); $ref->setAccessible(true); $db = $ref->getValue($object); $db->beginTransaction(); try { $invocation->proceed(); $db->commit(); } catch (Exception $e) { $db->rollback(); } } } Transactional interceptor Core Concern Cross Cutting Concern
  14. class CacheInterceptor implements MethodInterceptor { public function invoke(MethodInvocation $invocation) {

    $obj = $invocation->getThis(); $args = $invocation->getArguments(); $id = get_class($obj) . serialize($args); $saved = $this->cache->fetch($id); if ($saved) { return $saved; } $result = $invocation->proceed(); $this->cache->save($id, $result); return $result; } } Core Concern Cross Cutting Concern Cache interceptor
  15. <?php class SandboxResourcePageIndexRay0000000071f9ab280000000033fb446fAop extends Sandbox\Resource\Page\Index implements Ray\Aop\WeavedInterface { private $rayAopIntercept

    = true; public $rayAopBind; public function onGet() { // native call if (!isset($this->rayAopBind[__FUNCTION__])) { return call_user_func_array('parent::' . __FUNCTION__, func_get_args()); } // proceed source method from interceptor if (!$this->rayAopIntercept) { $this->rayAopIntercept = true; return call_user_func_array('parent::' . __FUNCTION__, func_get_args()); } // proceed next interceptor $this->rayAopIntercept = false; $interceptors = $this->rayAopBind[__FUNCTION__]; $annotation = isset($this->rayAopBind->annotation[__FUNCTION__]) ? $this->rayAopBind >annotation[__FUNCTION__] : null; $invocation = new \Ray\Aop\ReflectiveMethodInvocation(array($this, __FUNCTION__), func_get_args(), $interceptors, $annotation); return $invocation->proceed(); } Under the hood: Method interception sub class is created in order enable this interception and keep type safety.
  16. 2nd framework: Aspect Oriented Framework • AOP alliance standard •

    Layering by context • Type safe • Runtime injection
  17. Hypermedia framework for object as a service It allows objects

    to have RESTful web service benefits such as client-server, uniform interface, statelessness, resource expression with mutual connectivity and layered components.
  18. • API is hub • API is core value API

    driven development DB Mobil e Web API Cloud Moc k URI API API
  19. 2. Application script ᶃ create root object with context ᶄ

    304 ? ᶅ create request ᶆ invoke request ᶇ transfer
  20. Performance • annotation ? dependency injection ? 
 method interception

    ? DSL ? named parameter ? • Fast • cache all compiled object • generate raw factory code • http friendly architecture
  21. Scale • “model proxy” pattern • ‘app://self/blog/entry’ can be anything.

    • contextual injection makes db scale easy • assisted injection
  22. Hard spot / Soft spot • DI configure hard spot.

    QFSTZTUFN • Aop configure softspot, change on request

  23. Connecting frameworks • DI - object as dependency • AOP

    - domain logic to application logic • Hypermedia - resource to resource
  24. AOP (Gregor Kiczales) DI (Martin Fowler) REST (Roy Fielding) OOP

    (Allan Kay) Annotation (Anders Hejlsberg) Guice (Bob Lee)