![translation](https://cdn.durumis.com/common/trans.png)
นี่คือโพสต์ที่แปลด้วย AI
[Effective Java] รายการ 5: ใช้การฉีดการพึ่งพาแทนการระบุทรัพยากร
- ภาษาที่เขียน: ภาษาเกาหลี
- •
-
ประเทศอ้างอิง: ทุกประเทศ
- •
- เทคโนโลยีสารสนเทศ
เลือกภาษา
สรุปโดย AI ของ durumis
- หากคลาสขึ้นอยู่กับทรัพยากรอย่างน้อยหนึ่งทรัพยากรภายใน การใช้คลาสยูทิลิตี้แบบคงที่และคลาสซิงเกิลตันไม่ใช่ความคิดที่ดี และการใช้การฉีดการพึ่งพาเป็นที่ต้องการมากกว่า
- การใช้การฉีดการพึ่งพาช่วยปรับปรุงความยืดหยุ่น การนำกลับมาใช้ใหม่และความสะดวกในการทดสอบของคลาส และสามารถ ฉีดทรัพยากรผ่านคอนสตรัคเตอร์ โรงงานคงที่ บิลเดอร์ ฯลฯ
- การฉีดการพึ่งพาสามารถใช้โดยการส่งทรัพยากรเองหรือโรงงานทรัพยากร และสำหรับโปรเจ็กต์ที่มีการพึ่งพาจำนวนมาก การใช้เฟรมเวิร์กการพึ่งพาจะเป็นประโยชน์
หากคลาสขึ้นอยู่กับทรัพยากรภายในอย่างน้อยหนึ่งทรัพยากร และทรัพยากรดังกล่าวมียอดคงเหลือที่มีผลต่อการทำงานของคลาส ไม่ควรใช้ซิงเกิลตันและคลาสยูทิลิตี้แบบคงที่
คลาสไม่ควรสร้างทรัพยากรเหล่านี้โดยตรง แต่ควรส่งผ่านทรัพยากรที่จำเป็นไปยังคอนสตรัคเตอร์ การฉีดการพึ่งพาช่วยปรับปรุงความยืดหยุ่น ความสามารถในการใช้ซ้ำ และความสะดวกในการทดสอบของคลาส
ตัวอย่าง
ตัวอย่างการใช้คลาสยูทิลิตี้แบบคงที่
public class SpellChecker {
private static final Lexicon dictionary = new Lexicon();
private SpellChecker() {
}
public static boolean isValid(String word) {
// ตรรกะที่ใช้พจนานุกรม
}
public static List suggestions(String typo) {
// ตรรกะที่ใช้พจนานุกรม
}
คลาสยูทิลิตี้ดังกล่าวถือว่าใช้พจนานุกรมเพียงหนึ่งพจนานุกรมเท่านั้น แต่ในความเป็นจริง พจนานุกรมจะแยกตามภาษา และอาจมีพจนานุกรมสำหรับคำศัพท์เฉพาะแยกต่างหาก
ตัวอย่างการใช้คลาสซิงเกิลตัน
public class SpellChecker {
private final Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static boolean isValid(String word) {
// ตรรกะที่ใช้พจนานุกรม
}
public static List suggestions(String typo) {
// ตรรกะที่ใช้พจนานุกรม
}
คลาสซิงเกิลตันก็ถือว่าใช้พจนานุกรมเพียงหนึ่งพจนานุกรมเท่านั้น ดังนั้นจึงพบข้อเสียเดียวกันกับข้างต้น
วิธีแก้ปัญหา 1 - ลบคำสำคัญสุดท้ายออกจากฟิลด์
public class SpellChecker {
private Lexicon dictionary = new Lexicon();
public static SpellChecker INSTANCE = new SpellChecker();
private SpellChecker() {
}
public static void changeDictionary(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// ตรรกะที่ใช้พจนานุกรม
}
public static List suggestions(String typo) {
// ตรรกะที่ใช้พจนานุกรม
}
คุณสามารถลบคำสำคัญสุดท้ายออกจากพจนานุกรมของคลาสยูทิลิตี้แบบคงที่หรือคลาสซิงเกิลตัน และออกแบบให้สามารถเปลี่ยนพจนานุกรมเป็นพจนานุกรมอื่นจากภายนอกได้ แต่ใช้วิธีนี้ยาก และอาจทำให้เกิดปัญหาเกี่ยวกับความพร้อมกันในสภาพแวดล้อมแบบมัลติเธรด
วิธีแก้ปัญหา 2 - ใช้การฉีดการพึ่งพา
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
public static boolean isValid(String word) {
// ตรรกะที่ใช้พจนานุกรม
}
public static List suggestions(String typo) {
// ตรรกะที่ใช้พจนานุกรม
}
จากตัวอย่างนี้ เราสามารถเห็นได้ว่าคลาสคงที่และคลาสซิงเกิลตันไม่ควรพึ่งพาทรัพยากรภายใน นั่นหมายความว่าควรได้รับการฉีดจากภายนอก
คลาสที่ใช้การฉีดการพึ่งพามีข้อดีคือสามารถรับประกันความไม่แปรผันได้ด้วยคำสำคัญสุดท้าย และรองรับอินสแตนซ์ทรัพยากรหลายรายการ นอกจากนี้ การฉีดการพึ่งพายังสามารถนำไปใช้ในคอนสตรัคเตอร์ โรงงานแบบคงที่ และตัวสร้างได้
การฉีดการพึ่งพาเป็นเพียงวิธีการส่งผ่านทรัพยากรโดยตรงเท่านั้น แต่บ่อยครั้งที่ใช้การส่งผ่านโรงงานทรัพยากร โรงงานคืออ็อบเจ็กต์ที่สร้างอินสแตนซ์ของประเภทที่ระบุซ้ำ ๆ ทุกครั้งที่เรียก วิธีนี้เรียกว่ารูปแบบโรงงานเมธอด และ Supplier
public static List create(Supplier extends Car> generator) {
...
โดยทั่วไปจะใช้ประเภทไวด์การ์ดแบบจำกัดเพื่อจำกัดพารามิเตอร์ประเภทของโรงงาน วิธีนี้ช่วยให้ไคลเอ็นต์สามารถส่งผ่านโรงงานใด ๆ ที่เป็นประเภทย่อยของประเภทที่ระบุ
การฉีดการพึ่งพาช่วยปรับปรุงความยืดหยุ่นและความสะดวกในการทดสอบ แต่ในโครงการที่มีการพึ่งพาจำนวนมาก ค่าใช้จ่ายจะสูงมาก ในกรณีนี้ คุณสามารถใช้กรอบงานการพึ่งพา (Dagger, Guice, Spring ฯลฯ) เพื่อลดค่าใช้จ่าย