DAO מסמכת לגישה לנתונים. דגם ארכיטקטורי DAO משמש להפרדת הלוגיקה של ניצול הנתונים בשכבה נפרדת. בכך, השירות נשאר מובנה לגמרי ללא הבנה על אופן מימוש הפעולות ברמה נמוכה לגישה למסד הנתונים. מה שמכונה בעיקרון פיצול הלוגיקה.
דגם ארכיטקטורי DAO
עם דגם הארכיטקטורה DAO, יש לנו את הרכיבים הבאים עליהם תלוי עיצוב המערכת שלנו:
- המודל שמועבר משכבה אחת לאחרת.
- הממשקים המספקים עיצוב גמיש.
- מימוש הממשק המהווה מימוש קונקרטי של הלוגיקה לניצול הנתונים.
מימוש דגם DAO
עם הרכיבים המוזכרים לעיל, ננסה לממש את דגם הDAO. נשתמש ב-3 רכיבים כאן:
- המודל
Book
שמועבר משכבה אחת לאחרת. - ממשק ה-
BookDao
שמספק עיצוב גמיש וממשק API למימוש. BookDaoImpl
מחלקת קוד בטון שהיא יישום של ממשקBookDao
.
בואו נכניס את הלוגיקה הזו לתרשים:
מודל תבנית DAO
עכשיו, נציג את אובייקט המודל שלנו.
package com.journaldev.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 setter
}
זהו אובייקט פשוט עם שני מאפיינים כדי לשמור על הדברים פשוטים.
ממשק תבנית DAO
נגדיר כעת את הממשק לגישה לנתונים הקשורים אליו ברמת ההתמידות.
package com.journaldev.dao;
import com.journaldev.model.Books;
import java.util.List;
public interface BookDao {
List<Books> getAllBooks();
Books getBookByIsbn(int isbn);
void saveBook(Books book);
void deleteBook(Books book);
}
מימוש תבנית DAO
לבסוף, ניצור מחלקה בטונה המיישמת את הממשק לעיל.
package com.journaldev.daoimpl;
import com.journaldev.dao.BookDao;
import com.journaldev.model.Books;
import java.util.ArrayList;
import java.util.List;
public class BookDaoImpl implements BookDao {
// הרשימה פועלת כבסיס נתונים
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);
}
}
שימוש בתבנית DAO
סופסוף, השתמשנו במימוש זה בשיטת ה- main() שלנו:
package com.journaldev;
import com.journaldev.dao.BookDao;
import com.journaldev.daoimpl.BookDaoImpl;
import com.journaldev.model.Books;
public class AccessBook {
public static void main(String[] args) {
BookDao bookDao = new BookDaoImpl();
for (Books book : bookDao.getAllBooks()) {
System.out.println("Book ISBN : " + book.getIsbn());
}
//עדכון תלמיד
Books book = bookDao.getAllBooks().get(1);
book.setBookName("Algorithms");
bookDao.saveBook(book);
}
}
יתרונות של התבנית DAO
ישנם רבים יתרונות לשימוש בתבנית DAO. בואו נציין כמה מהם כאן:
- בעת שינוי מנגנון השמירה, שכבת השירות אף פעם אינה צריכה לדעת מאיפה מגיעים הנתונים. לדוגמה, אם אתה חושב על החלפה משימוש ב-MySQL ל-MongoDB, כל השינויים נדרשים להתבצע בשכבת ה-DAO בלבד.
- התבנית DAO מדגישה את ההתמקדות הנמוכה בין הרכיבים השונים של היישום. לכן, שכבת ה-View אינה תלויה בשכבת ה-DAO ורק שכבת השירות תלויה בה, אף על פי שזאת באמצעות הממשקים ולא מהמימוש הממשי.
- מאחר שהלוגיקה של השמירה היא מופרדת לחלוטין, ישנה יתרון רב יותר בכתיבת בדיקות יחידה לרכיבים פרטיים. לדוגמה, אם אתה משתמש ב-JUnit וב-Mockito כמסגרות לבדיקות, יהיה קל לשקף את רכיבי היישום הפרטיים שלך.
- כשאנו עובדים עם ממשקים בתבנית DAO, היא גם מדגישה את הסגנון "עבודה עם ממשקים במקום מימוש" שהוא סגנון מעולה של תכנות מונחה עצמים.
מסקנת התבנית DAO
שימו לב שבמאמר זה למדנו איך ניתן להשתמש בתבנית עיצוב DAO כדי להדגיש את החשיבות של שמירת הלוגיקה של התמידות בנפרד ובכך לשמר על קשר פחות צמוד בין הרכיבים שלנו. תבניות עיצוב מתבססות רק על אופן תכנות ולכן הן אינן תלויות בשפה או בסביבת פיתוח כלשהי. נשמח לקבל את דעתך בתגובות למטה. להורדת דוגמא לפרויקט שמציג את תבנית ה-DAO, יש ללחוץ על הקישור למטה:
מקורות: תיעוד Oracle, ויקיפדיה.
Source:
https://www.digitalocean.com/community/tutorials/dao-design-pattern