JavaRush /จาวาบล็อก /Random-TH /วิธีง่ายๆ ในการฉีดการพึ่งพา

วิธีง่ายๆ ในการฉีดการพึ่งพา

เผยแพร่ในกลุ่ม
การพึ่งพาการฉีด (DI) ไม่ใช่แนวคิดที่เข้าใจง่าย และการนำไปใช้กับแอปพลิเคชันใหม่หรือที่มีอยู่นั้นยิ่งสร้างความสับสน Jess Smithแสดงให้คุณเห็นถึงวิธีการ dependency insert โดยไม่ต้องใช้คอนเทนเนอร์การฉีดในภาษาการเขียนโปรแกรม C# และ Java วิธีง่ายๆ ในการฉีดการพึ่งพา - 1ในบทความนี้ ฉันจะแสดงให้คุณเห็นถึงวิธีการใช้ Dependency Injection (DI) ในแอปพลิเคชัน .NET และ Java แนวคิดของการพึ่งพาการฉีดได้รับความสนใจจากนักพัฒนาครั้งแรกในปี 2000 เมื่อ Robert Martin เขียนบทความ "หลักการและรูปแบบการออกแบบ" (ต่อมารู้จักกันในชื่อย่อSOLID ) D ใน SOLID หมายถึงการพึ่งพาของการผกผัน (DOI) ซึ่งต่อมากลายเป็นที่รู้จักในชื่อการฉีดการพึ่งพา คำจำกัดความดั้งเดิมและที่พบบ่อยที่สุด: การผกผันการพึ่งพาคือการผกผันของวิธีที่คลาสพื้นฐานจัดการการพึ่งพา บทความต้นฉบับของ Martin ใช้โค้ดต่อไปนี้เพื่อแสดงการพึ่งพาของคลาสCopyในคลาสระดับล่างWritePrinter:
void Copy()
	{
	 int c;
	 while ((c = ReadKeyboard()) != EOF)
		WritePrinter(c);
	}
ปัญหาแรกที่ชัดเจนคือ หากคุณเปลี่ยนรายการพารามิเตอร์หรือประเภทของเมธอดWritePrinterคุณจะต้องใช้การอัปเดตในทุกที่ที่มีการพึ่งพาเมธอดนั้น กระบวนการนี้จะเพิ่มค่าใช้จ่ายในการบำรุงรักษาและอาจเป็นสาเหตุให้เกิดข้อผิดพลาดใหม่ๆ
สนใจอ่านเกี่ยวกับ Java หรือไม่? เข้าร่วม กลุ่ม นักพัฒนา Java !
ปัญหาอีกประการหนึ่ง: คลาส Copy ไม่สามารถนำมาใช้ซ้ำได้อีกต่อไป ตัวอย่างเช่น จะเกิดอะไรขึ้นถ้าคุณต้องการส่งออกอักขระที่ป้อนจากแป้นพิมพ์ไปยังไฟล์แทนที่จะส่งไปยังเครื่องพิมพ์ เมื่อต้องการทำเช่นนี้ คุณสามารถปรับเปลี่ยนคลาสได้Copyดังต่อไปนี้ (ไวยากรณ์ภาษา C++):
void Copy(outputDevice dev)
	{
	int c;
	while ((c = ReadKeyboard()) != EOF)
		if (dev == printer)
			WritePrinter(c);
		else
			WriteDisk(c);
	}
แม้จะมีการแนะนำการพึ่งพาใหม่WriteDiskแต่สถานการณ์ก็ไม่ดีขึ้น (แต่ค่อนข้างแย่ลง) เนื่องจากมีการละเมิดหลักการอื่น: “เอนทิตีซอฟต์แวร์นั่นคือคลาสโมดูลฟังก์ชันและอื่น ๆ ควรเปิดเพื่อขยาย แต่ปิดเพื่อ การปรับเปลี่ยน” Martin อธิบายว่าคำสั่งเงื่อนไข if/else ใหม่เหล่านี้ลดความเสถียรและความยืดหยุ่นของโค้ด วิธีแก้ไขคือการกลับการขึ้นต่อกันเพื่อให้วิธีการเขียนและอ่านขึ้นอยู่กับไฟล์Copy. แทนที่จะเป็นการขึ้นต่อกันแบบ "แตก" พวกมันจะถูกส่งผ่านตัวสร้าง รหัสที่แก้ไขมีลักษณะดังนี้:
class Reader
	{
		public:
		virtual int Read() = 0;
	};
	class Writer
	{
		public:
		virtual void Write(char) = 0;
	};
	void Copy(Reader& r, Writer& w)
	{
		int c;
		while((c=r.Read()) != EOF)
		w.Write(c);
	}
ตอนนี้คลาสCopyสามารถนำกลับมาใช้ใหม่ได้อย่างง่ายดายด้วยการปรับใช้เมธอดคลาสReaderและWriter. คลาสCopyไม่มีข้อมูลใด ๆ เกี่ยวกับโครงสร้างภายในของประเภทReaderและWriterทำให้สามารถนำกลับมาใช้ใหม่ได้ด้วยการใช้งานที่แตกต่างกัน แต่ถ้าทั้งหมดนี้ดูเหมือนเป็น gobbledygook สำหรับคุณ บางทีตัวอย่างต่อไปนี้ใน Java และ C# จะช่วยชี้แจงสถานการณ์ได้

ตัวอย่างใน Java และ C#

เพื่อแสดงให้เห็นความง่ายในการฉีดการขึ้นต่อกันโดยไม่ต้องใช้คอนเทนเนอร์การขึ้นต่อกัน เรามาเริ่มด้วยตัวอย่างง่ายๆ ที่สามารถปรับแต่งเพื่อใช้ได้DIในไม่กี่ขั้นตอน สมมติว่าเรามีคลาสHtmlUserPresentationที่เมื่อมีการเรียกใช้เมธอดของคลาสนั้น จะสร้างอินเทอร์เฟซผู้ใช้ HTML นี่เป็นตัวอย่างง่ายๆ:
HtmlUserPresentation htmlUserPresentation = new HtmlUserPresentation();
String table = htmlUserPresentation.createTable(rowTableVals, "Login Error Status");
โปรเจ็กต์ใดๆ ที่ใช้โค้ดคลาสนี้จะต้องขึ้นอยู่กับคลาส ซึ่งHtmlUserPresentationส่งผลให้เกิดปัญหาด้านการใช้งานและการบำรุงรักษาตามที่อธิบายไว้ข้างต้น การปรับปรุงจะแนะนำตัวเองทันที: การสร้างอินเทอร์เฟซพร้อมลายเซ็นของวิธีการทั้งหมดที่มีอยู่ในคลาสในHtmlUserPresentationปัจจุบัน นี่คือตัวอย่างของอินเทอร์เฟซนี้:
public interface IHtmlUserPresentation {
	String createTable(ArrayList rowVals, String caption);
	String createTableRow(String tableCol);
	// Оставшиеся сигнатуры
}
หลังจากสร้างอินเทอร์เฟซแล้ว เราก็แก้ไขคลาสHtmlUserPresentationเพื่อใช้งาน กลับไปที่การสร้างอินสแตนซ์ของ type HtmlUserPresentationตอนนี้เราสามารถใช้ประเภทอินเทอร์เฟซแทนประเภทพื้นฐานได้:
IHtmlUserPresentation htmlUserPresentation = new HtmlUserPresentation();
String table = htmlUserPresentation.createTable(rowTableVals, "Login Error Status");
การสร้างอินเทอร์เฟซทำให้เราสามารถใช้การใช้งานอื่นๆ ของIHtmlUserPresentation. ตัวอย่างเช่น หากเราต้องการทดสอบประเภทนี้ เราก็สามารถแทนที่ประเภทพื้นฐานHtmlUserPresentationด้วยประเภทอื่นที่เรียกว่า ได้HtmlUserPresentationTestอย่าง ง่ายดาย การเปลี่ยนแปลงที่ทำจนถึงตอนนี้ทำให้โค้ดง่ายต่อการทดสอบ บำรุงรักษา และปรับขนาด แต่ไม่ทำอะไรเลยเพื่อนำมาใช้ซ้ำ เนื่องจากHtmlUserPresentationคลาสทั้งหมดที่ใช้ประเภทนี้ยังคงตระหนักถึงการมีอยู่ของมัน หากต้องการลบการพึ่งพาโดยตรงนี้ คุณสามารถส่งประเภทอินเทอร์เฟซIHtmlUserPresentationไปยังตัวสร้าง (หรือรายการพารามิเตอร์ของวิธีการ) ของคลาสหรือวิธีการที่จะใช้:
public UploadFile(IHtmlUserPresentation htmlUserPresentation)
ขณะนี้ Constructor UploadFileสามารถเข้าถึงฟังก์ชันการทำงานทั้งหมดของ type IHtmlUserPresentationแต่ไม่รู้อะไรเลยเกี่ยวกับโครงสร้างภายในของคลาสที่ใช้อินเทอร์เฟซนี้ UploadFileในบริบทนี้ การแทรกประเภทเกิดขึ้นเมื่ออินสแตน ซ์ของคลาสถูกสร้างขึ้น ประเภทอินเทอร์เฟIHtmlUserPresentationซจะสามารถนำมาใช้ซ้ำได้โดยการส่งต่อการใช้งานที่แตกต่างกันไปยังคลาสหรือวิธีการที่แตกต่างกันซึ่งต้องการฟังก์ชันการทำงานที่แตกต่างกัน

บทสรุปและคำแนะนำในการรวมวัสดุ

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

  • เปลี่ยนคลาสที่สร้างอินสแตนซ์ประเภทฐานนี้โดยตรงเพื่อใช้ประเภทอินเทอร์เฟซใหม่นี้และส่งผ่านรายการตัวสร้างหรือพารามิเตอร์ของวิธีการคลาสที่จะใช้

  • สร้างการใช้งานทดสอบเพื่อทดสอบอินเทอร์เฟซประเภทนี้ เมื่อโค้ดของคุณได้รับการปรับโครงสร้างใหม่แล้วDIคุณจะนำไปใช้ได้ง่ายขึ้น และคุณจะสังเกตได้ว่าแอปพลิเคชันของคุณมีความยืดหยุ่นมากขึ้นเพียงใดในแง่ของการใช้ซ้ำและการบำรุงรักษา
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION