Ошентип... Мурунку сабакта IoC жана DIнин теориялык бөлүгүн кыскача карап чыктык. Ошондой эле биздин долбоор үчүн pom.xml конфигурация файлын орноттук. Бүгүн биз программанын негизги бөлүгүн түзө баштайбыз. Биринчиден, мен IoC / DI жок программаны кантип түзүүнү көрсөтөм. Анан биз түздөн-түз көз карандылыкты өз алдынча киргизген программаны түзөбүз. Башкача айтканда, codeду башкаруу алHowтын колуна өтөт (коркунучтуу угулат). Биз программаны башкарып жатканда, белгилүү бир компания бар деп элестетиңиз. Ал эми компанияда (азыр) эки бөлүм бар: Java өнүктүрүү жана жалдоо бөлүмү. "Java өнүктүрүү бөлүмүн" сүрөттөгөн класстын эки ыкмасы болсун: String getName() - кызматкердин атын кайтаруу, String getJob() - кызматкердин ордун кайтаруу. (Листинг 1)
package org.example;
public class JavaDevelopment {
public String getName(){
return "Alexa";
}
public String getJob(){
return "Middle Java developer";
}
}
Жалдоо бөлүмүн сүрөттөгөн класста кызматкерди кабыл алган киргизүү конструктору жана кызматкерлер жөнүндө маалыматты көрсөткөн void displayInfo() ыкмасы болсун. (Листинг 2)
package org.example;
public class HiringDepartment {
private JavaDevelopment javaDevelopment;
public HiringDepartment(JavaDevelopment javaDevelopment) {
this.javaDevelopment = javaDevelopment;
}
public void displayInfo() {
System.out.println("Name: " + javaDevelopment.getName());
System.out.println("Job: " + javaDevelopment.getJob());
}
}
Ошондой эле негизги бар - бардык бөлүмдөрдү башкарган класс. (3-тизме)
package org.example;
public class Main {
public static void main(String ... args){
JavaDevelopment javaDevelopment = new JavaDevelopment();
HiringDepartment hiringDepartment = new HiringDepartment(javaDevelopment);
hiringDepartment.displayInfo();
}
}
Азырынча стабилдүүлүк. Негизги классты иштеткенде биз төмөнкү натыйжаны алабыз:
Name: Alexa
Job: Middle Java developer
Эми компания мыкты иштеп жатат деп элестетип көрөлү. Ошондуктан, алар өздөрүнүн ишмердүүлүгүнүн чөйрөсүн кеңейтүүнү чечишти жана Python өнүктүрүү бөлүмүн ачышты. Бул жерде суроо туулат: Бул бөлүмдү программалык деңгээлде кантип сүрөттөсө болот? Жооп: Сиз бул бөлүмдү сүрөттөшүңүз керек болгон жерде "көчүрүп, чапташыңыз" керек (эски жакшы ыкма🙃). Биринчиден, "Питонисттер" бөлүмүн сүрөттөгөн класстын өзүн түзөлү. (4-листинг)
package org.example;
public class PythonDevelopment {
public String getName(){
return "Mike";
}
public String getJob(){
return "Middle Python developer";
}
}
Анан аны жалдоо департаментине өткөрүп беребиз. Ал эми HiringDepartment бул бөлүм жөнүндө эч нерсе айтпайт. Ошондуктан, сиз PythonDevelopment классынын жаңы an objectин жана Python иштеп чыгуучуларын кабыл алган конструктор түзүшүңүз керек болот. Ошондой эле маалыматты туура көрсөтүү үчүн displayInfo() ыкмасын өзгөртүүгө туура келет. (5-тизме)
package org.example;
public class HiringDepartment {
private JavaDevelopment javaDevelopment;
public HiringDepartment(JavaDevelopment javaDevelopment) {
this.javaDevelopment = javaDevelopment;
}
//Тут создается отдел найма для Python - разработчиков
private PythonDevelopment pythonDevelopment;
public HiringDepartment(PythonDevelopment pythonDevelopment) {
this.pythonDevelopment = pythonDevelopment;
}
//Тогда придется изменить метод displayInfo()
public void displayInfo() {
if(javaDevelopment != null) {
System.out.println("Name: " + javaDevelopment.getName());
System.out.println("Job: " + javaDevelopment.getJob());
} else if (pythonDevelopment != null){
System.out.println("Name: " + pythonDevelopment.getName());
System.out.println("Job: " + pythonDevelopment.getJob());
}
}
}
Көрүнүп тургандай, codeдун көлөмү эки эсе көбөйдү, же андан да көп. Коддун чоң көлөмү менен анын окулушу төмөндөйт. Эң жаманы, биз бардык an objectтерди кол менен түзүп, бири-биринен өтө көз каранды класстарды жасайбыз. Макул, биз буга макул болдук. Алар жөн гана бир бөлүмдү сүрөттөп беришти. Биз мындан эч нерсе жоготпойбуз. Мейли, башка бөлүмдү кошсок кандай болот? Эки болсочу? Үч? Бирок эч ким «кен казууга жана мал жаюуга» тыюу салган эмес. Ооба, “Кен жана жайытка” эч ким тыюу салган эмес, бирок бул профессионалдуу эмес. Тыж — программист. Жана бул жерде сиз DI колдоно аласыз. Башкача айтканда, биз класстык деңгээлде эмес, интерфейстик деңгээлде иштейбиз. Эми биздин an objectтердин абалы интерфейстерде сакталат. Ошентип, класстар ортосундагы көз карандылык минималдуу болот. Бул үчүн, биз алгач Кызматкерди сүрөттөөнүн эки ыкмасы бар Өнүктүрүү интерфейсин түзөбүз. (Листинг 6)
package org.example;
public interface Development {
String getName();
String getJob();
}
Анда JavaDevelopment жана PythonDevelopment эки классы бул интерфейстен ишке ашырсын (мурас алсын) жана String getName() жана String getJob() ыкмаларын жокко чыгарсын. (Листинг 7, 8)
package org.example;
public class JavaDevelopment implements Development {
@Override
public String getName(){
return "Alexa";
}
@Override
public String getJob(){
return "Middle Java developer";
}
}
package org.example;
public class PythonDevelopment implements Development {
@Override
public String getName(){
return "Mike";
}
@Override
public String getJob(){
return "Middle Python developer";
}
}
Анда HiringDepartment классында сиз жөн гана Development түрүндөгү интерфейс an objectисин аныктай аласыз жана ошондой эле мындай an objectти конструкторго өткөрүп бере аласыз. (9-листинг)
package org.example;
public class HiringDepartment {
private Development development; //Определяем интерфейс
//Конструктор принимает an object интерфейса
public HiringDepartment(Development development){
this.development = development;
}
public void displayInfo(){
System.out.println("Name: " + development.getName());
System.out.println("Job: " + development.getJob());
}
}
Көрүнүп тургандай, codeдун көлөмү азайды. Эң негизгиси, көз карандылык минималдуу болду. Бул an objectтер үчүн баалуулуктар жана көз карандылыктар чындыгында кантип ишке ашырылат? Көз карандылыкты киргизүүнүн үч жолу бар:
- Конструкторду колдонуу
- Жөндөөчүлөрдү колдонуу
- Autowiring (автоматтык түрдө туташтыруу)
- XML файлдарын колдонуу (эскирген ыкма)
- Аннотацияларды + XML файлдарын колдонуу (Заманбап ыкма)
- Java codeун колдонуу (Заманбап жол)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="javaDeveloper" class="org.example.JavaDevelopment"/>
<bean id="pythonDeveloper" class="org.example.PythonDevelopment"/>
<bean id="hiringDepartment" class="org.example.HiringDepartment">
<constructor-arg ref="javaDeveloper"/>
</bean>
</beans>
Эми, ирети менен. Коддун биринчи сегиз саптары биз үчүн кызык эмес, алар демейки. Сиз аларды жөн гана көчүрө аласыз. <bean> </bean> теги Жазгы буурчакты аныктайт. Буурчак - бул Spring контейнери тарабынан түзүлгөн жана башкарылуучу an object. Жөнөкөй сөз менен айтканда, Spring контейнеринин өзү биз үчүн жаңы класс an objectин түзөт (мисалы: JavaDevelopment javaDevelopment = new JavaDevelopment();). Бул тегдин ичинде id жана класс атрибуттары бар. id буурчактын атын аныктайт. Бул id an objectке кирүү үчүн колдонулат. Бул Java классындагы an objectтин атына барабар. класс - биздин буурчак (an object) байланган класстын атын аныктайт. Сиз класска толук жолду көрсөтүшүңүз керек. Ишке алуу департаментине көңүл буруңуз. Бул буурчактын ичинде дагы бир <constructor-arg ref="javaDeveloper"/> теги бар. Бул жерде көз карандылык инъекциясы пайда болот (биздин учурда конструктордун жардамы менен инъекция). <constructor-arg> - Жазга Spring контейнери фасоль атрибутунда аныкталган класс конструкторунан көз карандылыктарды издөө керектигин айтат. Жана кайсы an object менен байланыштыруу керектиги ref атрибуту менен аныкталат , <constructor-arg> теги. ref - байланыша турган буурчактын идентификаторун көрсөтөт. Эгерде ref'де javaDeveloper ордуна биз id pythonDeveloper көрсөтсөк, анда байланыш PythonDevelopmen классы менен ишке ашат. Эми биз Негизги классты сүрөттөшүбүз керек. Бул төмөнкүдөй болот: (Listing11)
package org.example;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String ... args){
//Определяем контекст файл в котором содержатся прописанные нами бины
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//Получем бины, которые были определены в файле applicationContext.xml
HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);
hiringDepartment.displayInfo();
context.close(); //Контекст всегда должен закрываться
}
}
Бул жерде эмне бар?
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Бул сап Негизги классты биздин буурчактарды сүрөттөгөн .xml файлына байланыштырат. Конструкторго берилген маани .xml файлынын атына дал келиши керек. (Биздин учурда applicationContext.xml).
HiringDepartment hiringDepartment = context.getBean("hiringDepartment", HiringDepartment.class);
HiringDepartment классынын төө буурчакты (an objectисин) алгыбыз келгенин көрсөтөт. Биринчи аргумент биз xml файлында жазган буурчак идентификаторун көрсөтөт. Экинчи аргумент биз байланышкыбыз келген классты көрсөтөт. Бул процесс рефлексия деп аталат .
hiringDepartment.displayInfo();
context.close(); //Контекст всегда должен закрываться
Бул жерде биз HiringDepartment классынын ыкмасын оңой алабыз. Объекттерди алуу үчүн биз new ачкыч сөзүн колдонгон жокпуз жана JavaDevelopment же PythonDevelopment түрүндөгү көз каранды an objectтерди эч жерде аныктаган жокпуз. Алар жөн гана applicationContext.xml файлында сүрөттөлгөн. Акыркы сапка да көңүл буруңуз. Өчүрүүдөн мурун контекстти дайыма жабуу керек. Болбосо, ресурстар бошотулbyte жана эс тутумдун агып кетиши же программанын туура эмес иштеши мүмкүн. Суроолоруңуз же сунуштарыңыз болсо комментарийге жазыңыз, мен сөзсүз жооп берем. Көңүл бурганыңыздарга рахмат. Булак codeу шилтемедеги My GitHub Cart Курстун мазмуну Улантылат...
GO TO FULL VERSION