Das DAO Design Pattern: Ein praktischer Ansatz
In der modernen Softwarearchitektur ist es entscheidend, eine klare Trennung zwischen Geschäftslogik und Datenzugriff zu gewährleisten. Hier kommt das DAO (Data Access Object) Design Pattern ins Spiel. Das DAO-Pattern bietet eine systematische Möglichkeit, auf Daten aus einem persistenten Speichermechanismus, wie einer Datenbank, zuzugreifen, während sichergestellt wird, dass die Kernlogik von Änderungen an der Art und Weise, wie oder wo die Daten gespeichert werden, unberührt bleibt.
Schlüsselkomponenten des DAO-Patterns
Das DAO-Pattern kann in drei Hauptkomponenten unterteilt werden:
- Model: Repräsentiert die Datenstruktur, die zwischen den verschiedenen Schichten der Anwendung fließt.
- Interface: Bietet einen Vertrag für die Persistenzlogik und bietet Flexibilität für zukünftige Änderungen.
- Concrete Implementation: Eine spezifische Implementierung der Persistenzlogik, die durch das Interface definiert wird.
Implementierung des DAO-Patterns
In diesem Beitrag werden wir ein vereinfachtes DAO-Pattern mit einem Beispiel zur Verwaltung von Büchern implementieren. Wir werden die folgenden Schlüsselkomponenten durchgehen:
- Das Buchmodell – Dieses Modell repräsentiert einzelne Bücher.
- Das BookDao-Interface – Definiert die Operationen, die an Büchern durchgeführt werden können, wie z. B. das Abrufen oder Speichern von Büchern.
- Die BookDaoImpl-Klasse – Eine konkrete Implementierung des BookDao-Interfaces, die eine Datenbankinteraktion simuliert.
Lassen Sie uns in den Code eintauchen, um zu sehen, wie das funktioniert.
Schritt 1: Das Modell – Buchklasse
Das Modellobjekt repräsentiert die Daten, die zwischen den verschiedenen Schichten der Anwendung übertragen werden. In unserem Beispiel ist dies die Books
-Klasse, die zwei Eigenschaften hat: isbn
(zur eindeutigen Identifizierung eines Buches) und bookName
.
package com.example.model;
public class Books {
private int isbn;
private String bookName;
public Books() {
}
public Books(int isbn, String bookName) {
this.isbn = isbn;
this.bookName = bookName;
}
// Getter- und Setter-Methoden
public int getIsbn() {
return isbn;
}
public void setIsbn(int isbn) {
this.isbn = isbn;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
Diese Klasse bietet eine einfache Struktur mit einem Bezeichner (isbn
) und dem Namen des Buches. Die Getter- und Setter-Methoden ermöglichen einen gekapselten Zugriff auf diese Felder.
Schritt 2: Das Interface – BookDao
Als nächstes definieren wir das BookDao
-Interface. Dies dient als Vertrag für jede Implementierungsklasse und stellt sicher, dass bestimmte Datenoperationen (wie das Abrufen, Speichern oder Löschen von Büchern) einheitlich implementiert werden.
package com.example.dao;
import com.example.model.Books;
import java.util.List;
public interface BookDao {
List getAllBooks();
Books getBookByIsbn(int isbn);
void saveBook(Books book);
void deleteBook(Books book);
}
Das Interface definiert vier Hauptmethoden:
getAllBooks
: Abrufen einer Liste aller Bücher.getBookByIsbn
: Finden eines Buches anhand der ISBN.saveBook
: Hinzufügen eines neuen Buches zum System.deleteBook
: Entfernen eines vorhandenen Buches.
Schritt 3: Die Implementierung – BookDaoImpl
Nun implementieren wir die Persistenzlogik in der BookDaoImpl
-Klasse. In diesem Beispiel ist eine einfache In-Memory-Liste verwendet, um eine Datenbank zu simulieren.
package com.example.daoimpl;
import com.example.dao.BookDao;
import com.example.model.Books;
import java.util.ArrayList;
import java.util.List;
public class BookDaoImpl implements BookDao {
// Eine Liste simuliert eine Datenbank
private List books;
public BookDaoImpl() {
books = new ArrayList<>();
books.add(new Books(1, "Java"));
books.add(new Books(2, "Python"));
books.add(new Books(3, "Android"));
}
@Override
public List getAllBooks() {
return books;
}
@Override
public Books getBookByIsbn(int isbn) {
return books.get(isbn);
}
@Override
public void saveBook(Books book) {
books.add(book);
}
@Override
public void deleteBook(Books book) {
books.remove(book);
}
}
In der obigen Klasse:
- Die
books
-Liste simuliert einen einfachen Speichermechanismus. - Die Methode
getAllBooks
ruft alle Bücher in dieser Liste ab. - Die Methode
getBookByIsbn
ruft ein bestimmtes Buch anhand der ISBN ab. saveBook
fügt ein neues Buch zur Sammlung hinzu.deleteBook
entfernt ein vorhandenes Buch aus der Liste.
Schritt 4: Verwendung des DAO im Hauptprogramm
Schließlich können wir unsere DAO-Implementierung in einer einfachen main
-Methode testen. Hier interagieren wir mit dem DAO und führen verschiedene Operationen wie das Abrufen, Aktualisieren oder Hinzufügen neuer Bücher durch.
package com.example;
import com.example.dao.BookDao;
import com.example.daoimpl.BookDaoImpl;
import com.example.model.Books;
public class AccessBook {
public static void main(String[] args) {
BookDao bookDao = new BookDaoImpl();
// Abrufen aller Bücher
for (Books book : bookDao.getAllBooks()) {
System.out.println("Buch ISBN: " + book.getIsbn());
System.out.println("Buchname: " + book.getBookName());
}
// Aktualisierung eines Buches
Books book = bookDao.getBookByIsbn(1);
book.setBookName("Advanced Java");
bookDao.saveBook(book);
System.out.println("Aktualisierter Buchname: " + book.getBookName());
}
}
In diesem Beispiel:
- Holen wir alle verfügbaren Bücher ab und drucken sie aus.
- Aktualisieren wir den Namen eines Buches und speichern es zurück in die Sammlung.
Vorteile des DAO-Patterns
Das DAO-Pattern bietet mehrere Vorteile:
- Entkopplung: Die Datenzugriffslogik ist vollständig von der Geschäftslogik entkoppelt. Das bedeutet, dass Änderungen in der Datenbank oder der Datenquelle die Geschäftsschicht nicht beeinflussen.
- Flexibilität: Durch die Verwendung von Schnittstellen ist die Flexibilität gewährleistet, zwischen verschiedenen Datenquellen zu wechseln (z. B. von MySQL zu MongoDB), ohne die Kernlogik der Anwendung zu beeinträchtigen.
- Testbarkeit: Da die Persistenzlogik isoliert ist, ist es einfacher, einzelne Komponenten zu testen. Das Mocking von Schnittstellen kann beispielsweise Unit-Tests vereinfachen.
Fazit
Das DAO-Design-Pattern ist ein einfaches, aber leistungsstarkes Werkzeug zum Strukturieren von Anwendungen mit einer klaren Trennung zwischen Geschäftslogik und Datenzugriff. Durch die Nutzung von Schnittstellen und konkreten Implementierungen stellen Sie sowohl Flexibilität als auch Wartungsfreundlichkeit in Ihren Projekten sicher. Unabhängig davon, ob Ihre Anwendung an Komplexität gewinnt oder auf eine andere Datenbank wechselt, hilft Ihnen das DAO-Pattern dabei, Ihren Code robust und anpassungsfähig zu halten.