Na początek rozszyfrujmy skróty:
DAO - Data Access Object - czyli coś co zapewnia dostęp do źródła danych, nie ważne czy to z pliku czy to z bazy danych. Najlepiej żeby to był interfejs bo dzięki temu możliwe jest bardzo łatwe zmienianie źródła danych - co ma jeszcze dodatkowe znaczenie w testowaniu.
public interface UserDAO
{
List<User> getAllUsers();
}
I teraz nie ma problemu żeby zaimplementować ten interfejs np. tak żeby pobierał dane z pliku, a drugą implementacją będzie integracja z bazą danych:
public class FileData implements UserDAO
{
public List<User> getAllUsers()
{
//....implemetnacja
}
}
//dla bazy danych
public class DBData implements UserDAO
{
public List<User> getAllUsers()
{
//implementacja
}
}
I teraz kod, który korzysta z DAO jest odporny na zmianę źródła danych:
public class UserService
{
UserDAO userDAO;
public UserService(UserDAO userDAO)
{
this.userDAO = userDAO;
}
public List<User> getAllUsers()
{
return userDAO.getAllUsers();
}
}
//zastosowanie powyższej klasy
UserService userService = new UserService(new FileData()); //kiedy źródło danych to plik
UserService userService2 = new UserService(new DBData()); //kiedy źródło to baza danych
//zauważ że w kodzie klasy UserService nie trzeba nić zmieniać kiedy zmienia się źródło danych
DTO - Data Transfer Object - to obiekt, za pośrednictwem, którego udostępnia się jakieś dane zwykle na zewnątrz aplikacji - suche dane. To ma głównie zastosowanie w aplikacjach, które posiadają interfejs do którego można podłączyć się zdalnie (np. REST API), i gdzie dane udostępniane są tak na prawdę nie wiadomo komu. Błędem jest wystawianie bezpośrednio encji pobranych z bazy na zewnątrz. Dzięki DTO można udostępnić tylko część danych np. nie powinno się wyciągać haseł - nawet jeśli są hashowane.
To wydaje mi się, że najlepiej widać kiedy stosuje się JPA. Klasy encji są tak na prawdę tabelami bazy danych, i ich struktury nie można ujawniać. Być może jeszcze nie ma potrzeby udostępniania wszystkich danych np. wspomnianych haseł:
@Entity
public class Person
{
private String PESEL;
private String firstName;
private String lastName;
private String password;
//gettery settery
}
Jeśli udostępnia się powyższy obiekt - to nie należy udostępniać hasła i numeru PESEL:
public class PersonDTO
{
private String firstName;
private String lastName;
//gettery settery
}