JavaRush /Java блогы /Random-KK /Тәуелділіктерді енгізудің оңай жолы

Тәуелділіктерді енгізудің оңай жолы

Топта жарияланған
Тәуелділік инъекциясы (DI) түсіну оңай ұғым емес және оны жаңа немесе бар қолданбаларға қолдану одан да шатастырады. Джесс Смит C# және Java бағдарламалау тілдерінде инъекциялық контейнерсіз тәуелділік инъекциясын қалай жасау керектігін көрсетеді. Тәуелділік инъекциясының қарапайым тәсілі - 1Бұл мақалада мен .NET және Java қолданбаларында тәуелділік инъекциясын (DI) қалай енгізу керектігін көрсетемін. Тәуелділік инъекциясының тұжырымдамасы алғаш рет әзірлеушілердің назарына 2000 жылы Роберт Мартин «Дизайн принциптері мен үлгілері» (кейінірек SOLID аббревиатурасымен белгілі ) мақаласын жазған кезде келді. SOLID ішіндегі D кейінірек тәуелділік инъекциясы ретінде белгілі болған инversionға тәуелділікке (DOI) қатысты. Түпнұсқа және ең кең тараған анықтама: тәуелділік инversionсы - негізгі класс тәуелділіктерді басқару тәсілінің инversionсы. CopyМартиннің бастапқы мақаласы төменгі деңгейдегі сыныпқа сыныптың тәуелділігін көрсету үшін келесі codeты пайдаланды WritePrinter:
void Copy()
	{
	 int c;
	 while ((c = ReadKeyboard()) != EOF)
		WritePrinter(c);
	}
Бірінші айқын мәселе, егер сіз әдістің параметрлер тізімін немесе түрлерін өзгертсеңіз WritePrinter, сол әдіске тәуелділік бар жерде жаңартуларды енгізу қажет. Бұл процесс техникалық қызмет көрсету шығындарын арттырады және жаңа қателердің ықтимал көзі болып табылады.
Java туралы оқығыңыз келе ме? Java әзірлеушілер тобына қосылыңыз !
Тағы бір мәселе: Көшіру сыныбы енді қайта пайдалануға ықтимал үміткер емес. Мысалы, пернетақтадан енгізілген таңбаларды принтерге емес, файлға шығару қажет болса ше? Ол үшін сыныпты Copyкелесідей өзгертуге болады (C++ тілінің синтаксисі):
void Copy(outputDevice dev)
	{
	int c;
	while ((c = ReadKeyboard()) != EOF)
		if (dev == printer)
			WritePrinter(c);
		else
			WriteDisk(c);
	}
Жаңа тәуелділіктің енгізілгеніне қарамастан WriteDisk, жағдай жақсармады (керісінше нашарлады), себебі басқа принцип бұзылды: «бағдарламалық қамтамасыз ету нысандары, яғни сыныптар, модульдер, функциялар және т.б. кеңейту үшін ашық, бірақ жабық болуы керек. өзгерту». Мартин бұл жаңа шартты if/else мәлімдемелері codeтың тұрақтылығы мен икемділігін төмендететінін түсіндіреді. Шешім - жазу және оқу әдістері тәуелді болу үшін тәуелділіктерді инversionлау Copy. «Тәуелділіктердің» орнына олар конструктор арқылы өтеді. Өзгертілген code келесідей көрінеді:
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бұл оларды әртүрлі іске асырулармен қайта пайдалануға мүмкіндік береді. Бірақ егер мұның бәрі сізге қандай да бір құмарлық сияқты көрінсе, Java және C# тіліндегі келесі мысалдар жағдайды түсіндіреді.

Java және C# тіліндегі мысал

DIТәуелділік контейнерінсіз тәуелділік инъекциясының қарапайымдылығын көрсету үшін бірнеше қадамда пайдалану үшін теңшеуге болатын қарапайым мысалдан бастайық . Бізде HtmlUserPresentationоның әдістері шақырылған кезде HTML пайдаланушы интерфейсін жасайтын класс бар делік. Міне, қарапайым мысал:
HtmlUserPresentation htmlUserPresentation = new HtmlUserPresentation();
String table = htmlUserPresentation.createTable(rowTableVals, "Login Error Status");
Осы сынып codeын пайдаланатын кез келген жобаның классқа тәуелділігі болады HtmlUserPresentation, нәтижесінде жоғарыда сипатталған қолайлылық және техникалық қызмет көрсету мәселелері туындайды. Жақсарту бірден өзін ұсынады: қазіргі уақытта сыныпта қол жетімді барлық әдістердің қолтаңбалары бар интерфейс жасау HtmlUserPresentation. Міне, осы интерфейстің мысалы:
public interface IHtmlUserPresentation {
	String createTable(ArrayList rowVals, String caption);
	String createTableRow(String tableCol);
	// Оставшиеся сигнатуры
}
Интерфейсті жасағаннан кейін HtmlUserPresentationоны пайдалану үшін классты өзгертеміз. Түрді құруға оралсақ HtmlUserPresentation, енді біз негізгі түрдің орнына интерфейс түрін пайдалана аламыз:
IHtmlUserPresentation htmlUserPresentation = new HtmlUserPresentation();
String table = htmlUserPresentation.createTable(rowTableVals, "Login Error Status");
Интерфейс құру бізге басқа іске асыруларды оңай пайдалануға мүмкіндік береді IHtmlUserPresentation. Мысалы, егер біз осы түрді сынағымыз келсе, біз негізгі түрді HtmlUserPresentationдеп аталатын басқа түрмен оңай ауыстыра аламыз HtmlUserPresentationTest. Осы уақытқа дейін енгізілген өзгертулер codeты тексеруді, қолдауды және масштабтауды жеңілдетеді, бірақ қайта пайдалану үшін ештеңе жасамайды, өйткені HtmlUserPresentationтүрін пайдаланатын барлық сыныптар әлі де оның бар екенін біледі. IHtmlUserPresentationБұл тікелей тәуелділікті жою үшін интерфейс түрін оны пайдаланатын сыныптың немесе әдістің конструкторына (немесе әдіс параметрлерінің тізіміне) беруге болады :
public UploadFile(IHtmlUserPresentation htmlUserPresentation)
Конструктор UploadFileенді түрдегі барлық функцияларға қол жеткізе алады IHtmlUserPresentation, бірақ осы интерфейсті жүзеге асыратын класстың ішкі құрылымы туралы ештеңе білмейді. Бұл контексте типті енгізу сынып данасы жасалған кезде орын алады UploadFile. Интерфейс түрі IHtmlUserPresentationәртүрлі енгізулерді әртүрлі сыныптарға немесе әртүрлі функционалдылықты қажет ететін әдістерге беру арқылы қайта пайдалануға болады.

Қорытынды және материалды бекіту бойынша ұсыныстар

Тәуелділік инъекциясы туралы білдіңіз және олардың біреуі мақсатты түрдің функционалдығына қол жеткізу үшін екіншісін іске қосқанда, сыныптар бір-біріне тікелей тәуелді деп айтылады. Екі түр арасындағы тікелей тәуелділікті ажырату үшін интерфейсті жасау керек. Интерфейс түрге қажетті функционалдылықтың контекстіне байланысты әртүрлі іске асыруларды қосу мүмкіндігін береді. Интерфейс түрін сынып конструкторына немесе әдіске беру арқылы функционалдылықты қажет ететін сынып/әдіс интерфейсті жүзеге асыратын түр туралы ешқандай мәліметтерді білмейді. Осыған байланысты интерфейс түрін ұқсас, бірақ бірдей емес әрекетті қажет ететін әртүрлі сыныптарда қайта пайдалануға болады.
  • Тәуелділік инъекциясымен тәжірибе жасау үшін бір немесе бірнеше қолданбалардағы codeты қарап шығыңыз және көп пайдаланылатын негізгі түрді интерфейске түрлендіруге тырысыңыз.

  • Осы жаңа интерфейс түрін пайдалану үшін осы негізгі түрді тікелей жасайтын сыныптарды өзгертіңіз және оны пайдаланатын сынып әдісінің конструкторы немесе параметрлер тізімі арқылы өткізіңіз.

  • Осы интерфейс түрін тексеру үшін сынақты іске қосыңыз. Кодыңыз қайта өңделгеннен кейін DIоны іске асыру оңайырақ болады және қайта пайдалану және техникалық қызмет көрсету тұрғысынан қолданбаңыздың қаншалықты икемді болатынын байқайсыз.
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION