To co drażniące może być w Javie przy przejściu z innych języków. To liczne zestawienie klas do obsługi I/O (wejścia/wyjścia). Możesz się o tym przekonać odwiedzając stronę http://java.sun.com/j2se/1.4.2/docs/api/java/io/package-tree.html. Same książki nie ułatwiają ich wykorzystania ponieważ uwaga skupiona jest na zobrazowaniu listy ważniejszych klas wraz z opisem i przykładowym kodem. Pojawia się wiele wątpliwości, przy zapisie poniższego kodu:
try { InputStream in = new BufferedInputStream( new FileInputStream("magiczne liczby.txt"));} catch (IOException e) { e.printStackTrace();}
Dlaczego teraz muszę tworzyć kilka obiektów, by móc przeczytać sobie plik? Czy to kaprys projektantów mający utrudnić życie kodującym w Javie?
Środkiem potrzebnym do uzyskania odpowiedzi jest wzorzec projektowy "dekorator". To on wyraża relacje jaka istnieje między wspomnianymi klasami. Znając go zrozumiesz korzystanie z wielu podobnych schematów.
Opis szczegółowy wzorca znajdziesz w książce Head First Design Patterns, a także na stronie http://marioosh.5dots.pl/2009/02/wzorce-projektowe-decorator/, aby go pojąć niezbędne jest zrozumienie polimorfizmu.
Przejdźmy do rzeczy, spójrz na poniższy rysunek:

Klasa OutputStream (zielona ramka) oraz klasa FilterOutputStream (czerwona ramka) służą istnieniu relacji we wzorcu dekoratora, to dzięki nim możliwe jest zestawienie klas o którym powiem za chwilę. W tym wątku przedstawię tylko możliwość korzystania z gotowej relacji. Jeżeli chcesz umieć utworzyć własną relacje dekoratora to zajrzyj do lektury.
Najistotniejsza rzecz polega na użyciu składnika (niebieska ramka) i opakowaniu go w dekoratory (fioletowa ramka). Sam dekorator na nic się nie przyda. Jednak użycie go na składniku powoduje, że sam składnik zyskuje nowe możliwości. Mieszanie składnika z dekoratorami pozwala utworzyć obiekt, który będzie zawierał porządne przez nas cechy. W ten sposób z wielu prostych klas można tworzyć złożony obiekt dostosowany do naszych potrzeb.
Co więcej, istnieje możliwość tworzenia nowych własnych dekoratorów. W przykładzie utworzę dekorator pozwalający usunąć z wejścia cyfry. Przepuszcza tylko białe znaki i litery. Należy w tym celu utworzyć klasę, która będzie dziedziczyć od FileOutputStream. Klasę nazwałem AlphaStream.
Implementacja:
Plik: AlphaStream.java
import java.io.*;
public class AlphaStream extends FilterInputStream { public AlphaStream(InputStream in){ super(in); }
@Override public int read() throws IOException{ int c;
while ((c = super.read()) != -1) { if (Character.isLetter(c) || Character.isWhitespace(c)) return c; } return -1; }}
Plik: Main.java
import java.io.*;
public class Main {
public static void main(String[] argc) { try{ InputStream in = new AlphaStream( new BufferedInputStream(System.in)); String buff = ""; int c; while((c = in.read()) >= 0){ buff += (char)c; } System.out.println(buff); } catch( IOException e) { e.printStackTrace(); } }
}
Brak komentarzy:
Prześlij komentarz