Zend_Tool_Framework-Architecture.xml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.tool.framework.architecture">
  5. <title>Architektur</title>
  6. <sect2 id="zend.tool.framework.architecture.registry">
  7. <title>Registry</title>
  8. <para>
  9. Weil Provider und Manifeste von überall im <property>include_path</property> kommen
  10. können, wird eine Registry angeboten um den Zugriff auf die verschiedenen Teile der
  11. Toolchain zu vereinfachen. Diese Registry wird in Komponenten eingefügt die
  12. registry-aware sind, und damit Abhängigkeiten entfernen können, wenn das notwendig ist.
  13. Die meisten Abhängigkeiten die in der Registry registriert werden sind
  14. Unter-Komponenten spezifische Repositories.
  15. </para>
  16. <para>
  17. Das Interface für die Registry besteht aus der folgenden Definition:
  18. </para>
  19. <programlisting language="php"><![CDATA[
  20. interface Zend_Tool_Framework_Registry_Interface
  21. {
  22. public function setClient(Zend_Tool_Framework_Client_Abstract $client);
  23. public function getClient();
  24. public function setLoader(Zend_Tool_Framework_Loader_Abstract $loader);
  25. public function getLoader();
  26. public function setActionRepository(
  27. Zend_Tool_Framework_Action_Repository $actionRepository
  28. );
  29. public function getActionRepository();
  30. public function setProviderRepository(
  31. Zend_Tool_Framework_Provider_Repository $providerRepository
  32. );
  33. public function getProviderRepository();
  34. public function setManifestRepository(
  35. Zend_Tool_Framework_Manifest_Repository $manifestRepository
  36. );
  37. public function getManifestRepository();
  38. public function setRequest(Zend_Tool_Framework_Client_Request $request);
  39. public function getRequest();
  40. public function setResponse(Zend_Tool_Framework_Client_Response $response);
  41. public function getResponse();
  42. }
  43. ]]></programlisting>
  44. <para>
  45. Die verschiedenen Objekte welche die Registry managt werden in deren betreffenden
  46. Kapiteln besprochen.
  47. </para>
  48. <para>
  49. Klassen welche Registry-aware sind sollten
  50. <classname>Zend_Tool_Framework_Registry_EnabledInterface</classname> implementieren.
  51. Dieses Interface erlaubt hauptsächlich die Initialisierung der Registry in der
  52. Zielklasse.
  53. </para>
  54. <programlisting language="php"><![CDATA[
  55. interface Zend_Tool_Framework_Registry_EnabledInterface
  56. {
  57. public function setRegistry(
  58. Zend_Tool_Framework_Registry_Interface $registry
  59. );
  60. }
  61. ]]></programlisting>
  62. </sect2>
  63. <sect2 id="zend.tool.framework.architecture.providers">
  64. <title>Provider</title>
  65. <para>
  66. <classname>Zend_Tool_Framework_Provider</classname> repräsentiert den funktionalen oder
  67. "möglichen" Aspekt des Frameworks. Grundsätzlich bietet
  68. <classname>Zend_Tool_Framework_Provider</classname> das Interface um "Provider" zu
  69. erstellen, oder Teile für Werkzeug-Funktionalität die aufgerufen werden können und in
  70. der <classname>Zend_Tool_Framework</classname> Toolchain verwendet werden. Die einfache
  71. Natur der Implementation dieses Provider Interfaces erlaubt es dem Entwickler ein
  72. "One-Stop-Shop" für das Hinzufügen von Funktionalitäten oder Möglichkeiten zu
  73. <classname>Zend_Tool_Framework</classname>.
  74. </para>
  75. <para>
  76. Das Provider Interface ist ein leeres Interface und erzwingt keine Methoden
  77. (das ist das Marker Interface Pattern):
  78. </para>
  79. <programlisting language="php"><![CDATA[
  80. interface Zend_Tool_Framework_Provider_Interface
  81. {}
  82. ]]></programlisting>
  83. <para>
  84. Oder, wenn man das will, kann man den Basis (oder Abstrakten) Provider implementieren,
  85. welcher einem Zugriff auf <classname>Zend_Tool_Framework_Registry</classname> bietet:
  86. </para>
  87. <programlisting language="php"><![CDATA[
  88. abstract class Zend_Tool_Framework_Provider_Abstract
  89. implements Zend_Tool_Framework_Provider_Interface,
  90. Zend_Tool_Registry_EnabledInterface
  91. {
  92. protected $_registry;
  93. public function setRegistry(
  94. Zend_Tool_Framework_Registry_Interface $registry
  95. );
  96. }
  97. ]]></programlisting>
  98. </sect2>
  99. <sect2 id="zend.tool.framework.architecture.loaders">
  100. <title>Loader</title>
  101. <para>
  102. Der Zweck eines Loaders ist es Provider und Manifest Datei zu finden die Klassen
  103. enthalten welche entweder <classname>Zend_Tool_Framework_Provider_Interface</classname>
  104. oder <classname>Zend_Tool_Framework_Manifest_Interface</classname> implementieren.
  105. Sobald diese Dateien vom Loader gefunden wurden, werden die Provider in das Provider
  106. Repository geladen und die Manifest Metadaten in das Manifest Repository.
  107. </para>
  108. <para>
  109. Um einen Loader zu implementieren muß man die folgende abstrakte Klasse erweitern:
  110. </para>
  111. <programlisting language="php"><![CDATA[
  112. abstract class Zend_Tool_Framework_Loader_Abstract
  113. {
  114. abstract protected function _getFiles();
  115. public function load()
  116. {
  117. /** ... */
  118. }
  119. }
  120. ]]></programlisting>
  121. <para>
  122. Die <methodname>_getFiles()</methodname> Methode sollte ein Array von Dateien
  123. zurückgeben (absolute Pfade). Der mit Zend Framework ausgelieferte Loader wird
  124. IncludePath Loader genannt. Standardmäßig verwendet das Tooling Framework einen Loader
  125. der auf dem Include Pfad basiert um Dateien zu finden die Provider oder Manifest
  126. Metadaten Objekte enthalten können.
  127. <classname>Zend_Tool_Framework_Loader_IncludePathLoader</classname> sucht, ohne
  128. irgendeine Option, nach Dateien im Include Pfad die mit
  129. <filename>Mainfest.php</filename>, <filename>Tool.php</filename> oder
  130. <filename>Provider.php</filename> enden. Sobald Sie gefunden wurden, werden Sie (durch
  131. die <methodname>load()</methodname> Methode von
  132. <classname>Zend_Tool_Framework_Loader_Abstract</classname>) getestet um zu erkennen ob
  133. Sie irgendeines der unterstützten Interfaces implementieren. Wenn Sie das tun, wird
  134. eine Instanz der gefundenen Klasse instanziiert, und dann dem richtigen Repository
  135. angehängt.
  136. </para>
  137. <programlisting language="php"><![CDATA[
  138. class Zend_Tool_Framework_Loader_IncludePathLoader
  139. extends Zend_Tool_Framework_Loader_Abstract
  140. {
  141. protected $_filterDenyDirectoryPattern = '.*(/|\\\\).svn';
  142. protected $_filterAcceptFilePattern = '.*(?:Manifest|Provider)\.php$';
  143. protected function _getFiles()
  144. {
  145. /** ... */
  146. }
  147. }
  148. ]]></programlisting>
  149. <para>
  150. Wie man sieht, durchsucht der IncludePath Loader alle include_paths nach den Dateien
  151. die <varname>$_filterAcceptFilePattern</varname> entsprechen und
  152. <varname>$_filterDenyDirectoryPattern</varname> <emphasis>nicht</emphasis> entsprechen.
  153. </para>
  154. </sect2>
  155. <sect2 id="zend.tool.framework.architecture.manifests">
  156. <title>Manifests</title>
  157. <para>
  158. Kurz gesagt, sollte ein Manifest spezielle oder eigene Metadaten enthalten, die für
  159. jeden Provider oder Client nützlich sind, sowie dafür verantwortlich sein alle
  160. zusätzlichen Provider in das Provider Repository zu laden.
  161. </para>
  162. <para>
  163. Um Metadaten in ein Manifest Repository einzuführen, müssen alle das leere
  164. <classname>Zend_Tool_Framework_Manifest_Interface</classname> implementieren, und eine
  165. <methodname>getMetadata()</methodname> Methode anbieten die ein Array von Objekten
  166. zurückgeben sollte, welches
  167. <classname>Zend_Tool_Framework_Manifest_Metadata</classname> implementiert.
  168. </para>
  169. <programlisting language="php"><![CDATA[
  170. interface Zend_Tool_Framework_Manifest_Interface
  171. {
  172. public function getMetadata();
  173. }
  174. ]]></programlisting>
  175. <para>
  176. Metadaten Objekte werden in das Manifest Repository
  177. (<classname>Zend_Tool_Framework_Manifest_Repository</classname>) geladen (durch einen
  178. wie unten definierten Loader). Manifeste werden ausgeführt nachdem alle Provider
  179. gefunden und in das Provider Repository geladen wurden. Das sollte es Manifeste
  180. erlauben Metadaten Objekte, basierend auf dem was aktuell im Provider Repository ist,
  181. zu erstellen.
  182. </para>
  183. <para>
  184. Es gibt ein paar andere Metadaten Klassen die dazu verwendet werden können um Metadaten
  185. zu beschreiben. <classname>Zend_Tool_Framework_Manifest_Metadata</classname> ist das
  186. Basis Metadaten Objekt. Wie man durch das folgende Code Snippet sieht, ist die
  187. grundsätzliche Metadaten Klasse recht leichtgewichtig und von Natur aus abstrakt:
  188. </para>
  189. <programlisting language="php"><![CDATA[
  190. class Zend_Tool_Framework_Manifest_Basic
  191. {
  192. protected $_type = 'Global';
  193. protected $_name = null;
  194. protected $_value = null;
  195. protected $_reference = null;
  196. public function getType();
  197. public function getName();
  198. public function getValue();
  199. public function getReference();
  200. /** ... */
  201. }
  202. ]]></programlisting>
  203. <para>
  204. Es gibt andere eingebaute Metadaten Klassen für das beschreiben von spezialisierteren
  205. Metadaten: <classname>ActionMetadata</classname> und
  206. <classname>ProviderMetadata</classname>. Diese Klassen helfen dabei Metadaten
  207. detailierter zu beschreiben die spezifisch für Actions oder Provider ist, und von der
  208. Referenz wird erwartet das Sie entweder eine Referenz zu einer Action oder einem
  209. Provider ist. Diese Klassen werden im folgenden Code Snippet beschrieben.
  210. </para>
  211. <programlisting language="php"><![CDATA[
  212. class Zend_Tool_Framework_Manifest_ActionMetadata
  213. extends Zend_Tool_Framework_Manifest_Metadata
  214. {
  215. protected $_type = 'Action';
  216. protected $_actionName = null;
  217. public function getActionName();
  218. /** ... */
  219. }
  220. class Zend_Tool_Framework_Manifest_ProviderMetadata
  221. extends Zend_Tool_Framework_Manifest_Metadata
  222. {
  223. protected $_type = 'Provider';
  224. protected $_providerName = null;
  225. protected $_actionName = null;
  226. protected $_specialtyName = null;
  227. public function getProviderName();
  228. public function getActionName();
  229. public function getSpecialtyName();
  230. /** ... */
  231. }
  232. ]]></programlisting>
  233. <para>
  234. Der 'Type' in diesen Klassen wird verwendet um den Typ der Metadaten zu beschreiben
  235. für den das Objekt verantwortlich ist. Im Fall von
  236. <classname>ActionMetadata</classname> würde der Typ 'Action' sein, und für
  237. <classname>ProviderMetadata</classname> ist der Typ natürlich 'Provider'. Diese
  238. Typen der Metadaten werden enthalten auch zusätzliche strukturierte Informationen,
  239. sowohl über das "Ding" das Sie beschreiben, als auch über das Objekt (das
  240. <methodname>getReference()</methodname> ) auf das Sie mit diesen neuen Metadaten
  241. referenzieren.
  242. </para>
  243. <para>
  244. Um einen eigenen Metadaten Typ zu erstellen, müssen alle die grundsätzliche
  245. <classname>Zend_Tool_Framework_Manifest_Metadata</classname> Klasse erweitern und diese
  246. neuen Metadaten Objekte über die lokale Manifest Klasse oder das Objekt zurückgeben.
  247. Diese Benutzerbasierten Klassen werden alle im Manifest Repository leben.
  248. </para>
  249. <para>
  250. Sobald diese Metadaten Objekte im Repository sind gibt es zwei unterschiedliche
  251. Methoden die verwendet werden können um nach Ihnen im Repository zu suchen.
  252. </para>
  253. <programlisting language="php"><![CDATA[
  254. class Zend_Tool_Framework_Manifest_Repository
  255. {
  256. /**
  257. * To use this method to search, $searchProperties should contain the names
  258. * and values of the key/value pairs you would like to match within the
  259. * manifest.
  260. *
  261. * For Example:
  262. * $manifestRepository->findMetadatas(array(
  263. * 'action' => 'Foo',
  264. * 'name' => 'cliActionName'
  265. * ));
  266. *
  267. * Will find any metadata objects that have a key with name 'action' value
  268. * of 'Foo', AND a key named 'name' value of 'cliActionName'
  269. *
  270. * Note: to either exclude or include name/value pairs that exist in the
  271. * search critera but do not appear in the object, pass a bool value to
  272. * $includeNonExistentProperties
  273. */
  274. public function findMetadatas(Array $searchProperties = array(),
  275. $includeNonExistentProperties = true);
  276. /**
  277. * The following will return exactly one of the matching search criteria,
  278. * regardless of how many have been returned. First one in the manifest is
  279. * what will be returned.
  280. */
  281. public function findMetadata(Array $searchProperties = array(),
  282. $includeNonExistentProperties = true)
  283. {
  284. $metadatas = $this->getMetadatas($searchProperties,
  285. $includeNonExistentProperties);
  286. return array_shift($metadatas);
  287. }
  288. }
  289. ]]></programlisting>
  290. <para>
  291. Wenn man sich die Suchmethoden von oben anschaut, erlauben die Signaturen eine extrem
  292. flexible Suche. Um ein Metadaten Objekt zu finden, muss man einfach ein Array von
  293. passenden Abhängigkeiten über ein Array anhängen. Wenn auf die Daten über den Property
  294. Accessor zugegriffen werden kann (die <methodname>getSomething()</methodname> Methoden
  295. implementieren das Metadaten Objekt), dann wird es an den Benutzer als "gefundenes"
  296. Metadaten Objekt zurück gegeben.
  297. </para>
  298. </sect2>
  299. <sect2 id="zend.tool.framework.architecture.clients">
  300. <title>Clienten</title>
  301. <para>
  302. Clienten sind das Interface welches einen Benutzer oder ein externes Tool in das
  303. System von <classname>Zend_Tool_Framework</classname> verknüpft. Clienten können in
  304. allen Formen und Größen vorkommen: <acronym>RPC</acronym> Endpunkte, Kommandozeilen
  305. Interface, oder sogar ein Web Interface. <classname>Zend_Tool</classname> hat das
  306. Kommandozeilen Interface als standard Interface für die Interaktion mit dem
  307. <classname>Zend_Tool_Framework</classname> System implementiert.
  308. </para>
  309. <para>
  310. Um einen Client zu implementieren, muss man die folgende abstrakte Klasse erweitern:
  311. </para>
  312. <programlisting language="php"><![CDATA[
  313. abstract class Zend_Tool_Framework_Client_Abstract
  314. {
  315. /**
  316. * This method should be implemented by the client implementation to
  317. * construct and set custom loaders, request and response objects.
  318. *
  319. * (not required, but suggested)
  320. */
  321. protected function _preInit();
  322. /**
  323. * This method should be implemented by the client implementation to parse
  324. * out and setup the request objects action, provider and parameter
  325. * information.
  326. */
  327. abstract protected function _preDispatch();
  328. /**
  329. * This method should be implemented by the client implementation to take
  330. * the output of the response object and return it (in an client specific
  331. * way) back to the Tooling Client.
  332. *
  333. * (not required, but suggested)
  334. */
  335. abstract protected function _postDispatch();
  336. }
  337. ]]></programlisting>
  338. <para>
  339. Wie man sieht gibt es 1 Methode benötigte Methode um die Notwendigkeiten eines
  340. Cliente zu erfüllen (zwei andere sind empfohlen), die Initialisierung, Vorbehandlung
  341. (pre handling) und Nachbehandlung (post handling). Für eine tiefere Studie darüber wie
  342. das Kommandozeilen Interface arbeitet, schauen Sie bitte im <ulink
  343. url="http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Tool/Framework/Client/Console.php">Source
  344. Code</ulink>.
  345. </para>
  346. </sect2>
  347. </sect1>