Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ghost-object.html

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 11.26 KiB


 001  <!DOCTYPE html>
 002  <html class="no-js" id="top">
 003  <head>
 004      <title>ProxyManager - Ghost object</title>
 005   
 006      <meta name="description" content="A proxyManager write in php" />
 007      <meta name="keywords" content="ProxyManager, proxy, manager, ocramius, Marco Pivetta, php, ghost object" />
 008      <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
 009      <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600' rel='stylesheet' type='text/css'>
 010      <link href="css/styles.css" rel="stylesheet" />
 011      <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/styles/default.min.css">
 012      <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/highlight.min.js"></script>
 013      <script>hljs.initHighlightingOnLoad();</script>
 014      <link rel="shortcut icon" href="favicon.ico">
 015  </head>
 016  <body>
 017   
 018  <header class="site-header">
 019  <div class="container">
 020  <h1><a href="index.html"><img alt="ProxyManager" src="img/block.png" /></a></h1>
 021   
 022  <nav class="main-nav" role="navigation">
 023  <ul>
 024      <li><a href="https://github.com/Ocramius/ProxyManager" target="_blank">Github</a>
 025      <div class="bcms-clearfix"></div>
 026  </li>
 027  </ul>
 028  </nav>
 029  </div>
 030  </header>
 031  <main role="main">
 032  <section class="component-content">
 033   
 034  <div class="component-demo" id="live-demo">
 035      <div class="container">
 036              <div class="main-wrapper" style="text-align: right">
 037                  <iframe src="http://ghbtns.com/github-btn.html?user=ocramius&amp;repo=ProxyManager&amp;type=fork&amp;count=true&amp;size=large"
 038    allowtransparency="true" frameborder="0" scrolling="0" width="310" height="40"></iframe>
 039   
 040                  <iframe src="http://ghbtns.com/github-btn.html?user=ocramius&amp;repo=ProxyManager&amp;type=watch&amp;count=true&amp;size=large"
 041    allowtransparency="true" frameborder="0" scrolling="0" width="200" height="40"></iframe>
 042   
 043              </div>
 044          <div class="bcms-clearfix bcms-clearfix"></div>
 045      </div>
 046  </div>
 047  <div class="component-info">
 048  <div class="container">
 049  <aside class="sidebar">
 050      <nav class="spy-nav">
 051          <ul>
 052              <li><a href="index.html">Intro</a></li>
 053              <li><a href="virtual-proxy.html">Virtual Proxy</a></li>
 054              <li><a href="null-object.html">Null Objects</a></li>
 055              <li><a href="ghost-object.html">Ghost Objects</a></li>
 056              <li><a href="remote-object.html">Remote Object</a></li>
 057              <li><a href="contributing.html">Contributing</a></li>
 058              <li><a href="credits.html">Credits</a></li>
 059              <li><a href="copyright.html">Copyright</a></li>
 060          </ul>
 061      </nav>
 062  <div class="bcms-clearfix bcms-clearfix"></div>
 063  <a class="btn btn-action btn-full download-component"
 064      href="download.html">Download</a>
 065      <div class="bcms-clearfix"></div>
 066  </aside>
 067   
 068  <div class="content">
 069      <div class="bcms-clearfix"></div>
 070      <h3 class="section-title">Lazy Loading Ghost Object Proxies</h3>
 071   
 072      <p>A lazy loading ghost object proxy is a ghost proxy that looks exactly like the real instance of the proxied subject, but which has all properties nulled before initialization.</p>
 073  <hr />
 074   
 075      <h3 class="section-title">Lazy loading with the Ghost Object</h3>
 076   
 077      <p>In pseudo-code, in userland, <a href="http://www.martinfowler.com/eaaCatalog/lazyLoad.html" target="_blank">lazy loading</a> in a ghost object looks like following:</p>
 078   
 079      <pre>
 080          <code class="php">
 081  class MyObjectProxy
 082  {
 083      private $initialized = false;
 084      private $name;
 085      private $surname;
 086   
 087      public function doFoo()
 088      {
 089          $this->init();
 090   
 091          // Perform doFoo routine using loaded variables
 092      }
 093   
 094      private function init()
 095      {
 096          if (! $this->initialized) {
 097              $data          = some_logic_that_loads_data();
 098   
 099              $this->name    = $data['name'];
 100              $this->surname = $data['surname'];
 101   
 102              $this->initialized = true;
 103          }
 104      }
 105  }
 106          </code>
 107      </pre>
 108   
 109      <p>Ghost objects work similarly to virtual proxies, but since they don't wrap around a "real" instance of the proxied subject, they are better suited for representing dataset rows.</p>
 110      
 111  <hr />
 112   
 113      <h3 class="section-title">When do I use a ghost object?</h3>
 114   
 115      <p>You usually need a ghost object in cases where following applies</p>
 116      
 117      <ul>
 118          <li>you are building a small data-mapper and want to lazily load data across associations in your object graph</li>
 119          <li>you want to initialize objects representing rows in a large dataset</li>
 120          <li>you want to compare instances of lazily initialized objects without the risk of comparing a proxy with a real subject</li>
 121          <li>you are aware of the internal state of the object and are confident in working with its internals via reflection or direct property access</li>
 122      </ul>  
 123   
 124  <hr />
 125   
 126      <h3 class="section-title">Usage examples</h3>
 127   
 128      <p><a href="https://github.com/Ocramius/ProxyManager" target="_blank">ProxyManager</a> provides a factory that creates lazy loading ghost objects. To use it, follow these steps:</p>
 129   
 130      <p>First of all, define your object's logic without taking care of lazy loading:</p>
 131      
 132      <pre>
 133          <code class="php">
 134  namespace MyApp;
 135   
 136  class Customer
 137  {
 138      private $name;
 139      private $surname;
 140   
 141      // just write your business logic or generally logic
 142      // don't worry about how complex this object will be!
 143      // don't code lazy-loading oriented optimizations in here!
 144      public function getName() { return $this->name; }
 145      public function setName($name) { $this->name = (string) $name; }
 146      public function getSurname() { return $this->surname; }
 147      public function setSurname($surname) { $this->surname = (string) $surname; }
 148  }
 149          </code>
 150      </pre>
 151   
 152      <p>Then use the proxy manager to create a ghost object of it. You will be responsible of setting its state during lazy loading:</p>
 153      
 154      <pre>
 155          <code class="php">
 156  namespace MyApp;
 157   
 158  use ProxyManager\Factory\LazyLoadingGhostFactory;
 159  use ProxyManager\Proxy\LazyLoadingInterface;
 160   
 161  require_once __DIR__ . '/vendor/autoload.php';
 162   
 163  $factory     = new LazyLoadingGhostFactory();
 164  $initializer = function (LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) {
 165      $initializer   = null; // disable initialization
 166   
 167      // load data and modify the object here
 168      $proxy->setName('Agent');
 169      $proxy->setSurname('Smith');
 170   
 171      return true; // confirm that initialization occurred correctly
 172  };
 173   
 174  $instance = $factory->createProxy('MyApp\Customer', $initializer);
 175          </code>
 176      </pre>
 177   
 178      <p>You can now simply use your object as before:</p>
 179   
 180      <pre>
 181          <code class="php">
 182  // this will just work as before
 183  echo $proxy->getName() . ' ' . $proxy->getSurname(); // Agent Smith
 184          </code>
 185      </pre>
 186  <hr />
 187   
 188      <h3 class="section-title">Lazy Initialization</h3>
 189   
 190      <p>As you can see, we use a closure to handle lazy initialization of the proxy instance at runtime. The initializer closure signature for ghost objects should be as following:</p>
 191   
 192      <pre>
 193          <code class="php">
 194  /**
 195   * @var object  $proxy         the instance the ghost object proxy that is being initialized
 196   * @var string  $method        the name of the method that triggered lazy initialization
 197   * @var array   $parameters    an ordered list of parameters passed to the method that
 198   *                             triggered initialization, indexed by parameter name
 199   * @var Closure $initializer   a reference to the property that is the initializer for the
 200   *                             proxy. Set it to null to disable further initialization
 201   *
 202   * @return bool true on success
 203   */
 204  $initializer = function ($proxy, $method, $parameters, &amp; $initializer) {};
 205          </code>
 206      </pre>
 207   
 208      <p>The initializer closure should usually be coded like following:</p>
 209   
 210      <pre>
 211          <code class="php">
 212  $initializer = function ($proxy, $method, $parameters, & $initializer) {
 213      $initializer = null; // disable initializer for this proxy instance
 214   
 215      // modify the object with loaded data
 216      $proxy->setFoo(/* ... */);
 217      $proxy->setBar(/* ... */);
 218   
 219      return true; // report success
 220  };
 221          </code>
 222      </pre>
 223   
 224      <p>The <code>ProxyManager\Factory\LazyLoadingGhostFactory</code> produces proxies that implement both the <code>ProxyManager\Proxy\GhostObjectInterface</code> and the <code>ProxyManager\Proxy\LazyLoadingInterface</code>.</p>
 225   
 226      <p>At any point in time, you can set a new initializer for the proxy:</p>
 227   
 228      <pre>
 229          <code class="php">
 230  $proxy->setProxyInitializer($initializer);
 231          </code>
 232      </pre>
 233   
 234      <p>In your initializer, you <strong>MUST</strong> turn off any further initialization:</p>
 235   
 236      <pre>
 237          <code class="php">
 238  $proxy->setProxyInitializer(null);
 239          </code>
 240      </pre>
 241   
 242      <p>or</p>
 243   
 244      <pre>
 245          <code class="php">
 246  $initializer = null; // if you use the initializer passed by reference to the closure
 247          </code>
 248      </pre>
 249  <hr />
 250   
 251      <h3 class="section-title">Triggering Initialization</h3>
 252   
 253      <p>A lazy loading ghost object is initialized whenever you access any property or method of it. Any of the following interactions would trigger lazy initialization:</p>
 254   
 255      <pre>
 256          <code class="php">
 257  // calling a method
 258  $proxy->someMethod();
 259   
 260  // reading a property
 261  echo $proxy->someProperty;
 262   
 263  // writing a property
 264  $proxy->someProperty = 'foo';
 265   
 266  // checking for existence of a property
 267  isset($proxy->someProperty);
 268   
 269  // removing a property
 270  unset($proxy->someProperty);
 271   
 272  // cloning the entire proxy
 273  clone $proxy;
 274   
 275  // serializing the proxy
 276  $unserialized = unserialize(serialize($proxy));
 277          </code>
 278      </pre>
 279   
 280      <p>Remember to call <code>$proxy->setProxyInitializer(null);</code> to disable initialization of your proxy, or it will happen more than once.</p>
 281   
 282  <hr />
 283      
 284      <h3 class="section-title">Proxying interfaces</h3>
 285      
 286      <p>You can also generate proxies from an interface FQCN. By proxying an interface, you will only be able to access the methods defined by the interface itself, even if the <code>wrappedObject</code> implements more methods. This will anyway save some memory since the proxy won't contain any properties.</p>
 287   
 288      <p>Tuning performance for production</p>
 289   
 290      <p>See <a href="production.html">Tuning ProxyManager for Production.</a></p>
 291   
 292  </main>
 293   
 294      <footer class="site-footer" role="contentinfo">
 295          <div class="container">
 296              <div class="footer-logos">
 297                  <ul>
 298                      <li><a href="index.html">Intro</a> | </li>
 299                      <li><a href="virtual-proxy.html">Virtual Proxy</a> | </li>
 300                      <li><a href="null-object.html">Null Objects</a> | </li>
 301                      <li><a href="ghost-object.html">Ghost Objects</a> | </li>
 302                      <li><a href="remote-object.html">Remote Object</a> | </li>
 303                      <li><a href="contributing.html">Contributing</a> | </li>
 304                      <li><a href="credits.html">Credits</a> | </li>
 305                      <li><a href="copyright.html">Copyright</a></li>
 306                  </ul>
 307              </div>
 308          </div>
 309   
 310          <div class="bcms-clearfix"></div>
 311      </footer>
 312      <div class="bcms-clearfix"></div>
 313      </body>
 314  </html>
 315