Dao jeden interfejs, 2 implementacje, wyjątki i Spring

0

Houston mam problem, taki intefejs Dao wspólny dla dwóch implementacji

public interface StudentsDao {
	List<Student> list();
	void save(Student student);
	void initializeDataSource();
}

jedna wykorzystująca bazę danych (korzystam z hibernate), druga moja StudentsTxtDaoImpl . W przypadku mojej implementacji chciałabym informować komponenty wyżej (żeby na końcu w widoku użytkownik dostał powiadomienie) jeżeli podczas wczytywania pliku wystąpi np. błędna linijka (co się może zdarzyć, bo plik czasem będzie edytowany ręcznie) lub IOException. W implementacji z Hibernate nie muszę rzucać żadnymi wyjątkami. Zastanawiam się nad 3 wyjściami:

  1. Łapać IOException w swojej implementacji StudentsTxtDaoImpl i zrobić interfejs txtDaoClient dla klienta tej implementacji, który będzie otrzymywać info z tej implementacji np.
} catch (IOException io) {
	txtDaoClient.loadError();
	io.printStackTrace();
}

albo w przypadku błędnej linijki txtDaoClient.incorrectLine(line);

  1. Dodać throws IOException i jakieś inne swoje wyjątki do wspólnego interfejsu (mimo, że implementacja z Hibernate wyjątkami nie rzuca) i tym sposobem przekazywać wszystko wyżej.

  2. Stworzyć osobną klasę FileChecker w modelu czy gdzieś żeby najpierw sprawdziła plik, powiadomiła które linijki złe i czy ścieżka okey a potem dopiero użyć StudentsTxtDaoImpl

PS Mam wstrzykiwacza IoC Springa ;]

1

Według mnie metoda initializeDataSource w StudentsDao dziwnie pachnie :P. Skoro użytkownik wybiera implementację w widoku, to ja bym pomyślał nad przeniesieniem initializeDataSource do StudentsTxtDaoImpl. Tworzenie StudentsDao przeniósłbym do jakiejś metody/klasy z założeniem, że to stworzenie może się nie powieść. W przypadku tworzenia StudentsTxtDaoImpl wywoływałbym metodę initializeDataSource na konkretnej implementacji i odpowiednio reagował na niepowodzenie.

0

@mychal dobra jutro sobie to napiszę i napiszę jak mi to wygląda. ta metoda initializeDataSource to jest aby implementacja pobrała sobie ścieżkę i ustawienia z innego springowego beana singletonowego, ale fakt muszę jeszcze zobaczyć, bo chyba nie powinna być w interfejsie.

@Override
public void initializeDataSource() {
	filePath = Paths.get(txtDaoConfiguration.getFilename());
	charset = txtDaoConfiguration.getCharset();
}
1

@karolinaa, metoda initializeDataSource wykorzystywana w taki sposób jest o nóg tęgich wsparta słupy (sobie dorymuj końcówkę). Ma sens tylko w jednej implementacji DAO więc jest zbędna w interfejsie. Jeżeli już chcesz coś takiego mieć to nie na poziomie interfejsu, ale w konkretnej implementacji jako:

@PostConstruct
public void initializeDataSource() {
    filePath = Paths.get(txtDaoConfiguration.getFilename());
    charset = txtDaoConfiguration.getCharset();
}

Adnotacja @PostConstruct powoduje, że kontener IoC wywoła metodę po utworzeniu beana tzn. po wstyrzyknięciu wszystkich zalezności.

Co do informowania, że pobranie się nie powiodło to można stworzyć sobie napisać mechanizm callback, który wyśle powiadomienie w razie błędu do obiektu odpowiedzialnego za obsługę. Opcja nr 3. też jest całkiem fajna, ale nie powinna być ujawniana. Inaczej mówiąc StudentsTxtDaoImpl powinno mieć taki checker jako zalezność i odpalać go bez wiedzy, zgody i udziału użytkownika.

0

Dobra zrezygnowałam z txtDaoConfiguration przenosząc to czym się zajmowało do implementacji StudentsTxtDaoImpl i mam np;

public void setCharset(String charset) {
	this.charset = Charset.forName(charset);
}

i sobie ustawiam Springiem "UTF-8". (w konstruktorze na wszelki wypadek mam inicjalizacje Charset.default() w przypadku braku konfiguracji tego w Springu).

do tego też zrobiłam;

public interface TxtDaoEvents {
	void incorrectLine(String line);
	void loadError();
	void writeError();
}

i w StudentsTxtDaoImpl pole private TxtDaoEvents client; . Dao powiadomi w przypadku złej linijki / błędów podłączonego klienta. Teraz tylko zostaje mi zrobić w modelu jakiś obiekt np. public class Warner implements TxtDaoEvents , wstrzyknąć go do tego dao i w widoku obserwującym Warnera coś ala;

@Override
public void wrongLine() {
	JOptionPane.showMessageDialog(null, warner.getIncorrectLine());
}
1

Rzuć okiem na Guava ESB i wysyłaj komunikaty zamiast zwykłego obserwatora :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1