2012-02-13 7 views
19

Nếu lớp Dao của tôi ném ngoại lệ cụ thể cho Dao, thì việc xử lý chúng trong lớp dịch vụ của tôi có gây ra sự lo ngại không? Nếu có, thì tôi có nên làm cho các ngoại lệ chung chung và độc lập với bất kỳ lớp nào để giải quyết nó, hoặc có cách nào khác không?Xử lý trường hợp ngoại lệ Dao trong lớp dịch vụ

Câu hỏi tương tự cũng áp dụng cho các ngoại lệ xử lý lớp UI được lớp dịch vụ đưa ra.

Trả lời

27

Khi tạo một ứng dụng lớp, luôn có một lớp người dùng và một lớp được sử dụng khác. Đối với trường hợp này, lớp UI -> sử dụng lớp dịch vụ -> sử dụng lớp DAO.

Bây giờ, nó rất chủ quan và cởi mở để diễn giải. Nhưng mục tiêu phải là mức độ tách tốt. Để đạt được điều này, một cách thoát là xác định các ngoại lệ cụ thể của lớp chung nói PersistentException, ServiceException vv Các ngoại lệ này sẽ bao bọc ngoại lệ cụ thể của lớp thực tế.

Ví dụ nói nếu có một số lỗi về phía cơ sở dữ liệu (vi phạm chế vv), quấn rằng trong PersistentException và để cho lớp dịch vụ xử lý đó (như thế nào để truyền đạt này đến lớp UI trong một cách chung chung)

Bây giờ kể từ khi hội nhập giữa lớp dịch vụ và lớp DAO là hợp đồng (dựa trên giao diện), lớp DAO là miễn phí để thay đổi việc thực hiện bất cứ điều gì miễn là nó tuân theo hợp đồng giao diện . Vì vậy, nếu bạn thay đổi triển khai thực hiện ném một số ngoại lệ mới, những ngoại lệ mới này có thể được gói trong lớp PersistentExceptionLớp dịch vụ vẫn không bị ảnh hưởng.

+0

bạn có thể vui lòng cung cấp một ví dụ về điều này ... cảm ơn bạn –

+0

Tôi đã viết một bài đăng về điều này đôi khi trở lại. Vui lòng kiểm tra https://dzone.com/articles/quotdecouplingquot-the-exception-puzzle – Santosh

+0

ok, cảm ơn, tôi sẽ trải qua –

0

Câu hỏi hay .. !! Xử lý ngoại lệ ở lớp UI (ví dụ, lớp hành động nếu bạn đang sử dụng thanh chống) là cách tiếp cận tốt. Thực hiện chung ngoại lệ không phải là cách hay để giải quyết vấn đề này. Mỗi lớp nên có tuy nhiên ngoại lệ cụ thể của họ như là chung chung. ví dụ, lớp DAO có thể có các trình xử lý ngoại lệ tùy chỉnh như DavaSavingException, IOException, vv ..

Vì vậy, cách tiếp cận là ném ngoại lệ từ DAO sang lớp dịch vụ và lại ném nó vào lớp UI.

Tuy nhiên, mọi thứ quá ngoại giao tùy theo ứng dụng/nhu cầu của bạn.

+0

cảm ơn cho câu trả lời, nhưng tôi vẫn không rõ ràng nếu xử lý ngoại lệ Đạo trong lớp dịch vụ cấu thành một sự rò rỉ của mối quan tâm và nếu có, sau đó làm thế nào để xử lý đó. – shrini1000

+0

'rò rỉ mối quan tâm 'có nghĩa là ?? DAO ngoại lệ cụ thể mặc dù xử lý trong lớp dịch vụ hoặc DAO lớp chính nó có thể không phải là một mối quan tâm. – Ved

+0

Điều tôi ngụ ý là: Ngoại lệ Đạo có thể chứa trong đó thông tin cụ thể cho vấn đề Đạo; bây giờ nếu lớp dịch vụ đã xử lý thông tin này để xử lý các ngoại lệ, thì lớp dịch vụ sẽ không được kết hợp chặt chẽ với lớp Dao không? như vậy sẽ không tạo thành một sự rò rỉ của mối quan tâm từ Dao đến dịch vụ? – shrini1000

8

Có. một ý tưởng hay là tạo ra các ngoại lệ độc lập của riêng bạn cho mỗi lớp.

Ví dụ, nếu bạn đang sử dụng một triển khai DAO cụ thể, bạn nên bọc ngoại lệ cụ thể thực hiện cho ngoại lệ chung của riêng bạn và ném nó về phía trước để Service Layer. Tuy nhiên, bạn cần phải nhạy cảm trong việc tạo hệ thống phân cấp ngoại lệ của riêng mình sao cho nó không phải là chi phí phát triển ứng dụng cũng như khả năng duy trì thông tin được yêu cầu trong Lớp dịch vụ. Hầu hết các lần, mã lỗi tùy chỉnh với ngoại lệ chung đủ điều này.

Một cái gì đó như thế này có thể được sử dụng để mô phỏng ngoại lệ cụ thể thực hiện và ném vào lớp dịch vụ.

class AppDAOException extends Exception { 
    public final static int _FAIL_TO_INSERT = 1; 
    public final static int _UPDATE_FAILED = 2; 
    public final static int _SQL_ERROR = 3; 
    private int errorCode; 
    public AppDAOException(int errorCode) { 
     this.errorCode = errorCode; 
    } 
    public getErrorCode() { 
     return errorCode; 
    } 
} 

Throwing từ thực hiện DAO:

try { 
    //code here 
} catch (some.impl.SQLSyntaxException e) { 
    throw new AppDAOException (AppDAOException._SQL_ERROR); 
} 

Về rò rỉ quan tâm: Bạn có thể không muốn lớp dịch vụ của bạn phải bận tâm về tất cả các trường hợp ngoại lệ - chẳng hạn như:

} catch(NoRowExistsException e) { 
    return null; 
} finally { 
    //release resources 
} 

Vì vậy, cuộc gọi phải được thực hiện dựa trên nhu cầu ứng dụng.

6

lớp DAO của bạn đã bị rò rỉ vào lớp dịch vụ khi bạn làm các hoạt động như:

userDAO.persist(user); 

Exceptions, là một phần của API giống như hoạt động cần được xem xét trong cùng một cách.

try { 
    userDAO.persist(user); 
} catch (DAOException e) { 
    // looks fine to me 
} 

rò rỉ có thể xảy ra với trường hợp ngoại lệ thời gian chạy, hoặc khi bạn rethrow ngoại lệ

try { 
    userDAO.persist(user); 
} catch (SQLException e) { 
    // sql implementation exposed 
} 

Nhưng ngay cả điều này nghe có vẻ tốt hơn so với trường hợp ngoại lệ "lớp độc lập"