1. Dependency Injection là gì?
Dependency Inject là một kỹ thuật, 1 design pattern có thể chấp nhận được xóa quăng quật sự phụ thuộc hard-code và tạo nên ứng dụng của khách hàng dễ mở rộng và maintain hơn.
Bạn đang xem: Dependency là gì
Để hiểu tư tưởng trên, mình có ví dụ sau:
Mình có một ứng dụng hotline tới object của class MySQLDAO(class MySQLDAO chuyên tiến hành truy vấn cùng với cơ sở dữ liệu MySQL của ứng dụng)
Bây giờ bạn muốn truy vấn cho tới cơ sở dữ liệu postgre. Chúng ta phải xóa khai báo MySQLDAO trong ứng dụng và thay bởi PostgreDAO, kế tiếp muốn cần sử dụng lại MySQLDAO chúng ta lại làm cho ngược lại… rõ ràng code sẽ phải sửa lại với test các lần.
Giải pháp sử dụng if-else kiểm tra điều kiện sẽ dùng đối tượng người sử dụng DAO nào… nhưng sau đấy tất cả thêm một DAO khác ví dụ như MSSQLDAO chẳng hạn… phức hợp hơn nhiều phải không.
(Thường thì ít khi 1 ứng dụng dùng những loại cửa hàng dữ liệu khác biệt nhưng sẽ sở hữu trường hợp sử dụng nhiều database, mình để thành những loại cơ sở dữ liệu khác nhau cho dễ hình dung)
Dependency Injection (DI) là gì? Code ví dụ bằng JavaDependency Inject chính là để xử lý cho ngôi trường hợp như vậy này.
Trong ví dụ như trên ta tạo thành 1 interface AbstractDAO và cho những class DAO cơ thừa kế AbstractDAO. Hiện giờ trong những class sử dụng DAO ta khai báo AbstractDAO, tùy theo điều kiện tương ứng AbstractDAO hoàn toàn có thể là MySQLDAO hoặc PostgreDAO.
Việc thay thế sửa chữa AbstractDAO bởi MySQLDAO/PostgreDAO được gọi là injection.

2. Ví dụ.
Mình vẫn code thử nghiệm ví dụ trên:
Tạo một interface nhằm khai báo những method giao tiếp với database:
public interface AbstractDAO void insert(); void delete(); void update();Tạo những class DAO khớp ứng với từng nhiều loại database với implements các method của AbstractDAO
public class MySQLDAO implements AbstractDAO
Override public void insert() System.out.println("MySQL insert");
Override public void delete() System.out.println("MySQL delete");
Override public void update() System.out.println("MySQL update"); public class PostgreDAO implements AbstractDAO
Override public void insert() System.out.println("Postgre insert");
Override public void delete() System.out.println("Postgre delete");
Override public void update() System.out.println("Postgre update"); public class MSSQLDAO implements AbstractDAO
Override public void insert() System.out.println("MSSQL insert");
Override public void delete() System.out.println("MSSQL delete");
Override public void update() System.out.println("MSSQL update"); file config.properites lưu tin tức config ra quyết định sẽ kết nối tới database nào.
## 1: MySQL | 2: Postgre | 3: MSSQLdatabase=2Bây giờ sống class yêu cầu dùng mang lại dao ta vẫn khai báo AbstractDAO, phụ thuộc vào tham số trong file config cơ mà ta khởi tạo đối tượng người sử dụng AbstractDAO là MySQLDAO, PostgreDAO hay MSSQLDAO.
public class Client AbstractDAO dao; public Client() dao = FactoryDAO.getDAO(); public AbstractDAO getDao() return dao; public void setDao(AbstractDAO dao) this.dao = dao; public void execute() dao.insert(); dao.update(); dao.delete(); Như chúng ta thấy tại chỗ này mình cần sử dụng Factory Pattern để quyết định đối tượng người tiêu dùng được tạo nên ra. Class FactoryDAO (Factory class) vẫn đọc file cùng quyết định đối tượng người sử dụng nào được tạo ra ra.
public class FactoryDAO public static AbstractDAO getDAO() Properties prop = new Properties(); InputStream input = null; try input đầu vào = new FileInputStream("source/config.properties"); // load a properties tệp tin prop.load(input); // get the database value String database = prop.getProperty("database"); if (database.equals("1")) return new MySQLDAO(); if (database.equals("2")) return new PostgreDAO(); if (database.equals("3")) return new MSSQLDAO(); catch (IOException ex) ex.printStackTrace(); return null; return null;
Demo lấy một ví dụ trên:
public class MainApp public static void main(String<> args) Client client = new Client(); client.execute(); Kết quả:Postgre insertPostgre updatePostgre deleteSửa quý giá database trong tệp tin config.properties bởi 1 với chạy lại:
MySQL insertMySQL updateMySQL deleteBây giờ nếu như bạn có thêm một loại database khác cần áp dụng thì chỉ việc tạo DAO đến nó, implements AbstractDAO và sửa lại FactoryDAO là được.
Ví dụ mình có thêm database DB2.
mình sẽ tạo class DB2DAO.java implements AbstractDAO.
trong method getDAO() của FactoryDAO thêm đk nếu database = 4 thì sẽ trả về DB2DAO.
rõ ràng phương pháp làm này đỡ đần ta sẽ mở rộng ứng dụng hơn không ít và từng lần biến đổi đối tượng dao ta không nhất thiết phải khởi động/deploy lại ứng dụng mà chỉ cần biến hóa thông tin trong file config.properties.
Việc lấy thông tin từ tệp tin config.properites rồi đưa ra quyết định tạo đối tượng trong class Client.java đó là tiêm sự nhờ vào (Dependency Injection – DI)
Download code lấy một ví dụ trên tại đây
3. Các phương pháp thực hiện nay Dependency Injection.
Các phương thức cơ bản để Dependency Injection.
Constructor Injection: những dependency sẽ tiến hành truyền vào (inject vào) 1 class thông qua constructor của class đó. Đây là biện pháp thông dụng nhất. (ví dụ trên mình dùng theo cách này)Setter Injection: những dependency sẽ được truyền vào 1 class thông qua các hàm Setter/GetterVí dụ sinh hoạt trên mình vẫn sửa method getDao làm việc class Client.java thành
public AbstractDAO getDao() dao = FactoryDAO.getDAO(); return dao;Public fields: các dependency sẽ được truyền vào 1 class một biện pháp trực tiếp vào những public field. Cách này không nhiều được áp dụng nhất. Ví dụ ngơi nghỉ trên khi khai báo AbstractDAO sinh hoạt class Client.java thànhAbstractDAO dao = FactoryDAO.getDAO();Dependency Injection (DI) là gì? Code ví dụ bằng Java
4. Ưu điểm yếu của Dependency Injection
Ưu điểmGiảm sự dính nối giữa những moduleCode dễ bảo trì, dễ sửa chữa moduleRất dễ chạy thử và viết Unit TestDễ dàng thấy quan hệ tình dục giữa những module (Vì những dependecy số đông được inject vào constructor)Nhược điểmKhái niệm DI hơi khó hiểu với những người mớiKhó debug vì phân vân implements làm sao của interface được hotline đếnCác object được khởi tạo từ đầu làm giảm performanceLàm tăng độ tinh vi của codeDo đó với đầy đủ ứng dụng nhỏ dại gọn, làm ăn luôn luôn thì ko nên áp dụng DI, còn những ứng dụng cần sự linh hoạt, mở rộng, maintain thì áp dụng DI.Xem thêm: Một Cửa Hàng Bán Hoa Quả (Trái Cây) Thu Được 1 800 000 Đồng, Tính Ra Số Tiền Lãi Bằng 20%
5. Một vài khái niệm khác
DI ContainerDI Container là chỉ hầu hết thành phần chế tạo và làm chủ module/object con được Inject, ví dụ làm việc trên là FactoryDAO.Hiện tại có rất nhiều Framework và những thư viện cung cấp làm DI như CDI, Spring DI, JSF…Inversion of ControlInversion of Control dịch là hòn đảo ngược tinh chỉnh và điều khiển (hơi nặng nề hiểu)Ý của nó là làm thay đổi luồng điều khiển của ứng dụng. Ví như ở bên trên việc chuyển đổi thông tin trong tệp tin config.properties sẽ làm đổi khác luồng chạy của ứng dụng.Dependency Injection (DI) là gì? Code ví dụ bởi JavaReferences:
https://en.wikipedia.org/wiki/Dependency_injection
https://stackoverflow.com/questions/130794/what-is-dependency-injection
This entry was posted in thiết kế Pattern, FAQ và tagged thiết kế pattern, faq. Bookmark the permalink.