ชั้นบริการควรตรวจจับข้อยกเว้น dao ทั้งหมดและตัดเป็นข้อยกเว้นบริการหรือไม่


23

ฉันมีเว็บแอพ Spring สามชั้น: dao, บริการและผู้ควบคุม คอนโทรลเลอร์ไม่เคยเรียก dao โดยตรงมันทำผ่านเลเยอร์บริการ ตอนนี้เวลาส่วนใหญ่หากมีข้อยกเว้น dao (รันไทม์) ที่ไม่ได้จัดการมันจะถูกจับโดย JSP แสดงข้อความข้อผิดพลาดให้กับผู้ใช้ ชั้นบริการควรตรวจจับข้อยกเว้น dao ทั้งหมดและตัดเป็นข้อยกเว้นบริการหรือไม่

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

สมมติว่า ServiceException นั้นเป็น runtime เช่นกัน มีความแตกต่างใด ๆ เพียงแค่โยน DataAccessException แทนที่จะเป็น ServiceException หรือไม่ ฉันแค่คิดว่าเลเยอร์การนำเสนอไม่ควรทราบเกี่ยวกับข้อยกเว้นการเข้าถึงข้อมูล แต่ฉันไม่เห็นจุดที่จับข้อยกเว้นที่ไม่สามารถกู้คืนได้เพื่อห่อไว้

คำตอบ:


18

ฉันคิดว่าปัจจัยสำคัญคือลูกค้าของคุณคือใคร

หากเลเยอร์บริการของคุณเป็นเพียงแค่ขอบเขตสถาปัตยกรรมระหว่างเลเยอร์ในโครงการของคุณเองและเซอร์วิสลูกค้าอยู่ในขอบเขตความน่าเชื่อถือที่เหมือนกันดังนั้นจึงเป็นการผ่อนคลายเพื่อสิ่งต่าง ๆ และปล่อยให้ข้อยกเว้นที่ไม่ถูกตรวจสอบ

อย่างไรก็ตามสำหรับรหัสสาธารณะ บริการที่ถูกใช้โดยบุคคลที่สามหรือลูกค้าฉันคิดว่ามันสะอาดกว่าที่จะห่อข้อยกเว้นที่ไม่ได้ตรวจสอบด้วยข้อยกเว้นเชิงบริการส่วนใหญ่สำหรับข้อกังวลด้านความปลอดภัยอันดับสองสำหรับข้อต่อหลวมและสะอาดนามธรรม

ข้อยกเว้นเลเยอร์ข้อมูลไม่ควรทำให้ผู้ใช้ปลายทางของเว็บแอปพลิเคชันเข้าถึงผู้ใช้ปลายทางได้โดยตรง มันอาจมีข้อมูลภายในเกี่ยวกับสคีมาของคุณแบบสอบถามข้อมูลหมายเลขบรรทัดชื่อตัวแปรหรือฟังก์ชั่น ฯลฯ ข้อยกเว้นของผู้ใช้สามารถถูกทำให้สะอาดได้ในการตั้งค่าที่ปลอดภัย

ไคลเอ็นต์บริการภายนอกไม่เกี่ยวข้องกับรายละเอียดการใช้งานของคุณและไม่สามารถจัดการกับข้อยกเว้นที่ไม่ได้ตรวจสอบได้เนื่องจากเป็นปัญหาด้านสิ่งแวดล้อมหรือปัญหา ในแอปพลิเคชันที่ปลอดภัยข้อผิดพลาดของฐานข้อมูลนั้นไม่ปลอดภัยพอที่จะเผยแพร่OracleException - ORA-01234 - ...ซึ่งอาจเป็นตารางที่ 3 ที่ถูกแทรก ลูกค้าควรได้รับอนุญาตให้จัดการกับข้อยกเว้นที่ตรวจสอบ / คาดว่าจะสามารถจัดการได้และปฏิบัติต่อทุกสิ่งเป็นรายงานบั๊กที่เป็นไปได้ สัญญาการให้บริการของคุณควรเป็นสิ่งที่เป็นนามธรรมที่สอดคล้องและเป็นธุรกรรม หากไม่สามารถทำอะไรเกี่ยวกับข้อยกเว้นได้สิ่งที่มีประโยชน์เพียงอย่างเดียวคือให้รายงานข้อผิดพลาดแก่คุณ. คุณมีความสามารถในการบันทึกข้อยกเว้นแล้วเหตุใดจึงทำให้ผู้ใช้ปลายทางของคุณต้องมีรายละเอียด แอปของคุณสามารถตรวจสอบได้เพื่อให้คุณทราบเกี่ยวกับข้อยกเว้นที่ไม่ได้ตรวจสอบก่อนที่ผู้ใช้จะรายงาน

มันไม่เคยโอเคที่จะกินข้อยกเว้นหรือฉันเป็นแฟนของข้อยกเว้นที่ตรวจสอบ แต่ฉันชอบที่จะมีแผนที่เหมาะสมกับลักษณะของผลิตภัณฑ์โดยรวม


13

ไม่คุณไม่ควรห่อ DAO ข้อยกเว้นในเว็บแอปพลิเคชัน

มันมีเสียงรบกวนมากในรหัสเพื่อผลประโยชน์เป็นศูนย์ ข้อยกเว้น DAO เป็นข้อยกเว้นที่ไม่ได้ตรวจสอบเพื่อเหตุผลที่ดี รหัสแอปพลิเคชันไม่สามารถทำสิ่งใดที่มีประโยชน์ในการกู้คืนจากข้อยกเว้น DAO ปัญหาที่แท้จริงอยู่ที่นี่:

... มันจะถูกจับโดย JSP แสดงข้อความข้อผิดพลาดให้กับผู้ใช้

แก้ไขปัญหานี้ได้ในที่เดียวแทนที่จะสร้างความสับสนให้กับฐานรหัสทั้งหมด

คุณสามารถควบคุมวิธีการแสดงข้อยกเว้นที่ไม่ได้ตรวจสอบกับผู้ใช้ ข้อยกเว้นที่ไม่ได้ตรวจสอบเกิดจากข้อผิดพลาดของแอปพลิเคชันหรือความล้มเหลวในระบบพื้นฐาน ไม่มีเหตุผลที่จะให้ข้อมูลกับผู้ใช้เกี่ยวกับสาเหตุที่คำขอของเขาไม่สามารถให้บริการได้ ไม่มีสิ่งใดที่ผู้ใช้สามารถทำได้ สิ่งที่คุณควรทำคือแสดงหน้าข้อผิดพลาดที่เป็นมิตร

หมายเหตุ: หากคุณพบว่าตัวเองกำลังเขียนโค้ดที่น่าเบื่อมากเช่นการสร้างกลุ่มบล็อกที่ง่าย ๆ เพียงแค่ห่อและโยนใหม่ก็จะมีทางออกที่ดีกว่า


ขอบคุณสำหรับคำตอบ. และใช่ jsp แสดงข้อความที่กำหนดเอง: "อ๊ะเกิดข้อผิดพลาดบางอย่าง" จะไม่แสดงข้อมูลใด ๆ เกี่ยวกับข้อยกเว้น
Oscar

7

หนึ่งเหตุผลหลักที่จะใช้ข้อยกเว้นการตัดคือการป้องกันรหัสในชั้นธุรกิจจากต้องรู้เกี่ยวกับทุกข้อยกเว้นในระบบ มีสองเหตุผลหลักสำหรับสิ่งนี้:

  • Consistency: ข้อยกเว้นที่ประกาศรวมไว้ที่ด้านบนของ call stack หากคุณไม่ได้ห่อข้อยกเว้น แต่ผ่านพวกเขาโดยประกาศวิธีการของคุณที่จะโยนพวกเขาคุณอาจจบลงด้วยวิธีการระดับบนสุดที่ประกาศข้อยกเว้นที่แตกต่างกันมากมาย การประกาศข้อยกเว้นเหล่านี้ทั้งหมดในแต่ละวิธีการสำรองสแตกการโทรจะน่าเบื่อ

  • การห่อหุ้ม: คุณอาจไม่ต้องการให้องค์ประกอบระดับบนสุดของคุณรู้อะไรเกี่ยวกับองค์ประกอบระดับล่างสุดหรือข้อยกเว้นที่พวกเขาโยน ตัวอย่างเช่นวัตถุประสงค์ของอินเทอร์เฟซและการใช้งาน DAO คือการสรุปรายละเอียดของการเข้าถึงข้อมูลให้ห่างจากแอปพลิเคชั่นที่เหลือ ตอนนี้ถ้าวิธี DAO ของคุณโยน SQLException แล้วรหัสที่ใช้ DAO จะต้องจับพวกเขา ถ้าคุณเปลี่ยนเป็นการใช้งานที่อ่านข้อมูลจากบริการเว็บแทนจากฐานข้อมูล จากนั้นคุณวิธีการ DAO จะต้องโยนทั้ง RemoteException และ SQLException และถ้าคุณมี DAO ที่อ่านข้อมูลจากไฟล์คุณจะต้องโยน IOException ด้วย นั่นคือข้อยกเว้นที่แตกต่างกันสามข้อแต่ละข้อผูกมัดกับการใช้งาน DAO ของตนเอง

ดังนั้นในระยะสั้นคำตอบคือใช่!


3
การใช้งาน JPA (เช่น Hibernate) มีข้อยกเว้นที่ไม่ได้ตรวจสอบ พวกเขาไม่จำเป็นต้องประกาศหรือจับ
kevin cline
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.