Zend_Tool_Framework-Architecture.xml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15617 -->
  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 <code>include_path</code> kommen können,
  10. wird eine Registry angeboten um den Zugriff auf die verschiedenen Teile der Toolchain
  11. zu vereinfachen. Diese Registry wird in Komponenten eingefügt die registry-aware sind,
  12. und damit Abhängigkeiten entfernen können, wenn das notwendig ist. Die meisten
  13. Abhängigkeiten die in der Registry registriert werden sind Unter-Komponenten
  14. 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/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 Zend_Tool_Framework_Provider_Interface oder
  104. Zend_Tool_Framework_Manifest_Interface implementieren. Sobald diese Dateien vom
  105. Loader gefunden wurden, werden die Provider in das Provider Repository geladen und
  106. 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 _getFiles() Methode sollte ein Array von Dateien zurückgeben (absolute Pfade). Der
  123. mit ZF ausgelieferte Loader wird IncludePath Loader genannt. Standardmäßig verwendet
  124. das Tooling Framework einen Loader der auf dem Include Pfad basiert um Dateien zu
  125. finden die Provider oder Manifest Metadaten Objekte enthalten können.
  126. Zend_Tool_Framework_Loader_IncludePathLoader sucht, ohne irgendeine Option, nach
  127. Dateien im Include Pfad die mit Mainfest.php, Tool.php oder Provider.php enden. Sobald
  128. Sie gefunden wurden, werden Sie (durch die load() Methode von
  129. Zend_Tool_Framework_Loader_Abstract) getestet um zu erkennen ob Sie irgendeines der
  130. unterstützten Interfaces implementieren. Wenn Sie das tun, wird eine Instanz der
  131. gefundenen Klasse instanziiert, und dann dem richtigen Repository angehängt.
  132. </para>
  133. <programlisting language="php"><![CDATA[
  134. class Zend_Tool_Framework_Loader_IncludePathLoader
  135. extends Zend_Tool_Framework_Loader_Abstract
  136. {
  137. protected $_filterDenyDirectoryPattern = '.*(/|\\\\).svn';
  138. protected $_filterAcceptFilePattern = '.*(?:Manifest|Provider)\.php$';
  139. protected function _getFiles()
  140. {
  141. /** ... */
  142. }
  143. }
  144. ]]></programlisting>
  145. <para>
  146. Wie man sieht, durchsucht der IncludePath Loader alle include_paths nach den Dateien
  147. die $_filterAcceptFilePattern entsprechen und $_filterDenyDirectoryPattern NICHT
  148. entsprechen.
  149. </para>
  150. </sect2>
  151. <sect2 id="zend.tool.framework.architecture.manifests">
  152. <title>Manifests</title>
  153. <para>
  154. Kurz gesagt, sollte ein Manifest spezielle oder eigene Metadaten enthalten, die für
  155. jeden Provider oder Client nützlich sind, sowie dafür verantwortlich sein alle
  156. zusätzlichen Provider in das Provider Repository zu laden.
  157. </para>
  158. <para>
  159. Um Metadaten in ein Manifest Repository einzuführen, müssen alle das leere
  160. Zend_Tool_Framework_Manifest_Interface implementieren, und eine
  161. getMetadata() Methode anbieten die ein Array von Objekten zurückgeben sollte, welches
  162. Zend_Tool_Framework_Manifest_Metadata implementiert.
  163. </para>
  164. <programlisting language="php"><![CDATA[
  165. interface Zend_Tool_Framework_Manifest_Interface
  166. {
  167. public function getMetadata();
  168. }
  169. ]]></programlisting>
  170. <para>
  171. Metadaten Objekte werden in das Manifest Repository
  172. (Zend_Tool_Framework_Manifest_Repository) geladen (durch einen wie unten definierten
  173. Loader). Manifeste werden ausgeführt nachdem alle Provider gefunden und in das
  174. Provider Repository geladen wurden. Das sollte es Manifeste erlauben Metadaten Objekte,
  175. basierend auf dem was aktuell im Provider Repository ist, zu erstellen.
  176. </para>
  177. <para>
  178. Es gibt ein paar andere Metadaten Klassen die dazu verwendet werden können um Metadaten
  179. zu beschreiben. Wie man durch das folgende Code Snippet sieht, ist die grundsätzliche
  180. Metadaten Klasse recht leichtgewichtig und von Natur aus abstrakt:
  181. </para>
  182. <programlisting language="php"><![CDATA[
  183. class Zend_Tool_Framework_Manifest_Basic
  184. {
  185. protected $_type = 'Global';
  186. protected $_name = null;
  187. protected $_value = null;
  188. protected $_reference = null;
  189. public function getType();
  190. public function getName();
  191. public function getValue();
  192. public function getReference();
  193. /** ... */
  194. }
  195. ]]></programlisting>
  196. <para>
  197. Es gibt andere eingebaute Metadaten Klassen für das beschreiben von spezialisierteren
  198. Metadaten: ActionMetadata und ProviderMetadata. Diese Klassen helfen dabei Metadaten
  199. detailierter zu beschreiben die spezifisch für Actions oder Provider ist, und von der
  200. Referenz wird erwartet das Sie entweder eine Referenz zu einer Action oder einem
  201. Provider ist. Diese Klassen werden im folgenden Code Snippet beschrieben.
  202. </para>
  203. <programlisting language="php"><![CDATA[
  204. class Zend_Tool_Framework_Manifest_ActionMetadata
  205. extends Zend_Tool_Framework_Manifest_Metadata
  206. {
  207. protected $_type = 'Action';
  208. protected $_actionName = null;
  209. public function getActionName();
  210. /** ... */
  211. }
  212. class Zend_Tool_Framework_Manifest_ProviderMetadata
  213. extends Zend_Tool_Framework_Manifest_Metadata
  214. {
  215. protected $_type = 'Provider';
  216. protected $_providerName = null;
  217. protected $_actionName = null;
  218. protected $_specialtyName = null;
  219. public function getProviderName();
  220. public function getActionName();
  221. public function getSpecialtyName();
  222. /** ... */
  223. }
  224. ]]></programlisting>
  225. <para>
  226. Der 'Type' in diesen Klassen wird verwendet um den Typ der Metadaten zu beschreiben
  227. für den das Objekt verantwortlich ist. Im Fall von ActionMetadata würde der Typ
  228. 'Action' sein, und für ProviderMetadata ist der Typ natürlich 'Provider'. Diese
  229. Typen der Metadaten werden enthalten auch zusätzliche strukturierte Informationen,
  230. sowohl über das "Ding" das Sie beschreiben, als auch über das Objekt (das
  231. ->getReference() ) auf das Sie mit diesen neuen Metadaten referenzieren.
  232. </para>
  233. <para>
  234. Um einen eigenen Metadaten Typ zu erstellen, müssen alle die grundsätzliche
  235. Zend_Tool_Framework_Manifest_Metadata Klasse erweitern und diese neuen Metadaten
  236. Objekte über die lokale Manifest Klasse/Objekt zurückgeben. Diese Benutzerbasierten
  237. Klassen werden alle im Manifest Repository leben.
  238. </para>
  239. <para>
  240. Sobald diese Metadaten Objekte im Repository sind gibt es zwei unterschiedliche
  241. Methoden die verwendet werden können um nach Ihnen im Repository zu suchen.
  242. </para>
  243. <programlisting language="php"><![CDATA[
  244. class Zend_Tool_Framework_Manifest_Repository
  245. {
  246. /**
  247. * To use this method to search, $searchProperties should contain the names
  248. * and values of the key/value pairs you would like to match within the
  249. * manifest.
  250. *
  251. * For Example:
  252. * $manifestRepository->findMetadatas(array(
  253. * 'action' => 'Foo',
  254. * 'name' => 'cliActionName'
  255. * ));
  256. *
  257. * Will find any metadata objects that have a key with name 'action' value
  258. * of 'Foo', AND a key named 'name' value of 'cliActionName'
  259. *
  260. * Note: to either exclude or include name/value pairs that exist in the
  261. * search critera but do not appear in the object, pass a bool value to
  262. * $includeNonExistentProperties
  263. */
  264. public function findMetadatas(Array $searchProperties = array(),
  265. $includeNonExistentProperties = true);
  266. /**
  267. * The following will return exactly one of the matching search criteria,
  268. * regardless of how many have been returned. First one in the manifest is
  269. * what will be returned.
  270. */
  271. public function findMetadata(Array $searchProperties = array(),
  272. $includeNonExistentProperties = true)
  273. {
  274. $metadatas = $this->getMetadatas($searchProperties,
  275. $includeNonExistentProperties);
  276. return array_shift($metadatas);
  277. }
  278. }
  279. ]]></programlisting>
  280. <para>
  281. Wenn man sich die Suchmethoden von oben anschaut, erlauben die Signaturen eine extrem
  282. flexible Suche. Um ein Metadaten Objekt zu finden, muss man einfach ein Array von
  283. passenden Abhängigkeiten über ein Array anhängen. Wenn auf die Daten über den Property
  284. Accessor zugegriffen werden kann (die getSomething() Methoden implementieren das
  285. Metadaten Objekt), dann wird es an den Benutzer als "gefundenes" Metadaten Objekt
  286. zurück gegeben.
  287. </para>
  288. </sect2>
  289. <sect2 id="zend.tool.framework.architecture.clients">
  290. <title>Clienten</title>
  291. <para>
  292. Clienten sind das Interface welches einen Benutzer oder ein externes Tool in das
  293. System von Zend_Tool_Framework verknüpft. Clienten können in allen Formen und Größen
  294. vorkommen: RPC Endpunkte, Kommandozeilen Interface, oder sogar ein Web Interface.
  295. Zend_Tool hat das Kommandozeilen Interface als standard Interface für die Interaktion
  296. mit dem Zend_Tool_Framework System implementiert.
  297. </para>
  298. <para>
  299. Um einen Client zu implementieren, muss man die folgende abstrakte Klasse erweitern:
  300. </para>
  301. <programlisting language="php"><![CDATA[
  302. abstract class Zend_Tool_Framework_Client_Abstract
  303. {
  304. /**
  305. * This method should be implemented by the client implementation to
  306. * construct and set custom loaders, request and response objects.
  307. *
  308. * (not required, but suggested)
  309. */
  310. protected function _preInit();
  311. /**
  312. * This method should be implemented by the client implementation to parse
  313. * out and setup the request objects action, provider and parameter
  314. * information.
  315. */
  316. abstract protected function _preDispatch();
  317. /**
  318. * This method should be implemented by the client implementation to take
  319. * the output of the response object and return it (in an client specific
  320. * way) back to the Tooling Client.
  321. *
  322. * (not required, but suggested)
  323. */
  324. abstract protected function _postDispatch();
  325. }
  326. ]]></programlisting>
  327. <para>
  328. Wie man sieht gibt es 1 Methode benötigte Methode um die Notwendigkeiten eines
  329. Cliente zu erfüllen (zwei andere sind empfohlen), die Initialisierung, Vorbehandlung
  330. (pre handling) und Nachbehandlung (post handling). Für eine tiefere Studie darüber wie
  331. das Kommandozeilen Interface arbeitet, schauen Sie bitte im <ulink
  332. url="http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Tool/Framework/Client/Console.php">Source
  333. Code</ulink>.
  334. </para>
  335. </sect2>
  336. </sect1>