Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [Klasa] Router, Moje pierwsze praktyczne kroki w OOP i prośba o ocenę :)
mathev19
post
Post #1





Grupa: Zarejestrowani
Postów: 6
Pomógł: 0
Dołączył: 22.11.2009
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Na wstępie chciałem się ze wszystkimi przywitać, ponieważ jest to mój pierwszy post.
Dobrze przejdźmy więc do rzeczy napisałem sobie klasę Routera, której kod możecie zobaczyć poniżej. Przede wszystkim proszę o obiektywną krytykę bo jest to moja pierwsza klasa. (IMG:style_emoticons/default/snitch.gif)
  1. <?php
  2.  
  3. class Router {
  4. private $sPath = null;
  5. private $sController = null;
  6. private $sAction = null;
  7. private $aUrlSegments = array();
  8. private $aParams = array();
  9.  
  10. public function __construct() {
  11. $this->sPath = $_SERVER['PATH_INFO'];
  12. $this->setUrlSegments();
  13. $this->setController();
  14. $this->setAction();
  15. $this->setParams();
  16. }
  17.  
  18. /**
  19. * pobiera nazwę serwera
  20. * @return string
  21. */
  22. public function getServerName() {
  23. return $_SERVER['HTTP_HOST'];
  24. }
  25.  
  26. /**
  27. * pobiera ścieżkę i dzieli ją na segmenty
  28. * następnie umieszcza wszystko w tablicy aUrlSegments
  29. */
  30. private function setUrlSegments() {
  31. $this->aUrlSegments = explode('/', $this->sPath);
  32. }
  33.  
  34. /**
  35. * ustawia nazwę controllera
  36. */
  37. private function setController() {
  38. $this->sController = $this->getUrlSegment(1);
  39. }
  40.  
  41. /**
  42. * pobiera nazwę controllera
  43. */
  44. public function getController() {
  45. return $this->sController;
  46. }
  47.  
  48. /**
  49. * ustawia nazwę akcji
  50. */
  51. private function setAction() {
  52. $this->sAction = $this->getUrlSegment(2);
  53. }
  54.  
  55. /**
  56. * pobiera nazwę akcji
  57. */
  58. public function getAction() {
  59. return $this->sAction;
  60. }
  61.  
  62. /**
  63. * pobiera segment URL'a o wyznaczonym id
  64. * @param int $id
  65. * @return string
  66. */
  67. public function getUrlSegment($id) {
  68. return (isset($this->aUrlSegments[$id])) ? $this->aUrlSegments[$id] : false;
  69. }
  70.  
  71. /**
  72. * ustawia parametry z URL'a
  73. */
  74. private function setParams(){
  75. $this->aParams = array_slice($this->aUrlSegments,3);
  76. }
  77.  
  78. /**
  79. * pobiera parametry z URL'a
  80. */
  81. public function getParams(){
  82. return $this->aParams;
  83. }
  84.  
  85. /**
  86. * tworzy adres URL
  87. * @param string $sController
  88. * @param string $sAction
  89. * @param array $aParams
  90. * @return string
  91. */
  92. public function createUrl($sController,$sAction,$aParams) {
  93. return $this->getServerName().'/index.php/'.$sController.'/'.$sAction.'/'.$aParams[0].'/'.$aParams[1].'/'.$aParams[2];
  94. }
  95. }
  96.  
  97. ?>

Teraz moje pytania dotyczące ów klasy:
1. Czy ogólny sposób napisania Routera jest zgodny z filozofią OOP?
2. Co mogę napisać inaczej (czyt. lepiej)?
3. W jaki sposób prawidłowo tworzyć URL'e (metoda createUrl, na którą jak widać w kodzie nie mam zupełnie pomysłu) (IMG:style_emoticons/default/sadsmiley02.gif)
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


  1. Daruj sobie tą notację (znowu zapomniałem jak się nazywa) z typem zmiennej w jej nazwie. Jeżeli masz mieć taki burdel w kodzie czy nazewnictwie, że nie mógłbyś się połapać w nim oznacza to, że coś masz źle napisane.
  2. $this->sPath = $_SERVER['PATH_INFO']; - jedna z zasad OOP: za wszelką cenę unikać pobierania jakiś globalnych danych z wnętrza metod. Co jeżeli z jakiś przyczyn będziesz chciał określać parametry nie na podstawie tej zmiennej tylko np $abc? Normalnie nie stanowi to problemu: new Router($_SERVER['PATH_INFO']); lub new Router($abc);, a u Ciebie trzeba babrać się w kodzie klasy.
  3. Nazwy metod zaczynające się na set czy get z reguły służą do oznaczania tzw. publicznych setterów i getterów - wprowadzasz w błąd. Jeżeli potrzebujesz jakiejś metody, która uruchomi się na początku działania obiektu lepiej nazwać ją setup lub setupSomething.
  4. Router::getServerName() - router nie powinien zajmować się takimi rzeczami.
  5. W ogóle to te metody set*() u Ciebie są na siłę wepchane. Możesz ich zawartość zbiorczo wrzucić w jedną metodę, albo bezpośrednio w kontrolerze wywołać.
  6. Każda z Twoich prywatnych metod powinna być co najwyżej chroniona.


Cytat
3. W jaki sposób prawidłowo tworzyć URL'e (metoda createUrl, na którą jak widać w kodzie nie mam zupełnie pomysłu)
URLe tworzy się w sposób odwrotny do pierwotnego działania routera. Na podstawie określonych parametrów tworzy się ciąg reprezentujący je. Ty masz bardzo prostu Router, który ogranicza się do rozbicia względem znaku ukośnika, a więc generowanie to łączenie parametrów (ułożonych w odpowiedniej kolejności) znakiem ukośnika.

Cytat
Poza tym przy moim routerze zastosowałem wzorzec singleton, podczas jednego wywołania Router jest mi potrzebny w kilku obiektach, więc w ten sposób unikam bezsensownego powielania działania funkcji explode
No to jeszcze raz: Singleton nie służy do dostępu do obiektu z każdego miejsca aplikacji!
  1. To co obecnie zrobiłeś, czyli:
    1. protected function myMethod() {
    2. $router = Router::getInstance();
    3. }
    Jest dokładnym odpowiednikiem:
    1. protected function myMethod() {
    2. global $router;
    3. }
    A o tym dlaczego global jest złem w czystej postaci zapewne wiesz. Dodałeś jedynie pseudo-obiektową otoczkę dla niego.
  2. Tracisz jakąkolwiek przenośność kodu - nagle kod Twojej klasy ABC staje się zależny niepotrzebnie zależny od kodu innej klasy.
  3. Jakakolwiek próba zmiany zachowania działania obiektu ABC (oczywiście tego związanego z wykorzystaniem Routera) oznacza konieczność mieszania w kodzie klasy (patrz pkt 1.2 z pierwszej listy)


Cytat
Czy obiekt widoku powinienem tworzyć w dispatcherze czy jednak przerzucić to na kontroller?
Nazwa kontroler sugeruje, że mówimy tutaj o MVC, a podstawowe założenie tego wzorca to: Kontroler decyduje jakiego widok(ów) użyć i jakie przekazać do niego(ich) modele - dodatkowo Kontroler może wysłać jakąś informację do Modelu

Ten post edytował Crozin 29.07.2010, 12:50:09
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 10.06.2026 - 12:34