Wykład 2 - WGan.pl

advertisement
Tworzenie Aplikacji Internetowych
dr Wojciech M. Gańcza
2
Klasa GridRenderer

Klasa pisząca grid powinna
Przyjąć dane
 Wyświetlić na wyjściu tabelę zawierającą
dane

Dane możemy przekazać w
konstruktorze
 Albo przy wywołaniu metody render
 Konstruktorowi zostawmy definicję
tabeli (nagłówki, formaty) – dane
będą przekazane do metody render

Klasa GridRenderer …
class GridRenderer
{
function GridRenderer()
{
}
function render(&$out,
&$data)
…
}
Klasa GridRenderer …
function render(&$out, &$data)
{
$out->out(”<table>”);
while(!$data->eof())
{
$out->out(”<tr>”);
$row = $data->get();
foreach ($field in $row)
{
$out->out(”<td>$field</td>”);
}
$out->out(”</tr>”);
}
$out->out(”</table>”);
}
Klasa DataSource
Interfejs klasy określony jest przez to
czego się od niej wymaga.
 Można stworzyć interfejs który jest
prostszy – get może zwracać false
gdy nie ma danych
 Wtedy kod korzystający ze żródła
danych musi być na taką sytuacje
uczulony
 Ja wolę oddzielne metody (ale to
kwestia gustu)

Klasa DataSource …
class DataSource
{
function eof()
{
}
function get()
{
}
}
Przykładowe źródło danych
Do testów wyświetlania przyda nam
się jakiekolwiek źródło danych
 Zauważmy – że dane w czele nie
muszą pochodzić z bazy czy pliku!
 W przykładowym (testowym) źródle
możemy użyć wartości zaszytych na
sztywno w kodzie źródła
 Ma to swoje zalety – widok przy
każdym uruchomieniu będzie
dokładnie taki sam (testy!)

Przykładowe źródło danych
class ExampleSource
{
var $row;
function ExampleSource()
{
$this->row = 0;
}
function eof()
{
return $this->row == 3;
}
Przykładowe źródło danych
function get()
{
switch ($this->row)
{
case 0:
return array(1, ”Pierwszy”);
case 1:
return array(2, ”Btopou”);
case 2:
return array(3, ”Tres”);
};
}
}
Kilka uwag
Aby dostać się do składowych i
metod– musimy ZAWSZE używać this
 Jeśli tego nie zrobimy

Dla metod – dostaniemy informację o
tym, że taka funkcja (globalna) nie
istnieje (a jeśli istnieje – to zostanie
zawołana!)
 Dla składowych – otrzymamy zmienną
globalna o takiej nazwie – jeśli taka
istnieje lub utworzymy zmienną lokalną
– nie będzie informacji o błędzie!!!

Podział na pliki
Na początek wszystkie klasy możemy
definiować w jednym pliku
 Ale gdy program będzie się
komplikował

Trudno będzie znaleźć odpowiednią klasę
 Co z pracą w kilka osób


Warto umieszczać po jednej klasie w
pliku (i nazywać pliki jak klasy)
Program w wielu plikach

Kod umieszczony w innych plikach
możemy włączać do naszej strony
używając funkcji
include(…);
 require(…);
 require_once(…);


To nie są dyrektywy preprocesora
tylko funkcje – można przekazywać
nazwy plików w zmiennych, albo
włączać warunkowo
Strona

W aplikacji, wiele stron ma podobna
konstrukcję.
Nagłówek HTML
 Nagłówek aplikacji
 Menu
 Część robocza
 Stopka
 Zamknięcia znaczników strony


Warto przygotować sobie klasę która
je kapsułkuje
Klasa Page
class Page
{
var $body;
function setBody(&$body)
{
$this->body = &$body;
}
function render(&$out)
…
}
Klasa Page …
function render(&$out)
{
$out->out(”<html><head>”);
$out->out(”</head><body>”);
$this->body->render(&$out)
$out->out(”</body></html>”);
}

Ale jak podpiąć tu klasę rysującą grid z
danych
Budowa całej strony
Klasa tworząca grid potrzebuje przy
jego rysowaniu – drugiego parametru
 Nie można więc wstawić obiektu typu
GridRenderer jako ciała strony
 Co chyba wydaje się … dobre
 Grid – nie jest ciałem strony – ale
może być jej elementem
 Ciałem strony – powinien być Panel

Klasa Panel
class GridTestingPanel
{
function render(&$out)
{
$dat = new ExampleSource();
$grd = new GridRenderer();
$grd->render(&$out, &$dat);
}
}
Nareszcie pierwsza strona !
require_once(”Output.php”);
require_once(”Page.php”);
require_once(”GridRenderer.php”);
require_once(”ExampleSource.php”);
require_once(”ExampleSource.php”);
$out = new Output();
$page = new Page();
$panel = new GridTestingPanel();
$page->setBody(&$panel);
$page->render(&$out);
Po co to wszystko

Można prościej – pisząc po prostu kod
w HTML przeplatając poleceniami PHP
Szybciej otrzymujemy gotową stronę
 Kod jest szybciej interpretowany
 Nie robimy sobie bałaganu na dysku


Ale gdy aplikacja się rozrasta
Zmiany trzeba prowadzać w wielu
miejscach
 Trudno te miejsca znaleźć

Po co to wszystko …
Dodanie elementu do wszystkich
stron – wymaga zmiany klasy Page
 Zmiana metody pobierania danych –
wymaga użycia innego źródła
 Zmiana widoku, dodanie
formatowania czy dodanie innych
wariantów wyświetlania (PDF?)
wymaga jedynie zmiany renderera
 Łatwo można testować program

Testy
Testy są istotne
 Testujemy zawsze cały kod
 Testujemy każdą funkcjonalność
 Testy nie powinny zajmować nam
zbyt wiele czasu


Potrzebujemy możliwości
automatycznego testowania aplikacji
Testy automatyczne
Testy automatyczne – to nic innego
jak funkcje.
 Każda taka funkcja powinna
wyświetlić informacje o tym

Jaki test jest wykonywany
 Czy się powiódł
 Jeśli nie – to co się nie zgadza


Istnieje wiele środowisk testowych,
ale na nasze potrzeby napiszemy
własne 
Tester
class Tester
{
var $passed;
var $failed;
var $out;
function Tester()
{
$this->passed = 0;
$this->falied = 0;
}
Tester
function render(&$out)
{
$this->out = &$out;
// tu wołamy wszystkie funkcje
// testowe przekazując im $this
// jako tester na którym testy są
// sprawdzane.
// funcje te mogą wołać metodę
// test która sprawdza warunek…
$out->out(”<p>Passed: ” . $this->passed);
$out->out(”<p>Failed: ” . $this->failed);
}
Tester - test
function test($label, $should, $is)
{
$this->out->out(”Testing $label”);
if ($should == $is)
{
$this->out->out(” … passed<br>”);
++$this->passed;
}
else
{
$this->out->out(” … FAILED (found ‘$is’
but should be ‘$should’)<br>”);
++$this->failed;
}
}
Jak uruchomić testy?
Tester – ma taki sam interfejs jak
Panel – można więc go użyć jako
ciało strony
 Budując stronę testów możemy
wykorzystać klasę Page
 Funkcje testowe warto umieszczać w
oddzielnych plikach
 Ciało pierwszej funkcji testowej
możemy po prostu skopiować…

Test pierwszej strony
require_once(”Output.php”);
require_once(”Page.php”);
require_once(”GridRenderer.php”);
require_once(”ExampleSource.php”);
require_once(”ExampleSource.php”);
function TestOfFirstPage(&$tester)
{
$out = new TestingOutput();
$page = new Page();
$panel = new GridTestingPanel();
$page->setBody(&$panel);
$page->render(&$out);
$tester->test(”First page”, $out->getCRC(), 0);
}

Teraz wystarczy dodać wywołanie funnkcji do
testera
Rozbudowa testera
Przeszukiwanie katalogu z testami i
włączanie wszystkich znalezionych
plików.
 Uruchamianie wszystkich funkcji
testowych (jakoś je trzeba wyróżnić)
 Dodanie funkcji testujących konkretne
elementy które powtarzają się w
programie (źródeł danych, paneli, …)
 Inne – w miarę potrzeb

W następnym odcinku
Jak dostać się do bazy danych
 Elementy języka SQL
 Konstruktor bazy
 Dodawanie danych testowych
 Źródło danych
 I może uda się pokazać dane z bazy

Download