Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Jedno zadanie jeden obiekt. Czyżby?
Forum PHP.pl > Forum > PHP > Object-oriented programming
coomler
Cześć,
ostatnio postanowiłem poćwiczyć sobie programowanie obiektowe. Na tym forum zdążyłem już wiele razy przeczytać, że jeden obiekt = jedno zadanie. Przejdźmy do rzeczy. Mam jakieś archiwum a w nim kilka plików .txt. Teraz chcę napisać skrypt, który rozpakuje to archiwum i zmieni rozszerzenie plików z .txt na .html, po czym spakuje je. Jak zrobić to, aby było poprawnie? Osobna klasa do rozpakowywanie i pakowania i osobna do zmiany rozszerzenia? Czy w takim wypadku klasa stosować dziedziczenie? Może macie inne, lepsze, bardziej poprawne rozwiązania? Rozumiem, że lepiej nie pakować tego do jednej klasy?
mike
Zrób klasę Archiver, która będzie realizowała operacje extract i pack. Samą funkcjonalność tych operacji wydziel do klas ArchiveExtractor i ArchivePacker.
Ponadto napisz klasę w stylu File, do operacji na pliku. Operacji takich właśnie jak zmiana nazwy pliku.

Gdzie chciałbyś tu upchnąć dziedziczenie?

To wstępny pomysł. Szkic. Można go i zapewne trzeba, dopracować w zależności od Twoich potrzeb.
coomler
Cytat
Zrób klasę Archiver, która będzie realizowała operacje extract i pack. Samą funkcjonalność tych operacji wydziel do klas ArchiveExtractor i ArchivePacker.


Mam rozumieć, że do samej obsługi archiwów potrzebuję aż trzech klas? Archiver, która będzie wywoływać klasy ArchiveExtractor i ArchivePacker?

Zrozum mnie jeśli to źle zrozumiałem, ale jakoś tych dwóch zdań nie mogę pojąć. Ja myślałem o czymś takim - klasa Archiver i w niej są dwie metody jedna pakuje druga rozpakowuje.
Crozin
Czasami dobrze jest projektować od końca, tj. od interfejsu:
  1. $archive = new Archive('/path/to/archive');
  2. $archive->extract('/path/to/destination/dir');
  3.  
  4. $archive = new Archive();
  5.  
  6. foreach (new DirectoryIterator('/path/to/destination/dir') as $file) {
  7. $file->isFile() or continue;
  8.  
  9. // zmiana pliku tekstowego na dokument HTML
  10.  
  11. $archive->addFile($file);
  12. }
  13.  
  14. $achive->pack('/path/do/destination/file');
Oczywiście to jest przykład najbardziej podstawowego archiwizatora. Nie uwzględniłem tutaj też bloków try/catch na wyjątki.
coomler
Try/catch póki co nie używam, bo nie wiem za bardzo jak, ale wydaje mi się, że można je zastąpić instrukcją warunkową lub die().

Teraz już mniej więcej wiem jak to podzielić, ale mam jeszcze jedno pytanie, gdzie wpakować usunięcie tego niespakowanego katalogu(będziemy mieli archiwum z plikami .txt, archiwum z plikami .html oraz katalog z plikami .html). Ja bym go dał do klasy zmieniającej rozszerzenie, dokładniej w __destruct mimo tego że folder ten powstał dzięki klasie Archive(chyba że jako osobny obiekt).
Crozin
Usunięcie zbędnego katalogu przy powyższym schemacie dajesz po prostu po utworzeniu archiwum. Ot pętla usuwająca wszystkie pliki, a na końcu usunięcie pustego katalogu.

Cytat
Try/catch póki co nie używam, bo nie wiem za bardzo jak, ale wydaje mi się, że można je zastąpić instrukcją warunkową lub die().
Pomijając już fakt, że wyjątki w PHP są śmiechu warte. Nie, nie da się ich zastąpić w żaden cywilizowany sposób instrukcjami warunkowymi, a co do die()... wyjątki dopiero w ostateczności służą wywaleniu skryptu.
mike
Cytat(coomler @ 17.10.2010, 19:16:17 ) *
Mam rozumieć, że do samej obsługi archiwów potrzebuję aż trzech klas? Archiver, która będzie wywoływać klasy ArchiveExtractor i ArchivePacker?
W rzeczywistości ja napisałabym tu jeszcze więcej. Wspomniane wyżej zamieniłbym na interfejsy i dodał realizacje ZipArchiveExtractor, ZipArchivePacker.
Dzięki czemu możesz osiągnąć dużą elastyczność w implementacji, choćby dzięki strategii, którą można wykorzystać aby wprowadzić później użycie RarArchiveExtractor, e.t.c.

Skąd zdziwienie, że trzy klasy to dużo? Czemu uważasz to za problem? Małe klasy realizujące pojedynczą odpowiedzialność to coś do czego powinieneś dążyć.
coomler
Za problem tego nie uważam, ale przyznam, że wydaje mi się to sporo, pomimo tego, że rozumiem, że jedna klasa = jedno zadanie.

Dzięki za wszystkie wskazówki i zainteresowanie tematem.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.