පරායත්ත එන්නත් කිරීම පිළිබඳ නිශ්චිත ප්රශ්න සමඟ දැනටමත් ප්රශ්න කිහිපයක් පළ කර ඇත , එය භාවිතා කළ යුත්තේ කවදාද සහ ඒ සඳහා කුමන රාමු තිබේද යන්න. කෙසේවෙතත්,
පරායත්ත එන්නත් කිරීම යනු කුමක්ද සහ එය භාවිතා කළ යුත්තේ කවදාද / ඇයි?
පරායත්ත එන්නත් කිරීම පිළිබඳ නිශ්චිත ප්රශ්න සමඟ දැනටමත් ප්රශ්න කිහිපයක් පළ කර ඇත , එය භාවිතා කළ යුත්තේ කවදාද සහ ඒ සඳහා කුමන රාමු තිබේද යන්න. කෙසේවෙතත්,
පරායත්ත එන්නත් කිරීම යනු කුමක්ද සහ එය භාවිතා කළ යුත්තේ කවදාද / ඇයි?
Answers:
පරායත්ත එන්නත් කිරීම යනු වෙනත් වස්තූන් හෝ රාමුවකට යැපීම (පරායත්ත ඉන්ජෙක්ටර්) ය.
යැපුම් එන්නත් කිරීම පරීක්ෂා කිරීම පහසු කරයි. එන්නත් කිරීම ඉදිකිරීම්කරු හරහා කළ හැකිය .
SomeClass()
එහි ඉදිකිරීම්කරු පහත පරිදි වේ:
public SomeClass() {
myObject = Factory.getObject();
}
ගැටලුව : myObject
තැටි ප්රවේශය හෝ ජාල ප්රවේශය වැනි සංකීර්ණ කාර්යයන් ඇතුළත් නම් , ඒකක පරීක්ෂණයක් කිරීම දුෂ්කර ය SomeClass()
. වැඩසටහන්කරුවන් නිග්රහ කිරීමට ඇති myObject
හා ශක්තිය අල්ලා කර්මාන්ත ඇමතුම.
විකල්ප විසඳුම :
myObject
ඉදිකිරීම්කරුට තර්කයක් ලෙස සම්මත වීමpublic SomeClass (MyClass myObject) {
this.myObject = myObject;
}
myObject
පරීක්ෂා කිරීම පහසු කරන කෙලින්ම සම්මත කළ හැකිය.
පරායත්ත එන්නත් කිරීමකින් තොරව ඒකක පරීක්ෂණයේදී සංරචක හුදකලා කිරීම දුෂ්කර ය.
2013 දී, මම මෙම පිළිතුර ලියන විට, මෙය ගූගල් පරීක්ෂණ බ්ලොග් අඩවියේ ප්රධාන තේමාවක් විය . ක්රමලේඛකයන්ට සෑම විටම ඔවුන්ගේ ධාවන කාල සැලසුමේ අමතර නම්යශීලී බවක් අවශ්ය නොවන බැවින් එය මට ඇති ලොකුම වාසියයි (නිදසුනක් ලෙස සේවා ස්ථානගත කිරීම හෝ ඒ හා සමාන රටාවන් සඳහා). ක්රමලේඛකයන්ට බොහෝ විට පරීක්ෂණ අතරතුර පන්ති හුදකලා කිරීමට අවශ්ය වේ.
මම මෙතෙක් සොයාගෙන ඇති හොඳම අර්ථ දැක්වීම ජේම්ස් ෂෝර් විසිනි :
"යැපුම් එන්නත් කිරීම" යනු ශත 5 සංකල්පයක් සඳහා ඩොලර් 25 ක යෙදුමකි. [...] පරායත්ත එන්නත් කිරීම යනු වස්තුවකට එහි නිදර්ශන විචල්යයන් ලබා දීමයි. [...].
නැත මාටින් ලතා විසින් ලිපියක් ද, ප්රයෝජනවත් බව ඔප්පු කරන පිණිස.
පරායත්ත එන්නත් කිරීම යනු මූලික වශයෙන් වස්තුවකට අවශ්ය වස්තූන් (එහි පරායත්තතාවයන්) සැපයීමයි. පරායත්තයන් සමච්චලයට ලක් කිරීමට හෝ මුරණ්ඩු කිරීමට ඉඩ සලසන බැවින් එය පරීක්ෂා කිරීම සඳහා ඉතා ප්රයෝජනවත් තාක්ෂණයකි.
පරායත්තයන් බොහෝ ආකාරවලින් වස්තූන් තුළට එන්නත් කළ හැකිය (ඉදිකිරීම්කරු එන්නත් කිරීම හෝ සෙටර් එන්නත් කිරීම වැනි). ඒ සඳහා යමෙකුට විශේෂිත යැපුම් එන්නත් රාමු (උදා: වසන්තය) භාවිතා කළ හැකිය, නමුත් ඒවා නිසැකවම අවශ්ය නොවේ. පරායත්ත එන්නත් කිරීම සඳහා ඔබට එම රාමු අවශ්ය නොවේ. වස්තූන් ස්ථාපනය කිරීම සහ පසු කිරීම (පරායත්තතා) පැහැදිලිවම රාමුව අනුව එන්නත් කිරීම තරම් හොඳ එන්නත් කිරීමකි.
ලිහිල් සම්බන්ධතාවයට අනුව මෙම විහිලු උදාහරණය මට හමු විය :
ඕනෑම යෙදුමක් සෑදී ඇත්තේ ප්රයෝජනවත් දේවල් ඉටු කිරීම සඳහා එකිනෙකා සමඟ සහයෝගයෙන් කටයුතු කරන බොහෝ වස්තූන්ගෙනි. සාම්ප්රදායිකව සෑම වස්තුවක්ම එය සමඟ සහයෝගයෙන් කටයුතු කරන යැපෙන වස්තූන් (පරායත්තතා) වෙත තමන්ගේම යොමු ලබා ගැනීම සඳහා වගකිව යුතුය. මෙය ඉහළ සම්බන්ධිත පන්ති සහ පරීක්ෂා කිරීමට අපහසු කේත වලට මග පාදයි.
උදාහරණයක් ලෙස, Car
වස්තුවක් සලකා බලන්න .
A ධාවනය Car
කිරීමට රෝද, එන්ජින්, ඉන්ධන, බැටරි ආදිය මත රඳා පවතී. සාම්ප්රදායිකව අපි එවැනි යැපෙන වස්තූන්ගේ වෙළඳ නාමය අර්ථ දක්වමු Car
.
යැපුම් එන්නත් කිරීමකින් තොරව (DI):
class Car{
private Wheel wh = new NepaliRubberWheel();
private Battery bt = new ExcideBattery();
//The rest
}
මෙන්න, යැපෙන වස්තු නිර්මාණය කිරීම සඳහාCar
වස්තුව වගකිව යුතුය.
Wheel
ආරම්භක NepaliRubberWheel()
සිදුරුවලින් පසුව - එහි යැපෙන වස්තුව වර්ගය වෙනස් කිරීමට අපට අවශ්ය නම් කුමක් කළ යුතුද ? මෝටර් රථ වස්තුව එහි නව පරායත්තතාවයෙන් යුතුව ප්රතිනිර්මාණය කළ යුතුය ChineseRubberWheel()
, නමුත් එය කළ හැක්කේ Car
නිෂ්පාදකයාට පමණි .
එහෙනම් අපිට මොකද කරන්නේ Dependency Injection
...?
පරායත්ත එන්නත් භාවිතා කරන විට, වස්තූන් සම්පාදනය කරන වේලාවට (මෝටර් රථ නිෂ්පාදන කාලය) වෙනුවට ධාවන වේලාවේදී ඔවුන්ගේ පරායත්තතාවයන් ලබා දෙනු ලැබේ . එවිට අපට දැන් Wheel
අපට අවශ්ය ඕනෑම වේලාවක වෙනස් කළ හැකිය . මෙන්න, dependency
( wheel
) Car
ධාවන වේලාවට එන්නත් කළ හැකිය .
පරායත්ත එන්නත් භාවිතා කිරීමෙන් පසු:
මෙහි දී, අපි කරන එන්නත් ද පරායත්තයන් ක්රියාත්මක වීමේදී (රෝද හා බැටරි). එබැවින් පදය: යැපුම් එන්නත් කිරීම.
class Car{
private Wheel wh; // Inject an Instance of Wheel (dependency of car) at runtime
private Battery bt; // Inject an Instance of Battery (dependency of car) at runtime
Car(Wheel wh,Battery bt) {
this.wh = wh;
this.bt = bt;
}
//Or we can have setters
void setWheel(Wheel wh) {
this.wh = wh;
}
}
මූලාශ්රය: පරායත්ත එන්නත් කිරීම අවබෝධ කර ගැනීම
new
එය ටයරය? මම දන්ෙන නෑ. මට කළ යුතුව ඇත්තේ ඔවුන්ගෙන් මිලදී ගැනීම (පාරම් හරහා එන්නත් කිරීම), ස්ථාපනය කිරීම සහ වහ්-ලා! එබැවින්, ක්රමලේඛනය වෙත නැවත පැමිණීම, C # ව්යාපෘතියකට දැනට පවතින පුස්තකාලයක් / පන්තියක් භාවිතා කිරීමට අවශ්ය බව පවසන්න, ක්රියාත්මක කිරීමට /
new
එයට වේ, 2 වන විකල්පය එය පරාමිතිය ලෙස සම්මත කරයි. නිවැරදි නොවිය හැකි නමුත් සරල මෝඩකම තේරුම් ගැනීමට පහසුය.
පරායත්ත එන්නත් කිරීම යනු වස්තූන් අභ්යන්තරව තැනීම වෙනුවට වෙනත් කේත කැබලි වලින් වස්තු ලබා ගන්නා ආකාරයෙන් නිර්මාණය කර ඇති පුහුණුවකි. මෙයින් අදහස් කරන්නේ වස්තුවට අවශ්ය අතුරු මුහුණත ක්රියාත්මක කරන ඕනෑම වස්තුවක් කේතය වෙනස් නොකර ආදේශ කළ හැකි අතර එය පරීක්ෂණ සරල කරන අතර විසංයෝජනය වැඩි දියුණු කරයි.
උදාහරණයක් ලෙස, මෙම වගන්ති සලකා බලන්න:
public class PersonService {
public void addManager( Person employee, Person newManager ) { ... }
public void removeManager( Person employee, Person oldManager ) { ... }
public Group getGroupByManager( Person manager ) { ... }
}
public class GroupMembershipService() {
public void addPersonToGroup( Person person, Group group ) { ... }
public void removePersonFromGroup( Person person, Group group ) { ... }
}
මෙම උදාහරණයේ දී, ක්රියාත්මක කිරීම PersonService::addManager
සහ PersonService::removeManager
එම ක උදාහරණයක් අවශ්ය වනු ඇත GroupMembershipService
, එහි කටයුතු කරන්න අවශ්ය වී. පරායත්ත එන්නත් කිරීමකින් තොරව, මෙය සිදු කිරීමේ සාම්ප්රදායික ක්රමය වනුයේ නව නිපැයුම්කරු තුළ ක්ෂණිකව ස්ථාපනය GroupMembershipService
කිරීම PersonService
සහ එම අවස්ථා දෙකෙහිම එම උදාහරණ ගුණාංගය භාවිතා කිරීමයි. කෙසේ වෙතත්, ඉදිකිරීම්කරුට GroupMembershipService
අවශ්ය බොහෝ දේ තිබේ නම් හෝ ඊටත් වඩා නරක නම්, සමහර ආරම්භක “සැකසුම්” කැඳවිය යුතු වේ GroupMembershipService
, කේතය ඉක්මණින් වර්ධනය වන අතර PersonService
දැන් රඳා පවතින්නේ පමණක් GroupMembershipService
නොව අනෙක් සියල්ල මත ය GroupMembershipService
මත රඳා පවතී. තව දුරටත්, වෙත සම්බන්ධතාවය GroupMembershipService
තදින් කේතනය කර ඇති PersonService
අතර එයින් අදහස් කරන්නේ ඔබට "ව්යාජ" කළ නොහැකි බවයිGroupMembershipService
පරීක්ෂණ අරමුණු සඳහා හෝ ඔබේ යෙදුමේ විවිධ කොටස්වල උපාය මාර්ග රටාවක් භාවිතා කිරීම.
පරායත්ත එන්නත් කිරීම සමඟ , ඔබ GroupMembershipService
තුළ ඇති දේ ක්ෂණිකව ස්ථාපනය කරනවා වෙනුවට PersonService
, ඔබ එය PersonService
ඉදිකිරීම්කරු වෙත භාර දෙනු ඇත , නැතහොත් එහි දේශීය අවස්ථාවක් සැකසීමට දේපලක් (ලබා ගන්නෙකු සහ සැකසුම් කරන්නෙකු) එක් කරන්න. මෙයින් අදහස් කරන්නේ ඔබ PersonService
තව දුරටත් GroupMembershipService
එය නිර්මාණය කරන්නේ කෙසේද යන්න ගැන කරදර විය යුතු නැති බවත් , එය ලබා දී ඇති ඒවා පිළිගෙන ඒවා සමඟ වැඩ කරන බවත්ය. මෙය ද ක උපපංතිය වන ඕනෑම දෙයක් අදහස් GroupMembershipService
, හෝ උපකරණ වන GroupMembershipService
අතුරු මුහුණත "එන්නත් කරන" කළ හැකි බවට PersonService
, සහ PersonService
වෙනස් කිරීම පිළිබඳව දැන ගැනීමට අවශ්ය නැහැ.
පිළිගත් පිළිතුර හොඳ පිළිතුරකි - නමුත් DI යනු කේතයේ දෘඩ කේත නියතයන් සම්භාව්ය ලෙස මග හැරීම හා සමාන බව මම මෙයට එක් කිරීමට කැමැත්තෙමි.
ඔබ දත්ත සමුදා නාමයක් වැනි නියතයක් භාවිතා කරන විට, ඔබ එය ඉක්මනින් කේතයේ ඇතුළත සිට යම් වින්යාස ගොනුවකට ගෙන ගොස් එම අගය අඩංගු විචල්යයක් අවශ්ය ස්ථානයට ගෙන යනු ඇත. එසේ කිරීමට හේතුව මෙම නියතයන් සාමාන්යයෙන් අනෙක් කේතයට වඩා නිතර වෙනස් වීමයි. උදාහරණයක් ලෙස ඔබ පරීක්ෂණ දත්ත ගබඩාවක කේතය පරීක්ෂා කිරීමට කැමති නම්.
වස්තු දිශානත ක්රමලේඛන ලෝකයේ DI මේ හා සමාන වේ. නියත වචනාර්ථයන් වෙනුවට එහි ඇති අගයන් සමස්ත වස්තූන් වේ - නමුත් පන්ති කේතයෙන් ඒවා නිර්මාණය කරන කේතය ගෙනයාමට හේතුව සමාන වේ - වස්තූන් නිතර නිතර වෙනස් වන අතර ඒවා භාවිතා කරන කේතය. එවැනි වෙනසක් අවශ්ය වන එක් වැදගත් අවස්ථාවක් වන්නේ පරීක්ෂණ ය.
කාර් සහ එන්ජින් පංති සමඟ සරල උදාහරණයක් උත්සාහ කරමු , ඕනෑම මෝටර් රථයකට ඕනෑම තැනකට යාමට එන්ජිමක් අවශ්යය, අවම වශයෙන් දැනට. එබැවින් පරායත්ත එන්නත් කිරීමකින් තොරව කේතය පෙනෙන්නේ කෙසේද යන්න පහතින්.
public class Car
{
public Car()
{
GasEngine engine = new GasEngine();
engine.Start();
}
}
public class GasEngine
{
public void Start()
{
Console.WriteLine("I use gas as my fuel!");
}
}
කාර් පන්තිය ක්ෂණිකව ක්රියාත්මක කිරීම සඳහා අපි ඊළඟ කේතය භාවිතා කරමු:
Car car = new Car();
මෙම කේතය සමඟ ඇති ගැටළුව අප ගෑස් එන්ජින් සමඟ තදින් සම්බන්ධ කර ඇති අතර එය විදුලි එන්ජින් ලෙස වෙනස් කිරීමට තීරණය කළහොත් අපට කාර් පන්තිය නැවත ලිවීමට අවශ්ය වනු ඇත. යෙදුම විශාල වන තරමට ගැටළු සහ හිසරදය අපට නව වර්ගයේ එන්ජින් එකතු කර භාවිතා කිරීමට සිදුවේ.
වෙනත් වචන වලින් කිවහොත්, අපගේ ඉහළ මට්ටමේ කාර් පන්තිය SOLID වෙතින් යැපුම් ප්රතිලෝම මූලධර්මය (DIP) උල්ලං which නය කරන පහළ මට්ටමේ ගෑස් එන්ජින් පන්තිය මත රඳා පවතී. ඩීඅයිපී යෝජනා කරන්නේ අප රඳා පැවතිය යුත්තේ කොන්ක්රීට් පංති නොව වියුක්ත කිරීම් මත බවයි. එබැවින් මෙය තෘප්තිමත් කිරීම සඳහා අපි IEngine අතුරුමුහුණත හඳුන්වා දී පහත කේතය නැවත ලියන්නෙමු:
public interface IEngine
{
void Start();
}
public class GasEngine : IEngine
{
public void Start()
{
Console.WriteLine("I use gas as my fuel!");
}
}
public class ElectricityEngine : IEngine
{
public void Start()
{
Console.WriteLine("I am electrocar");
}
}
public class Car
{
private readonly IEngine _engine;
public Car(IEngine engine)
{
_engine = engine;
}
public void Run()
{
_engine.Start();
}
}
දැන් අපගේ කාර් පන්තිය රඳා පවතින්නේ එන්ජින් අතුරුමුහුණත මත මිස නිශ්චිත එන්ජිමක් ක්රියාත්මක කිරීම මත නොවේ. දැන්, එකම උපක්රමය නම් අපි මෝටර් රථයේ නිදසුනක් නිර්මාණය කර එයට ගෑස් එන්ජින් හෝ විදුලි එන්ජින් වැනි සත්ය කොන්ක්රීට් එන්ජින් පන්තියක් ලබා දෙන්නේ කෙසේද යන්නයි. එතන තමයි යැපුම් එන්නත එන්නේ.
Car gasCar = new Car(new GasEngine());
gasCar.Run();
Car electroCar = new Car(new ElectricityEngine());
electroCar.Run();
මෙන්න අපි මූලික වශයෙන් අපගේ යැපීම (එන්ජින් උදාහරණය) කාර් සාදන්නාට එන්නත් කරන්නෙමු. දැන් අපගේ පංතිවලට වස්තූන් සහ ඒවායේ පරායත්තතාවයන් අතර ලිහිල් සම්බන්ධතාවයක් ඇති අතර, කාර් පන්තිය වෙනස් නොකර අපට පහසුවෙන් නව වර්ගයේ එන්ජින් එකතු කළ හැකිය.
පරායත්ත එන්නතෙහි ප්රධාන වාසිය වන්නේ පන්ති වඩාත් ලිහිල් ලෙස සම්බන්ධ වී ඇති බැවින් ඒවාට දෘඩ කේත පරායත්තයන් නොමැති බැවිනි. මෙය ඉහත සඳහන් කළ පරායත්ත ප්රතිලෝම මූලධර්මය අනුගමනය කරයි. නිශ්චිත ක්රියාත්මක කිරීම් ගැන සඳහන් කරනවා වෙනුවට , පංතිය ගොඩනඟන විට ලබා දෙන සාරාංශ (සාමාන්යයෙන් අතුරුමුහුණත් ) ඉල්ලා සිටී.
එබැවින් අවසානයේදී යැපුම් එන්නත් කිරීම යනු වස්තූන් සහ ඒවායේ පරායත්තතාවයන් අතර ලිහිල් සම්බන්ධතාවයක් ඇති කර ගැනීමේ තාක්ෂණයකි. එහි ක්රියාකාරකම් සිදු කිරීම සඳහා පන්තියට අවශ්ය වන පරායත්තයන් සෘජුවම ස්ථාපනය කරනවා වෙනුවට, පරායත්තතා පන්තියට (බොහෝ විට) ඉදිකිරීම්කරු එන්නත් කිරීම මඟින් සපයනු ලැබේ.
අපට බොහෝ පරායත්තතා ඇති විට, අපගේ සියලු පරායත්තතාවයන් සඳහා සංයුක්ත ක්රියාත්මක කිරීම් කුමන අතුරුමුහුණත් සිතියම් ගත කළ යුතුදැයි අපට කිව හැකි ප්රතිලෝම පාලක (අයිඕසී) බහාලුම් භාවිතා කිරීම ඉතා හොඳ පුරුද්දකි. එය ගොඩනඟන විට එම පරායත්තතාවයන් අප විසින් නිරාකරණය කර ගත හැකිය. අපේ වස්තුව. උදාහරණයක් ලෙස, IoC කන්ටේනරය සඳහා සිතියම්ගත කිරීමේදී අපට සඳහන් කළ හැක්කේ IEngine පරායත්තතාවය GasEngine පන්තියට සිතියම් ගත කළ යුතු අතර අපගේ මෝටර් රථ පන්තියේ උදාහරණයක් සඳහා IoC කන්ටේනරය විමසූ විට , එය ස්වයංක්රීයව අපගේ කාර් පන්තිය ගෑස් එන්ජින් පරායත්තතාවයකින් ගොඩනගනු ඇත. ඇතුලට ආවා.
යාවත්කාලීන කිරීම: මෑතකදී ජුලී ලර්මන් වෙතින් ඊඑෆ් කෝර් පිළිබඳ පා course මාලාවක් නැරඹූ අතර ඩීඅයි පිළිබඳ ඇගේ කෙටි අර්ථ දැක්වීමටද කැමති විය.
පරායත්ත එන්නත් කිරීම යනු ඔබේ යෙදුමට පියාසර කරන වස්තූන් අවශ්ය පන්තිවලට එන්නත් කිරීමට ඉඩ සලසන රටාවකි. එමඟින් ඔබේ කේතය වඩාත් ලිහිල්ව සම්බන්ධ කිරීමට ඉඩ ලබා දෙන අතර, ආයතන රාමු හරය මෙම සේවා පද්ධතියටම සම්බන්ධ වේ.
ඔබට මසුන් ඇල්ලීමට අවශ්ය යැයි සිතමු:
පරායත්ත එන්නත් කිරීමකින් තොරව, ඔබ සියල්ල ඔබම බලා ගත යුතුය. ඔබට බෝට්ටුවක් සොයා ගැනීමට, ධීවර පොල්ලක් මිලදී ගැනීමට, ඇමක් සෙවීමට යනාදිය අවශ්යය. ඇත්ත වශයෙන්ම එය කළ හැකි නමුත් එය ඔබට විශාල වගකීමක් පැවරේ. මෘදුකාංග අර්ථයෙන් ගත් කල, එයින් අදහස් වන්නේ ඔබ මේ සියල්ල ගැන සොයා බැලිය යුතු බවයි.
යැපුම් එන්නත් කිරීම සමඟ, වෙනත් අයෙකු සියලු සූදානම ගැන සැලකිලිමත් වන අතර අවශ්ය උපකරණ ඔබට ලබා දේ. ඔබට ලැබෙනු ඇත ("එන්නත් කරනු ලැබේ") බෝට්ටුව, ධීවර සැරයටිය සහ ඇමක් - සියල්ල භාවිතා කිරීමට සූදානම්.
මෙම කටයුතු පිලිබඳ වඩාත් සරල පැහැදිලි කිරීමක් සත්කාර එන්නත් හා සත්කාර එන්නත් බහාලුම් මා කවදාවත් දැක:
යැපුම් එන්නත් කිරීම සහ යැපීම එන්නත් බහාලුම් විවිධ දේ:
යැපුම් එන්නත් කිරීම සඳහා ඔබට කන්ටේනරයක් අවශ්ය නොවේ. කෙසේ වෙතත් කන්ටේනරයක් ඔබට උදව් කළ හැකිය.
“පරායත්ත එන්නත් කිරීම” යන්නෙන් අදහස් කරන්නේ පරාමිතිගත ඉදිකිරීම්කරුවන් සහ පොදු සැකසුම් භාවිතා කිරීම නොවේද?
ජේම්ස් ෂෝර්ගේ ලිපිය සංසන්දනය සඳහා පහත උදාහරණ පෙන්වයි .
පරායත්ත එන්නත් කිරීමකින් තොරව ඉදිකිරීම්කරු:
public class Example { private DatabaseThingie myDatabase; public Example() { myDatabase = new DatabaseThingie(); } public void doStuff() { ... myDatabase.getData(); ... } }
පරායත්ත එන්නත් සහිත ඉදිකිරීම්කරු:
public class Example { private DatabaseThingie myDatabase; public Example(DatabaseThingie useThisDatabaseInstead) { myDatabase = useThisDatabaseInstead; } public void doStuff() { ... myDatabase.getData(); ... } }
new DatabaseThingie()
වලංගු myDatabase නිදසුනක් ජනනය නොකරන්නේ නම් පමණි .
පරායත්ත එන්නත් සංකල්පය තේරුම් ගැනීමට සරල කිරීම. බල්බයක් ටොගල කිරීමට (සක්රිය / අක්රිය) ස්විච් බොත්තම පිළිබඳ උදාහරණයක් බලමු.
ස්විචයට මා සම්බන්ධ කර ඇත්තේ කුමන බල්බයටද යන්න කලින් දැනගත යුතුය (දෘඩ කේතයෙන් යැපීම). ඒ නිසා,
ස්විචය -> ස්ථිර බල්බ් // ස්විචය ස්ථිර බල්බයකට කෙලින්ම සම්බන්ධ වී ඇත, පරීක්ෂා කිරීම පහසුවෙන් කළ නොහැක
Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}
ස්විචය දන්නේ මා වෙත බල්බය ලබා දුන් ඕනෑම දෙයක් සක්රිය / අක්රිය කළ යුතු බවයි. ඒ නිසා,
මාරු කරන්න -> බල්බ් 1 හෝ බල්බ් 2 හෝ රාත්රී බල්බ් (එන්නත් කරන ලද යැපීම)
Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}
ස්විචය සහ බල්බ සඳහා ජේම්ස් උදාහරණය වෙනස් කිරීම :
public class SwitchTest {
TestToggleBulb() {
MockBulb mockbulb = new MockBulb();
// MockBulb is a subclass of Bulb, so we can
// "inject" it here:
Switch switch = new Switch(mockBulb);
switch.ToggleBulb();
mockBulb.AssertToggleWasCalled();
}
}
public class Switch {
private Bulb myBulb;
public Switch() {
myBulb = new Bulb();
}
public Switch(Bulb useThisBulbInstead) {
myBulb = useThisBulbInstead;
}
public void ToggleBulb() {
...
myBulb.Toggle();
...
}
}`
යැපුම් එන්නත් (DI) යනු කුමක්ද?
අනෙක් අය පවසා ඇති පරිදි, අපගේ උනන්දුව දක්වන පන්තිය (පාරිභෝගික පන්තිය) රඳා පවතින ( යූඑම්එල් අර්ථයෙන් ) වෙනත් වස්තු අවස්ථාවන්හි සෘජු නිර්මාණය හා ආයු කාලය කළමනාකරණය කිරීමේ වගකීම යැපුම් එන්නත් කිරීම (DI) ඉවත් කරයි . මෙම අවස්ථා ඒ වෙනුවට අපගේ පාරිභෝගික පන්තියට, සාමාන්යයෙන් ඉදිකිරීම්කරුවන්ගේ පරාමිතීන් ලෙස හෝ දේපල සැකසුම් හරහා යවනු ලැබේ (පරායත්ත වස්තු කළමනාකරණය සහ පාරිභෝගික පන්තියට ගමන් කිරීම සාමාන්යයෙන් සිදු කරනු ලබන්නේ ප්රතිලෝම පාලන (IoC) බහාලුමක් මගිනි , නමුත් එය තවත් මාතෘකාවක් වේ) .
DI, DIP සහ SOLID
විශේෂයෙන්, රොබට් සී මාටින්ගේ SOLID මූලධර්මවල Object Oriented Design හි පරමාදර්ශය තුළ , DI
එය ක්රියාත්මක කළ හැකි එකකි යැපුම් ප්රතිලෝම මූලධර්මය (ඩීඅයිපී) . මෙම DIP යනු D
පිළිබඳ SOLID
මන්ත්රය - වෙනත් DIP නිර්මාණයන් සේවා සෙවීම, සහ හොදම විදිය තමයි රටා ඇතුලත් වේ.
ඩීඅයිපී හි පරමාර්ථය වන්නේ පංති අතර තද, කොන්ක්රීට් පරායත්තතාවයන් විසන්ධි කිරීම සහ ඒ වෙනුවට, වියුක්තයක් මගින් සම්බන්ධ කිරීම ලිහිල් කිරීමයි, එය හරහා ලබා ගත හැකි interface
, abstract class
හෝ pure virtual class
, භාවිතා කරන භාෂාව සහ ප්රවේශය අනුව ය.
ඩීඅයිපී නොමැතිව, අපගේ කේතය (මම මෙම 'පරිභෝජන පන්තිය' ලෙස හැඳින්වූයේ) සෘජුවම කොන්ක්රීට් පරායත්තතාවයකට සම්බන්ධ වන අතර බොහෝ විට මෙම පරායත්තතාවයේ නිදසුනක් ලබා ගන්නේ කෙසේද සහ කළමනාකරණය කරන්නේ කෙසේද යන්න දැන ගැනීමේ වගකීම ද, එනම් සංකල්පමය වශයෙන්:
"I need to create/use a Foo and invoke method `GetBar()`"
ඩීඅයිපී අයදුම් කිරීමෙන් පසු අවශ්යතාවය ලිහිල් වන අතර Foo
යැපීමේ ආයු කාලය ලබා ගැනීම සහ කළමනාකරණය කිරීම පිළිබඳ සැලකිලිමත් වීම ඉවත් කර ඇත.
"I need to invoke something which offers `GetBar()`"
DIP (සහ DI) භාවිතා කරන්නේ ඇයි?
මේ ආකාරයෙන් පන්ති අතර පරායත්තතාවයන් විකේතනය කිරීමෙන් මෙම පරායත්තතා පංති වෙනත් ක්රියාත්මක කිරීම් සමඟ පහසුවෙන් ආදේශ කිරීමට ඉඩ සලසයි . එපමණක්ද නොව, අනෙක් අය සඳහන් කර ඇති පරිදි, සමහරවිට එම තෙමාලන හරහා ජීවයේ පන්ති වඩාත් පොදු හේතුව පානය පන්ති හුදෙකලාව පරීක්ෂා කර තහවුරු කිරීම සඳහා ඉඩ ඇති මේ පරායත්තයන් දැන් stubbed සහ / හෝ සමච්චල් කරමින් කළ හැකි පරිදි වේ.
DI හි එක් ප්රතිවිපාකයක් නම් පරායත්ත වස්තු සිද්ධි වල ආයු කාලය තවදුරටත් පරිභෝජනය කරන පන්තියක් විසින් පාලනය නොකිරීමයි. මන්දයත් පරායත්ත වස්තුව දැන් පරිභෝජන පන්තියට (ඉදිකිරීම්කරු හෝ සෙටර් එන්නත් කිරීම හරහා) යවනු ලැබේ.
මෙය විවිධ ආකාරවලින් නැරඹිය හැකිය:
Create
අවශ්ය පරිදි කර්මාන්තශාලාව අතර, මෙම අවස්ථා අවසන් වූ පසු බැහැර කරන්න.DI භාවිතා කළ යුත්තේ කවදාද?
MyDepClass
නූල් ආරක්ෂිතයි - අපි එය තනි පුද්ගලයකු බවට පත් කර එකම අවස්ථාව සියලු පාරිභෝගිකයින්ට එන්නත් කළහොත් කුමක් කළ යුතුද?)උදාහරණයක්
මෙන්න සරල C # ක්රියාත්මක කිරීමකි. පහත දැක්වෙන පරිභෝජන පන්තිය:
public class MyLogger
{
public void LogRecord(string somethingToLog)
{
Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog);
}
}
අහිංසක බවක් පෙනෙන්නට තිබුණද, එයට static
තවත් පන්ති දෙකක් මත යැපීම් දෙකක් ඇත, System.DateTime
සහSystem.Console
එම දැව සදහා නිෂ්පාදනය විකල්ප (කිසිවෙකු බලා නම් අග්රය වෙත ප්රවේශ වීම්, කිසි කමකට නැති වනු ඇත), සීමා පමණක් නොව, නමුත් ඊටත් වඩා, ඒ මත රඳා පැවැතීමට ලබා ස්වයංක්රීයව පරීක්ෂා කිරීම අපහසු වේ නිර්ණායක නොවන පද්ධති ඔරලෝසුව.
කෙසේ වෙතත් අපට DIP
මෙම පන්තියට අයදුම් කළ හැක්කේ කාල පරාසය යැපීම ලෙස සැලකීමෙන් වියුක්ත කිරීමෙන් සහ MyLogger
සරල අතුරුමුහුණතකට පමණක් සම්බන්ධ වීමෙන් ය:
public interface IClock
{
DateTime Now { get; }
}
Console
A වැනි වියුක්තයක් මත යැපීම අපට ලිහිල් කළ හැකිය TextWriter
. සත්කාර එන්නත් සාමාන්යයෙන් එක්කෝ ලෙස මෙය ක්රියාත්මක වේ constructor
එන්නත් (අ පානය පන්තියේ ඉදිකිරීමටත් පරාමිතියක් ලෙස යැපීම වියුක්තකර පසුකර) හෝ Setter Injection
(අ හරහා පරායත්ත පසුකර setXyz()
සමග පන්දු පිරිනමන්නා හෝ .Net ඉඩකඩම් {set;}
අර්ථ). ඉදිකිරීම් වලින් පසු පන්තිය නිවැරදි තත්වයක පවතින බවට සහතික වන බැවින් ඉදිකිරීම් එන්නත් කිරීම වඩාත් සුදුසු වේ. තවද අභ්යන්තර පරායත්තතා ක්ෂේත්ර readonly
(C #) හෝ final
(ජාවා) ලෙස සලකුණු කිරීමට ඉඩ ලබා දේ . එබැවින් ඉහත උදාහරණයේ ඉදිකිරීම්කරු එන්නත් කිරීම භාවිතා කිරීමෙන් මෙය අපට ඉතිරි වේ:
public class MyLogger : ILogger // Others will depend on our logger.
{
private readonly TextWriter _output;
private readonly IClock _clock;
// Dependencies are injected through the constructor
public MyLogger(TextWriter stream, IClock clock)
{
_output = stream;
_clock = clock;
}
public void LogRecord(string somethingToLog)
{
// We can now use our dependencies through the abstraction
// and without knowledge of the lifespans of the dependencies
_output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog);
}
}
(කොන්ක්රීට් එකක් Clock
සැපයිය යුතුය, ඇත්ත වශයෙන්ම එය ආපසු හැරවිය හැකියDateTime.Now
අතර පරායත්තතා දෙක ඉදිකිරීම්කරු එන්නත් කිරීම හරහා අයිඕසී බහාලුමක් මගින් සැපයිය යුතුය)
ස්වයංක්රීය ඒකක පරීක්ෂණයක් ගොඩනගා ගත හැකි අතර, එය අපගේ ල ger ු-සටහන නිවැරදිව ක්රියා කරන බව නිශ්චිතවම සනාථ කරයි, මන්දයත් දැන් අපට පරායත්තයන් - කාලය පාලනය කර ඇති අතර අපට ලිඛිත ප්රතිදානය පිළිබඳ ඔත්තු බැලීමට හැකිය:
[Test]
public void LoggingMustRecordAllInformationAndStampTheTime()
{
// Arrange
var mockClock = new Mock<IClock>();
mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45));
var fakeConsole = new StringWriter();
// Act
new MyLogger(fakeConsole, mockClock.Object)
.LogRecord("Foo");
// Assert
Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString());
}
ඊළඟ පියවර
පරායත්ත එන්නත් කිරීම පාලක බහාලුමක් (IoC) සමඟ නිරන්තරයෙන් සම්බන්ධ වේ , කොන්ක්රීට් පරායත්තතා අවස්ථා එන්නත් කිරීම (සැපයීම) සහ ආයු කාලය කළමනාකරණය කිරීම. වින්යාස කිරීමේ / ඇරඹුම් ක්රියාවලිය අතරතුර, IoC
බහාලුම් පහත සඳහන් දේ අර්ථ දැක්වීමට ඉඩ දෙයි:
IBar
ආපසු ConcreteBar
එවන්න" )IDisposable
වගකීම භාර ගනී Disposing
.සාමාන්යයෙන්, IoC බහාලුම් වින්යාසගත කිරීමෙන් / ඇරඹූ පසු, ඒවා බාධාවකින් තොරව ක්රියාත්මක වන අතර, කෝඩරයට පරායත්තතාවයන් ගැන කරදර නොවී අතේ ඇති කේතය කෙරෙහි අවධානය යොමු කිරීමට ඉඩ ලබා දේ.
DI- හිතකාමී කේතයේ ප්රධාන දෙය නම් පන්ති ස්ථිතිකව සම්බන්ධ වීම වළක්වා ගැනීම සහ යැපීම් නිර්මාණය කිරීම සඳහා නව () භාවිතා නොකිරීමයි.
ඉහත උදාහරණයට අනුව, පරායත්තයන් විකේතනය කිරීම සඳහා යම් නිර්මාණ උත්සාහයක් අවශ්ය වන අතර, සංවර්ධකයාට, new
යැපීම්වල පුරුද්ද කෙලින්ම බිඳ දැමීම සඳහා අවශ්ය පරමාදර්ශී වෙනසක් අවශ්ය වන අතර ඒ වෙනුවට පරායත්තතා කළමනාකරණය කිරීම සඳහා කන්ටේනරය විශ්වාස කරයි.
නමුත් ප්රතිලාභ බොහෝය, විශේෂයෙන් ඔබේ උනන්දුව දක්වන පන්තිය හොඳින් පරීක්ෂා කිරීමේ හැකියාව තුළ.
සටහන : new ..()
POCO / POJO / Serialization DTOs / Entity Graphs / Anonymous JSON ප්රක්ෂේපණ සහ වෙනත් - එනම් “දත්ත පමණක්” පන්ති හෝ වාර්තා නිර්මාණය කිරීම / සිතියම්ගත කිරීම / ප්රක්ෂේපණය ( ක්රමයෙන්) භාවිතා කරන හෝ ආපසු ලබා දෙන ක්රම මත රඳා නොපවතී ( යූඑම්එල් හැඟීම) සහ DI ට යටත් නොවේ. new
මේවා ප්රක්ෂේපණය කිරීම සඳහා භාවිතා කිරීම හොඳයි.
යැපුම් එන්නත් කිරීමේ (DI) සමස්ත කරුණ වන්නේ යෙදුම් ප්රභව කේතය පිරිසිදුව හා ස්ථාවරව තබා ගැනීමයි :
ප්රායෝගිකව, සෑම සැලසුම් රටාවක්ම අනාගත වෙනස්කම් අවම ලිපිගොනු වලට බලපාන ලෙස සැලකිලිමත් වේ.
DI හි නිශ්චිත වසම වන්නේ පරායත්ත වින්යාසය සහ ආරම්භය පැවරීමයි.
ඔබ ඉඳහිට ජාවා වලින් පිටත වැඩ කරන්නේ source
නම්, බොහෝ ස්ක්රිප්ටින් භාෂාවන්හි (ෂෙල්, ටීඑල්සී, ආදිය හෝ import
පයිතන්හි පවා මේ සඳහා අනිසි ලෙස භාවිතා කර ඇති ආකාරය) මතක තබා ගන්න.
සරල dependent.sh
පිටපතක් සලකා බලන්න :
#!/bin/sh
# Dependent
touch "one.txt" "two.txt"
archive_files "one.txt" "two.txt"
ස්ක්රිප්ට් එක රඳා පවතී: එය තනිවම සාර්ථකව ක්රියාත්මක නොවේ ( archive_files
අර්ථ දක්වා නැත).
ඔබ අර්ථ archive_files
දී archive_files_zip.sh
(භාවිතා ක්රියාත්මක තිර රචනය zip
මෙම නඩුවේ):
#!/bin/sh
# Dependency
function archive_files {
zip files.zip "$@"
}
source
ක්රියාත්මක කිරීමේ ස්ක්රිප්ට් සෘජුවම යැපෙන එකෙහි වෙනුවට , ඔබ injector.sh
“සංරචක” දෙකම ආවරණය කරන “බහාලුමක්” භාවිතා කරයි :
#!/bin/sh
# Injector
source ./archive_files_zip.sh
source ./dependent.sh
මෙම archive_files
පරායත්ත පමණක් වී ඇත එන්නත් කරන බවට රඳා තිර රචනය.
ඔබ ක්රියාත්මක කරන පරායත්ත ශරීරගත විය හැකි archive_files
භාවිතා tar
හෝ xz
.
dependent.sh
ස්ක්රිප්ට් සෘජුවම පරායත්තයන් භාවිතා කළේ නම් , ප්රවේශය පරායත්තතා විමසුම ලෙස හැඳින්වේ (එය පරායත්ත එන්නත් කිරීමට ප්රතිවිරුද්ධ වේ ):
#!/bin/sh
# Dependent
# dependency look-up
source ./archive_files_zip.sh
touch "one.txt" "two.txt"
archive_files "one.txt" "two.txt"
දැන් ගැටළුව වන්නේ යැපෙන “සංරචකය” ආරම්භක ක්රියාවලියම සිදු කිරීමයි.
"සංරචකයේ" ප්රභව කේතය පිරිසිදු හෝ ස්ථාවර නොවේ නොවේ, මන්දයත් පරායත්තතා ආරම්භ කිරීමේ සෑම වෙනස්කමකටම "සංරචක" හි ප්රභව කේත ගොනුව සඳහා නව නිකුතුවක් අවශ්ය වේ.
DI යනු ජාවා රාමුවල තරම් විශාල වශයෙන් අවධාරණය කර ජනප්රිය කර නොමැත.
එහෙත් එය පහත දැක්වෙන කරුණු සඳහා පොදු ප්රවේශයකි:
පමණක් වින්යාසය භාවිතා පරායත්ත බැලීම මානකරණ පරාමිතික සංඛ්යාව ලෙස උදව් පරායත්තතාවන් සහාය වර්ග (උදා: නව දත්ත සමුදා වර්ගය) සංඛ්යාව ලෙස පරායත්ත අනුව (උදා: නව අනන්යතාවය තහවුරු කරගැනීමේ මාදිලිය) මෙන්ම වෙනස් විය හැක නැහැ.
ඉහත සියලු පිළිතුරු හොඳයි, මගේ අරමුණ වන්නේ ක්රමලේඛ දැනුමක් නැති ඕනෑම කෙනෙකුට සංකල්පය තේරුම් ගත හැකි වන පරිදි සංකල්පය සරල ආකාරයකින් පැහැදිලි කිරීමයි
පරායත්ත එන්නත් කිරීම සංකීර්ණ පද්ධති සරල ආකාරයකින් නිර්මාණය කිරීමට අපට උපකාරී වන සැලසුම් රටාවකි.
අපගේ එදිනෙදා ජීවිතයේදී මෙම රටාවේ විවිධාකාර යෙදුම් අපට දැක ගත හැකිය. උදාහරණ සමහරක් නම් ටේප් රෙකෝඩරය, වීසීඩී, සීඩී ඩ්රයිව් යනාදියයි.
ඉහත රූපය 20 වන සියවසේ මැද භාගයේ රීල්-ටු-රීල් අතේ ගෙන යා හැකි ටේප් රෙකෝඩරයේ රූපයකි. මූලාශ්රය .
ටේප් රෙකෝඩර් යන්ත්රයක මූලික අභිප්රාය වන්නේ ශබ්දය පටිගත කිරීම හෝ නැවත ධාවනය කිරීමයි.
පද්ධතියක් නිර්මාණය කිරීමේදී ශබ්දය හෝ සංගීතය පටිගත කිරීම හෝ ධාවනය කිරීම සඳහා රීල් එකක් අවශ්ය වේ. මෙම ක්රමය සැලසුම් කිරීම සඳහා අවස්ථා දෙකක් තිබේ
අපි පළමු එක භාවිතා කරන්නේ නම්, බටය වෙනස් කිරීම සඳහා යන්ත්රය විවෘත කළ යුතුය. අපි දෙවැන්න තෝරා ගන්නේ නම්, එය රීල් සඳහා කොක්කක් තබන්නේ නම්, රීල් වෙනස් කිරීමෙන් ඕනෑම සංගීතයක් වාදනය කිරීමෙන් අපට අමතර ප්රතිලාභයක් ලැබේ. තවද ශ්රිතය අඩු කරන්නේ රීල් එකේ ඕනෑම දෙයක් වාදනය කිරීමට පමණි.
Wise ානවන්ත පරායත්ත එන්නත් කිරීම යනු පරායත්තයන් බාහිරකරණය කිරීමේ ක්රියාවලිය වන අතර එමඟින් සංරචකයේ නිශ්චිත ක්රියාකාරිත්වය කෙරෙහි පමණක් අවධානය යොමු කළ යුතුය.
යැපුම් එන්නත් භාවිතා කිරීමෙන් අප ලබාගත් ප්රධාන ප්රතිලාභ.
දැන් මෙම සංකල්පය ක්රමලේඛන ලෝකයේ ප්රකට රාමු වල පදනම වේ. වසන්ත කෝණික යනාදිය මෙම සංකල්පයේ මුදුනේ ගොඩනගා ඇති සුප්රසිද්ධ මෘදුකාංග රාමු වේ
පරායත්ත එන්නත් කිරීම යනු වෙනත් වස්තූන් සම්පාදනය කරන වේලාවේදී නොදැන එම වස්තූන් එම ක්රියාකාරීත්වය සැපයීම සඳහා භාවිතා කරන්නේ කුමන පන්තියද යන්න හෝ වස්තුවකට ගුණාංග එන්නත් කරන ආකාරය පරායත්ත එන්නත් කිරීම ලෙස හැඳින්වීම සඳහා භාවිතා කරන රටාවකි.
යැපුම් එන්නත් සඳහා උදාහරණය
මීට පෙර අපි මේ වගේ කේත ලියනවා
Public MyClass{
DependentClass dependentObject
/*
At somewhere in our code we need to instantiate
the object with new operator inorder to use it or perform some method.
*/
dependentObject= new DependentClass();
dependentObject.someMethod();
}
පරායත්ත එන්නත් කිරීමත් සමඟ පරායත්ත ඉන්ජෙක්ටර් අප වෙනුවෙන් ක්ෂණිකව ඉවත් කරනු ඇත
Public MyClass{
/* Dependency injector will instantiate object*/
DependentClass dependentObject
/*
At somewhere in our code we perform some method.
The process of instantiation will be handled by the dependency injector
*/
dependentObject.someMethod();
}
ඔබට කියවිය හැකිය
පරායත්ත එන්නත් කිරීම (DI) යනු එකිනෙකා මත යැපෙන වස්තූන් විසන්ධි කිරීමයි. වස්තුව A වස්තුව B මත රඳා පවතින බව පවසන්න, එබැවින් අදහස මෙම වස්තුව එකිනෙකාගෙන් විසන්ධි කිරීමයි. සම්පාදනය කරන වේලාව තිබියදීත්, ක්රියාත්මක වන වේලාවේදී වස්තූන් මත පරායත්තතාවයන් බෙදා ගැනීම වෙනුවට නව මූල පදයක් භාවිතා කරමින් අපට වස්තුව තදින් කේත කිරීමට අවශ්ය නොවේ. අපි කතා කරන්නේ නම්
වින්යාස ගොනුවේ බෝංචි පරායත්තතාවය නිර්වචනය කිරීම වෙනුවට නව වචන භාවිතා කරමින් අපට වස්තුව තදින් කේත කිරීමට අවශ්ය නොවේ. වසන්ත බහාලුම සියල්ල සම්බන්ධ කිරීමට වගකිව යුතුය.
අයිඕසී යනු පොදු සංකල්පයක් වන අතර එය විවිධාකාරයෙන් ප්රකාශ කළ හැකි අතර යැපුම් එන්නත් කිරීම අයිඕසී හි එක් ස්ථිර උදාහරණයකි.
කන්ටේනරය තර්ක ගණනාවක් සහිත පන්ති ඉදිකිරීම්කරුවකුට ආරාධනා කරන විට, ඉදිකිරීම්කරු මත පදනම් වූ DI සිදු කරනු ලැබේ, සෑම එකක්ම වෙනත් පන්තියක් මත යැපීමක් නියෝජනය කරයි.
public class Triangle {
private String type;
public String getType(){
return type;
}
public Triangle(String type){ //constructor injection
this.type=type;
}
}
<bean id=triangle" class ="com.test.dependencyInjection.Triangle">
<constructor-arg value="20"/>
</bean>
ඔබේ බෝංචි ක්ෂණික කිරීම සඳහා තර්ක රහිත ඉදිකිරීම්කරුවෙකු හෝ තර්ක රහිත ස්ථිතික කර්මාන්තශාලා ක්රමයක් යෙදීමෙන් පසු ඔබේ බෝංචි මත ඇති බහාලුම් ඇමතුම් සැකසුම් ක්රම මඟින් සෙටර් මත පදනම් වූ DI සිදු කරනු ලැබේ.
public class Triangle{
private String type;
public String getType(){
return type;
}
public void setType(String type){ //setter injection
this.type = type;
}
}
<!-- setter injection -->
<bean id="triangle" class="com.test.dependencyInjection.Triangle">
<property name="type" value="equivialteral"/>
සටහන: අනිවාර්ය පරායත්තතාවයන් සඳහා ඉදිකිරීම්කරුවන්ගේ තර්ක භාවිතා කිරීම සහ විකල්ප පරායත්තතාවයන් සඳහා සැකසුම් භාවිතා කිරීම හොඳ රීතියකි. Setter අවශ්ය විවරණයන් මත පදනම්ව අපි විවරණයක් භාවිතා කරන්නේ නම්, අවශ්ය පරායත්තයන් ලෙස සැකසුම් සෑදිය හැකිය.
මට සිතිය හැකි හොඳම ප්රතිසමය වන්නේ ශල්යාගාරයේ සිටින ශල්ය වෛද්යවරයා සහ ඔහුගේ සහායකයා ය. එහිදී ශල්ය වෛද්යවරයා ප්රධාන පුද්ගලයා වන අතර ඔහුට අවශ්ය විටදී විවිධ ශල්ය සංරචක සපයන ශල්ය වෛද්යවරයා සහ ඔහුගේ සහායකයා ශල්ය වෛද්යවරයාට අවධානය යොමු කළ හැකිය. ඔහු හොඳම දේ (සැත්කම්). සහායකයා නොමැතිව ශල්ය වෛද්යවරයාට අවශ්ය සෑම අවස්ථාවකම එම සංරචක ලබා ගත යුතුය.
කෙටියෙන් DI යනු, යැපෙන සංරචක ලබා ගැනීම සඳහා සංරචක මත පොදු අමතර වගකීමක් (බරක්) ඉවත් කිරීමේ තාක්ෂණයකි.
DI වැනි තනි වගකීම් (SR) මූලධර්මයට ඔබව සමීප කරයි surgeon who can concentrate on surgery
.
DI භාවිතා කළ යුත්තේ කවදාද: සෑම නිෂ්පාදන ව්යාපෘතියකම (කුඩා / විශාල), විශේෂයෙන් වෙනස්වන ව්යාපාරික පරිසරයන් තුළ DI භාවිතා කිරීමට මම නිර්දේශ කරමි :)
ඇයි: ඔබේ කේතය පහසුවෙන් පරීක්ෂා කළ හැකි, සමච්චල් කළ හැකි යනාදිය ඔබට අවශ්ය නිසා ඔබේ වෙනස්කම් ඉක්මනින් පරීක්ෂා කර වෙළඳපොළට තල්ලු කළ හැකිය. ඔබට වැඩි පාලනයක් ඇති කේත කඳවුරක් කරා යන ගමනේදී ඔබට සහාය වීමට අතිවිශිෂ්ට නිදහස් මෙවලම් / රාමු රාශියක් ඇති විට ඔබ එසේ නොකරන්නේ මන්ද.
උදාහරණයක් ලෙස, අපට පන්ති 2 ක් Client
සහ Service
. Client
භාවිතා කරනු ඇතService
public class Service {
public void doSomeThingInService() {
// ...
}
}
මාර්ගය 1)
public class Client {
public void doSomeThingInClient() {
Service service = new Service();
service.doSomeThingInService();
}
}
මාර්ගය 2)
public class Client {
Service service = new Service();
public void doSomeThingInClient() {
service.doSomeThingInService();
}
}
මාර්ගය 3)
public class Client {
Service service;
public Client() {
service = new Service();
}
public void doSomeThingInClient() {
service.doSomeThingInService();
}
}
1) 2) 3) භාවිතා කිරීම
Client client = new Client();
client.doSomeThingInService();
වාසි
අවාසි
Client
පන්තිය සඳහා අමාරුයිService
ඉදිකිරීමටත්, අප සියලු ස්ථානයේ වෙනසක් කේතය අවශ්ය නිර්මාණය Service
වස්තුවමාර්ගය 1) ඉදිකිරීම්කරු එන්නත් කිරීම
public class Client {
Service service;
Client(Service service) {
this.service = service;
}
// Example Client has 2 dependency
// Client(Service service, IDatabas database) {
// this.service = service;
// this.database = database;
// }
public void doSomeThingInClient() {
service.doSomeThingInService();
}
}
භාවිතා කිරීම
Client client = new Client(new Service());
// Client client = new Client(new Service(), new SqliteDatabase());
client.doSomeThingInClient();
මාර්ගය 2) සෙටර් එන්නත් කිරීම
public class Client {
Service service;
public void setService(Service service) {
this.service = service;
}
public void doSomeThingInClient() {
service.doSomeThingInService();
}
}
භාවිතා කිරීම
Client client = new Client();
client.setService(new Service());
client.doSomeThingInClient();
මාර්ගය 3) අතුරුමුහුණත් එන්නත් කිරීම
චෙක් පත Https://en.wikipedia.org/wiki/Dependency_injection
===
දැන්, මෙම කේතය දැනටමත් අනුගමනය කර ඇති Dependency Injection
අතර එය පරීක්ෂණ Client
පන්තියට පහසු වේ .
කෙසේ වෙතත්, අපි තවමත් new Service()
බොහෝ කාලයක් භාවිතා කරන අතර Service
ඉදිකිරීම්කරු වෙනස් කිරීමේදී එය හොඳ නැත . එය වලක්වා ගැනීම සඳහා අපට
1) සරල අත්පොත වැනි DI ඉන්ජෙක්ටර් භාවිතා කළ හැකියInjector
public class Injector {
public static Service provideService(){
return new Service();
}
public static IDatabase provideDatatBase(){
return new SqliteDatabase();
}
public static ObjectA provideObjectA(){
return new ObjectA(provideService(...));
}
}
භාවිතා කිරීම
Service service = Injector.provideService();
2) පුස්තකාලය භාවිතා කරන්න: Android dagger2 සඳහා
වාසි
Service
, ඔබට එය වෙනස් කළ යුත්තේ ඉන්ජෙක්ටර් පන්තියේ පමණිConstructor Injection
, ඔබ ඉදිකිරීම්කරු දෙස බලන විට Client
, Client
පන්තියේ යැපීම කොපමණ දැයි ඔබට පෙනෙනු ඇතඅවාසි
Constructor Injection
, එම Service
විට වස්තුව නිර්මාණය කරයි Client
නිර්මාණය, අපි ක්රියාව භාවිත ටික Client
තොරව පන්ති Service
එසේ නිර්මාණය Service
අපතේ යනhttps://en.wikipedia.org/wiki/Dependency_injection
පරායත්තතාවය යනු භාවිතා කළ හැකි වස්තුවකි (
Service
)
එන්නත් කිරීම යනු යැපීම (Service
) යැපෙන වස්තුවකට යැවීම (Client
) එය භාවිතා කරන
එහි අර්ථය වන්නේ වස්තූන් සඳහා ඔවුන්ගේ කාර්යය කිරීමට අවශ්ය තරම් පරායත්තතා පමණක් තිබිය යුතු අතර පරායත්තතා ස්වල්පයක් විය යුතු බවයි. තවද, වස්තුවක පරායත්තතාවයන් විය යුත්තේ අතුරු මුහුණත් මත මිස හැකි සෑම විටම “කොන්ක්රීට්” වස්තූන් මත නොවේ. (කොන්ක්රීට් වස්තුවක් යනු නව පදය සමඟ නිර්මාණය කරන ලද ඕනෑම වස්තුවකි.) ලිහිල් බැඳීම වැඩි නැවත භාවිතා කිරීමේ හැකියාව, පහසුවෙන් නඩත්තු කළ හැකි බව ප්රවර්ධනය කරන අතර මිල අධික සේවා වෙනුවට “විහිළු” වස්තු පහසුවෙන් ලබා දීමට ඔබට ඉඩ සලසයි.
“යැපුම් එන්නත් කිරීම” (DI) “පාලනයේ ප්රතිලෝම” (IoC) ලෙසද හැඳින්වේ, මෙම ලිහිල් සම්බන්ධතාවය දිරිගැන්වීමේ තාක්ෂණයක් ලෙස භාවිතා කළ හැකිය.
DI ක්රියාත්මක කිරීම සඳහා මූලික ප්රවේශයන් දෙකක් තිබේ:
එය වස්තු පරායත්තයන් එහි ඉදිකිරීම්කරු වෙත යැවීමේ තාක්ෂණයයි.
ඉදිකිරීම්කරු කොන්ක්රීට් වස්තුවක් නොව අතුරු මුහුණතක් පිළිගන්නා බව සලකන්න. OrderDao පරාමිතිය ශුන්ය නම් ව්යතිරේකයක් විසි කරන බව සලකන්න. වලංගු යැපීමක් ලැබීමේ වැදගත්කම මෙයින් අවධාරණය කෙරේ. ඉදිකිරීම්කරු එන්නත් කිරීම, මගේ මතය අනුව, වස්තුවකට එහි පරායත්තතාවයන් ලබා දීමට වඩාත් කැමති යාන්ත්රණයයි. නිසි ලෙස ක්රියාත්මක කිරීම සඳහා “පුද්ගලයා” වස්තුවට යැපීම් ලබා දිය යුතු වස්තුව ඉල්ලීමේදී සංවර්ධකයාට එය පැහැදිලි ය.
නමුත් පහත උදාහරණය සලකා බලන්න… ඔබට පරායත්තතා නොමැති ක්රම දහයක් සහිත පංතියක් ඇතැයි සිතමු, නමුත් ඔබ නව ක්රමයක් එකතු කරන්නේ IDAO මත යැපීමක් ඇතිවය. ඉදිකිරීම්කරු ඉන්ජෙක්ෂන් භාවිතා කිරීම සඳහා ඔබට ඉදිකිරීම්කරු වෙනස් කළ හැකිය, නමුත් මෙය සෑම තැනකම ඇති සියලුම ඉදිකිරීම්කරුවන්ගේ ඇමතුම් වෙනස් කිරීමට බල කරයි. විකල්පයක් ලෙස, ඔබට පරායත්තතාව ලබා ගන්නා නව ඉදිකිරීම්කරුවෙකු එකතු කළ හැකිය, නමුත් එක් ඉදිකිරීම්කරුවෙකු අනෙකට වඩා භාවිතා කළ යුත්තේ කවදාදැයි සංවර්ධකයෙකු පහසුවෙන් දැන ගන්නේ කෙසේද? අවසාන වශයෙන්, යැපීම නිර්මාණය කිරීම ඉතා මිල අධික නම්, එය කලාතුරකින් පමණක් භාවිතා කළ හැකි විට එය නිර්මාණය කර ඉදිකිරීම්කරු වෙත භාර දිය යුත්තේ ඇයි? “සෙටර් ඉන්ජෙක්ෂන්” යනු මෙවැනි අවස්ථාවන්හිදී භාවිතා කළ හැකි තවත් DI තාක්ෂණයකි.
සැකසුම් එන්නත් මඟින් පරායත්තයන් ඉදිකිරීම්කරු වෙත යැවීමට බල නොකරයි. ඒ වෙනුවට, පරායත්තයන් අවශ්ය වස්තුව මගින් නිරාවරණය වන පොදු දේපල මත තබා ඇත. කලින් ඇඟවූ පරිදි, මෙය සිදු කිරීම සඳහා මූලික පෙළඹවීම් ඇතුළත් වන්නේ:
ඉහත කේතය පෙනෙන්නේ කෙසේද යන්න පිළිබඳ උදාහරණය මෙන්න:
public class Person {
public Person() {}
public IDAO Address {
set { addressdao = value; }
get {
if (addressdao == null)
throw new MemberAccessException("addressdao" +
" has not been initialized");
return addressdao;
}
}
public Address GetAddress() {
// ... code that uses the addressdao object
// to fetch address details from the datasource ...
}
// Should not be called directly;
// use the public property instead
private IDAO addressdao;
මම හිතන්නේ හැමෝම DI සඳහා ලියා ඇති නිසා, මට ප්රශ්න කිහිපයක් ඇසීමට ඉඩ දෙන්න ..
මෙය පදනම් වී ඇත්තේ @ ඇඩම් එන් පළ කළ පිළිතුර මත ය.
GroupMembershipService ගැන පුද්ගල සේවාව තවදුරටත් කරදර නොවිය යුත්තේ ඇයි? ඔබ සඳහන් කළේ GroupMembership මත රඳා පවතින බහුවිධ දේ (වස්තු / ගුණාංග) ඇත. PService හි GMS සේවා අවශ්ය නම්, ඔබට එය දේපලක් ලෙස තිබේ. ඔබ එය එන්නත් කළත් නැතත් ඔබට සමච්චල් කළ හැකිය. එය එන්නත් කිරීමට මා කැමති එකම අවස්ථාව වන්නේ GMService හි වඩාත් නිශ්චිත ළමා පන්ති තිබේ නම්, එය ක්රියාත්මක වන තෙක් ඔබ නොදැන සිටියි. එවිට ඔබට උප පංතිය එන්නත් කිරීමට අවශ්ය වනු ඇත. නැතහොත් ඔබට එය සිංගල්ටන් හෝ මූලාකෘතියක් ලෙස භාවිතා කිරීමට අවශ්ය නම්. ඇත්තම කිව්වොත්, වින්යාස ගොනුවේ සෑම දෙයක්ම දෘ c කේත කර ඇති අතර එය සම්පාදනය කරන වේලාවේදී එන්නත් කිරීමට යන වර්ගයක් (අතුරුමුහුණතක්) සඳහා වන උප පංතිය තරම් දුරට ඇත.
සංස්කරණය කරන්න
ඩීඅයි හි ජෝස් මාරියා අරන්ස් විසින් කරන ලද කදිම අදහසක්
යැපීමේ දිශාව තීරණය කිරීමට සහ ඕනෑම මැලියම් කේතයක් ලිවීමට ඇති අවශ්යතාවය ඉවත් කිරීමෙන් DI සහජීවනය වැඩි කරයි.
අසත්යය. පරායත්තයන්ගේ දිශාව XML ස්වරූපයෙන් හෝ විවරණ ලෙස, ඔබේ පරායත්තතා XML කේතය සහ විවරණ ලෙස ලියා ඇත. XML සහ විවරණ ප්රභව කේත වේ.
ඔබේ සියලු සංරචක මොඩියුලර් (එනම් ප්රතිස්ථාපනය කළ හැකි) බවට පත් කිරීමෙන් DI සම්බන්ධතාවය අඩු කරයි, සහ එකිනෙකට හොඳින් අර්ථ දක්වා ඇති අතුරු මුහුණත් ඇත.
අසත්යය. අතුරුමුහුණත් මත පදනම්ව මොඩියුලර් කේතයක් තැනීම සඳහා ඔබට DI රාමුවක් අවශ්ය නොවේ.
ප්රතිස්ථාපනය කළ හැකි දේ ගැන: ඉතා සරල .ප්රොපර්ටීස් ලේඛනාගාරයක් සහ Class.forName සමඟ ඔබට කුමන පන්ති වෙනස් කළ හැකිද යන්න නිර්වචනය කළ හැකිය. ඔබගේ කේතයේ ඕනෑම පන්තියක් වෙනස් කළ හැකි නම්, ජාවා ඔබ සඳහා නොවේ, ස්ක්රිප්ටින් භාෂාවක් භාවිතා කරන්න. මාර්ගය වන විට: නැවත සකස් කිරීමකින් තොරව විවරණ වෙනස් කළ නොහැක.
මගේ මතය අනුව DI රාමු සඳහා එකම හේතුවක් තිබේ: බොයිලේරු තහඩු අඩු කිරීම. හොඳින් සිදු කරන ලද කර්මාන්තශාලා පද්ධතියක් සමඟ ඔබට කැමති DI රාමුවකට සමාන, වඩා පාලනය කළ හැකි සහ වඩා පුරෝකථනය කළ හැකිය, DI රාමු මඟින් කේත අඩු කිරීම පොරොන්දු වේ (XML සහ ව්යාඛ්යාවන් ප්රභව කේත ද වේ). ගැටළුව වන්නේ මෙම බොයිලේරු තහඩු අඩු කිරීම ඉතා සරල අවස්ථාවන්හිදී සත්ය වේ (එක් අවස්ථාවකට එක් පන්තියකට හා ඒ හා සමාන), සමහර විට සැබෑ ලෝකයේ විසර්ජන සේවා වස්තුව තෝරා ගැනීම පන්තියක් තනි වස්තුවකට සිතියම් ගත කිරීම තරම් පහසු නොවේ.
ජනප්රිය පිළිතුරු උදව්වක් නොවේ, මන්ද ඒවා යැපුම් එන්නත් කිරීම ප්රයෝජනවත් නොවන ආකාරයෙන් අර්ථ දක්වයි. “පරායත්තතාව” යන්නෙන් අප අදහස් කරන්නේ අපගේ වස්තුව X ට අවශ්ය වෙනත් පෙර පැවති වස්තුවක් බව අපි එකඟ වෙමු. නමුත් අපි කියන විට අපි "යැපුම් එන්නත්" කරන බව නොකියමු
$foo = Foo->new($bar);
අපි එම පරාමිතීන් ඉදිකිරීම්කරු වෙතට යමු. ඉදිකිරීම්කරුවන් සොයාගත් දා සිට අපි එය නිතිපතා කරමින් සිටිමු.
“යැපුම් එන්නත් කිරීම” “පාලනයේ ප්රතිලෝම” වර්ගයක් ලෙස සලකනු ලැබේ, එයින් අදහස් කරන්නේ අමතන්නාගෙන් යම් තර්කනයක් ඉවත් කර ඇති බවයි. අමතන්නා පරාමිතීන් පසු කරන විට එය එසේ නොවේ, එබැවින් එය DI නම්, DI මඟින් පාලනයේ ප්රතිලෝම බවක් අදහස් නොකෙරේ.
DI යනු පරායත්තතා කළමනාකරණය කරන අමතන්නා සහ ඉදිකිරීම්කරු අතර අතරමැදි මට්ටමක් ඇති බවයි. Makefile යනු පරායත්ත එන්නත් කිරීම සඳහා සරල උදාහරණයකි. "අමතන්නා" යනු විධාන රේඛාවේ "සාදන්න තීරුව" ටයිප් කරන පුද්ගලයා වන අතර "ඉදිකිරීම්කරු" සම්පාදකයා වේ. Makefile මඟින් තීරුව foo මත රඳා පවතින බව සඳහන් කරයි, එය a
gcc -c foo.cpp; gcc -c bar.cpp
කිරීමට පෙර
gcc foo.o bar.o -o bar
"සාදන්න තීරුව" ටයිප් කරන පුද්ගලයාට තීරුව foo මත රඳා පවතින බව දැන ගැනීමට අවශ්ය නොවේ. "Make bar" සහ gcc අතර පරායත්තතාවය එන්නත් කරන ලදී.
අතරමැදි මට්ටමේ ප්රධාන පරමාර්ථය වන්නේ ඉදිකිරීම්කරුට පරායත්තතාවයන් ලබා දීම පමණක් නොව, සියලු පරායත්තයන් එකම ස්ථානයක ලැයිස්තුගත කිරීම සහ ඒවා කෝඩරයෙන් සැඟවීමයි (කෝඩරය ඒවා සැපයීමට නොවේ).
සාමාන්යයෙන් අතරමැදි මට්ටම මඟින් ඉදිකරන ලද වස්තූන් සඳහා කර්මාන්තශාලා සපයන අතර, එමඟින් ඉල්ලා සිටින සෑම වස්තු වර්ගයක්ම සපුරාලිය යුතු කාර්යභාරයක් සැපයිය යුතුය. එයට හේතුව ඉදිකිරීම් පිළිබඳ තොරතුරු සැඟවිය හැකි අතරමැදි මට්ටමක් තිබීම නිසා, ඔබ දැනටමත් කර්මාන්තශාලා විසින් පනවා ඇති වියුක්ත ද penalty ුවමට යටත් වී ඇති බැවින් ඔබට කර්මාන්තශාලා ද භාවිතා කළ හැකිය.
පරායත්ත එන්නත් කිරීම යනු ක්රමයක් (ඇත්ත වශයෙන්ම ඕනෑම ක්රමයක් පරායත්තයන් වෙත ප්රවේශ වීමට කේතය එක් කොටසක් (උදා: පන්ති) සඳහා) (ෙවනත් පංතිවල කේතය වෙනත් අමතර කොටස්, උදා:, ඒ මත රඳා පවතී) ඒ රොකට්ටුවක් මොඩියුල ආකාරයකින් ඔවුන් hardcoded තොරව (එසේ ඒවා වෙනස් කළ හැකිය හෝ නිදහසේ අභිබවා යා හැකිය, නැතහොත් අවශ්ය පරිදි වෙනත් වේලාවක පටවනු ලැබේ)
(සහ ps, ඔව් එය තරමක් සරල, සංකල්පයක් සඳහා ඕනෑවට වඩා උද්දීපනය වූ 25 $ නමක් බවට පත්ව ඇත) , මගේ .25
ශත
දැනටමත් බොහෝ පිළිතුරු ඇති බව මම දනිමි, නමුත් මෙය ඉතා ප්රයෝජනවත් බව මට පෙනී ගියේය: http://tutorials.jenkov.com/dependency-injection/index.html
public class MyDao {
protected DataSource dataSource = new DataSourceImpl(
"driver", "url", "user", "password");
//data access methods...
public Person readPerson(int primaryKey) {...}
}
public class MyDao {
protected DataSource dataSource = null;
public MyDao(String driver, String url, String user, String password) {
this.dataSource = new DataSourceImpl(driver, url, user, password);
}
//data access methods...
public Person readPerson(int primaryKey) {...}
}
DataSourceImpl
ක්ෂණිකකරණය ඉදිකිරීම්කරුවෙකු වෙත ගෙන යන ආකාරය සැලකිල්ලට ගන්න . ඉදිකිරීම්කරු විසින් අවශ්ය වන අගයන් හතර වන පරාමිති හතරක් ගනී DataSourceImpl
. MyDao
පංතිය තවමත් මෙම අගයන් හතර මත රඳා පැවතුනද , එය තවදුරටත් මෙම පරායත්තතාවයන් තෘප්තිමත් නොකරයි. MyDao
නිදසුනක් සපයන්නේ කුමන පන්තියකින්ද ඒවා සපයනු ලැබේ .
පරායත්ත එන්නත් කිරීම යනු සාමාන්යයෙන් “යැපුම් අපැහැදිලි” අවශ්යතාවය ලෙස හැඳින්විය හැකි එක් විසඳුමකි. පරායත්තතා අපැහැදිලි කිරීම යනු අවශ්ය පංතියකට යැපීමක් ලබා දීමේ ක්රියාවලියෙන් 'පැහැදිලිව පෙනෙන' ස්වභාවය ඉවත් කිරීමේ ක්රමයකි. එම නිසා එම පන්තියට යැපීම යම් ආකාරයකින් අපැහැදිලි වේ. මෙය අනිවාර්යයෙන්ම නරක දෙයක් නොවේ. ඇත්ත වශයෙන්ම, පන්තියකට පරායත්තතාවයක් ලබා දෙන ආකාරය අපැහැදිලි කිරීමෙන් පංතියෙන් පිටත යමක් යැපීම නිර්මාණය කිරීම සඳහා වගකිව යුතු අතර, එයින් අදහස් වන්නේ විවිධ අවස්ථා වලදී, කිසිදු වෙනස් කිරීමකින් තොරව පන්තියට යැපීම වෙනස් ලෙස ක්රියාත්මක කළ හැකි බවයි. පන්තියට. නිෂ්පාදන සහ පරීක්ෂණ ක්රම අතර මාරුවීම සඳහා මෙය විශිෂ්ටයි (උදා: 'විහිළු' සේවා යැපීමක් භාවිතා කිරීම).
අවාසනාවට නරක දෙය නම්, යැපුම් අපැහැදිලි කිරීම සඳහා ඔබට විශේෂිත රාමුවක් අවශ්ය යැයි සමහරු උපකල්පනය කර ඇති අතර ඔබ එය කිරීමට විශේෂිත රාමුවක් භාවිතා නොකිරීමට තීරණය කරන්නේ නම් ඔබ කෙසේ හෝ 'අඩු' ක්රමලේඛකයෙකු වනු ඇත. බොහෝ දෙනා විශ්වාස කරන තවත් අතිශය කරදරකාරී මිථ්යාවක් නම් පරායත්තතා අපැහැදිලි කිරීම සාක්ෂාත් කරගත හැකි එකම ක්රමය පරායත්ත එන්නත් කිරීමයි. මෙය නිරූපණයෙන් හා ically තිහාසිකව හා පැහැදිලිවම 100% වැරදියි, නමුත් ඔබේ යැපීමේ අපැහැදිලි අවශ්යතා සඳහා පරායත්ත එන්නත් කිරීම සඳහා විකල්ප ඇති බව සමහර අයට ඒත්තු ගැන්වීමට ඔබට අපහසු වනු ඇත.
ක්රමලේඛකයින් වසර ගණනාවක් තිස්සේ පරායත්තතා අපැහැදිලි කිරීමේ අවශ්යතාවය වටහාගෙන ඇති අතර යැපුම් එන්නත් පිළිසිඳ ගැනීමට පෙර සහ පසුව බොහෝ විකල්ප විසඳුම් විකාශනය වී ඇත. කර්මාන්තශාලා රටා ඇත, නමුත් විශේෂිත අවස්ථාවකට එන්නත් කිරීමක් අවශ්ය නොවන ThreadLocal භාවිතා කරමින් බොහෝ විකල්ප ඇත - පරායත්තය effectively ලදායී ලෙස නූල් තුළට එන්නත් කරනු ලබන අතර එමඟින් වස්තුව ලබා ගැනීමේ වාසිය (පහසුව ස්ථිතික ලබා ගැනීමේ ක්රම හරහා) ඕනෑම කෙනෙකුටපංතියට අවශ්ය පංති වලට විවරණ එකතු නොකර එය සිදු කිරීම සඳහා සංකීර්ණ XML 'මැලියම්' සකසන්න. ඔබේ පරායත්තතාවයන් නොනැසී පැවතීම සඳහා අවශ්ය වූ විට (JPA / JDO හෝ වෙනත් ඕනෑම දෙයක්) එය ඔබට වඩාත් පහසු සහ 'නොනැසී පවත්නා' තත්වයක් අත්කර ගැනීමට ඉඩ සලසයි.
තාක්ෂණික විස්තරයට යාමට පෙර එය සැබෑ ජීවිත උදාහරණයකින් දෘශ්යමාන කරන්න, මන්දයත් යැපුම් එන්නත් කිරීම ඉගෙන ගැනීමට ඔබට බොහෝ තාක්ෂණික කරුණු සොයාගත හැකි නමුත් මා වැනි අයට එහි මූලික සංකල්පය ලබා ගත නොහැකි බැවිනි.
පළමු පින්තූරයේ, ඔබට එක්සත් කම් රාශියක් ඇති කාර් කර්මාන්ත ශාලාවක් ඇතැයි උපකල්පනය කරන්න . මෝටර් රථයක් සැබවින්ම එකලස් කිරීමේ ඒකකයේ ඉදිකර ඇති නමුත් එයට එන්ජින් , ආසන මෙන්ම රෝද අවශ්ය වේ. එබැවින් එකලස් කිරීමේ ඒකකය මෙම සියලු ඒකක මත රඳා පවතින අතර ඒවා කර්මාන්ත ශාලාවේ යැපීම් වේ.
මෙම කර්මාන්තශාලාවේ සියලුම කාර්යයන් නඩත්තු කිරීම දැන් ඉතා සංකීර්ණ බව ඔබට හැඟිය හැකිය, මන්ද ප්රධාන කාර්යය සමඟ (එකලස් කිරීමේ ඒකකයේ මෝටර් රථ එකලස් කිරීම) ඔබ වෙනත් ඒකක කෙරෙහි ද අවධානය යොමු කළ යුතු බැවිනි. නඩත්තු කිරීම දැන් ඉතා මිල අධික වන අතර කර්මාන්තශාලා ගොඩනැගිල්ල අති විශාල බැවින් ඔබේ අමතර මුදල් කුලියට ගැනීමට සිදුවේ.
දැන්, දෙවන පින්තූරය දෙස බලන්න. ඔබේ ස්වයං නිෂ්පාදන පිරිවැයට වඩා රෝද , ආසන සහ එන්ජින් මිල අඩු සපයන සමහර සැපයුම් සමාගම් ඔබ සොයා ගන්නේ නම් , දැන් ඒවා ඔබේ කර්මාන්ත ශාලාවේ සෑදීමට අවශ්ය නොවේ. ඔබේ එකලස් කිරීමේ ඒකකය සඳහා ඔබට දැන් කුඩා ගොඩනැගිල්ලක් කුලියට ගත හැකි අතර එමඟින් ඔබේ නඩත්තු කාර්යය අඩු වන අතර ඔබේ අමතර කුලී පිරිවැය අඩු වේ. දැන් ඔබට ඔබේ ප්රධාන කාර්යය (කාර් එකලස් කිරීම) කෙරෙහි පමණක් අවධානය යොමු කළ හැකිය.
දැන් අපට පැවසිය හැක්කේ මෝටර් රථයක් එකලස් කිරීම සඳහා වන සියලු පරායත්තයන් කර්මාන්තශාලාවට එන්නත් කරනු ලබන්නේ සැපයුම්කරුවන්ගෙනි . එය සැබෑ ජීවිත පරායත්ත එන්නත (DI) සඳහා උදාහරණයකි .
දැන් තාක්ෂණික වචනයෙන්, පරායත්ත එන්නත් කිරීම යනු එක් වස්තුවක් (හෝ ස්ථිතික ක්රමය) වෙනත් වස්තුවක පරායත්තතාවයන් සපයන තාක්ෂණයකි. එබැවින්, වස්තුව වෙනත් කෙනෙකුට පැවරීමේ කාර්යය පැවරීම සහ සෘජුවම පරායත්තතාවය භාවිතා කිරීම පරායත්ත එන්නත් කිරීම ලෙස හැඳින්වේ.
කිසියම් තාක්ෂණික වචනයක් සමඟ DI ඉගෙන ගැනීමට මෙය දැන් ඔබට උපකාරී වනු ඇත. මෙම DI හා විය යුතු විට භාවිතා කිරීමට විට පෙන්වනු ඇත නොහැකි .
පොතෙන්, ' හොඳින් බිම් මට්ටමේ ජාවා සංවර්ධක: ජාවා 7 හි වැදගත් ශිල්පීය ක්රම සහ පොලිග්ලොට් ක්රමලේඛනය
DI යනු IoC හි විශේෂිත ආකාරයකි, එමඟින් ඔබේ පරායත්තයන් සොයා ගැනීමේ ක්රියාවලිය ඔබගේ දැනට ක්රියාත්මක වන කේතයේ control ජු පාලනයෙන් බැහැර වේ.
පොත Apress.Spring.Persistence.with.Hibernate.Oct.2010 වෙතින්
පරායත්ත එන්නත් කිරීමේ පරමාර්ථය වන්නේ ඔබේ යෙදුම් ව්යාපාර තර්කනයෙන් බාහිර මෘදුකාංග සංරචක නිරාකරණය කිරීමේ කාර්යය විසන්ධි කිරීමයි. යැපුම් එන්නත් කිරීමකින් තොරව, අවශ්ය සේවාවන් වෙත සංරචකයක් ප්රවේශ වන ආකාරය පිළිබඳ විස්තර සංරචකයේ කේතය සමඟ පටලවා ගත හැකිය. මෙය දෝෂ සඳහා විභවය වැඩි කිරීම, කේත පිපිරීම එකතු කිරීම සහ නඩත්තු සංකීර්ණතා විශාල කිරීම පමණක් නොව; එමඟින් සංරචක වඩාත් සමීපව සම්බන්ධ වන අතර ප්රතිචක්රීකරණය කිරීමේදී හෝ පරීක්ෂා කිරීමේදී පරායත්තතා වෙනස් කිරීම අපහසු වේ.
පරායත්ත එන්නත් කිරීම (DI) යනු නිර්මාණ රටාවන්ගෙන් එකක් වන අතර එය OOP හි මූලික ලක්ෂණය භාවිතා කරයි - එක් වස්තුවක තවත් වස්තුවක් සමඟ සම්බන්ධතාවය. උරුමය එක් වස්තුවකට වඩාත් සංකීර්ණ හා නිශ්චිත තවත් වස්තුවක් උරුම කර දෙන අතර, සම්බන්ධතාවය හෝ ඇසුර යනු හුදෙක් එක් වස්තුවකින් තවත් වස්තුවකට දර්ශකයක් නිර්මාණය කරයි. DI හි බලය OOP හි අතුරුමුහුණත් සහ සැඟවුණු කේතය වැනි අනෙකුත් අංග සමඟ සංයුක්ත වේ. පුස්තකාලයේ අපට ගනුදෙනුකරුවෙකු (ග්රාහකයකු) සිටී යැයි සිතමු, සරල බව සඳහා එක් පොතක් පමණක් ණයට ගත හැකිය.
පොතේ අතුරුමුහුණත:
package com.deepam.hidden;
public interface BookInterface {
public BookInterface setHeight(int height);
public BookInterface setPages(int pages);
public int getHeight();
public int getPages();
public String toString();
}
ඊළඟට අපට බොහෝ වර්ගවල පොත් තිබිය හැකිය; එක් වර්ගයක් ප්රබන්ධයකි:
package com.deepam.hidden;
public class FictionBook implements BookInterface {
int height = 0; // height in cm
int pages = 0; // number of pages
/** constructor */
public FictionBook() {
// TODO Auto-generated constructor stub
}
@Override
public FictionBook setHeight(int height) {
this.height = height;
return this;
}
@Override
public FictionBook setPages(int pages) {
this.pages = pages;
return this;
}
@Override
public int getHeight() {
// TODO Auto-generated method stub
return height;
}
@Override
public int getPages() {
// TODO Auto-generated method stub
return pages;
}
@Override
public String toString(){
return ("height: " + height + ", " + "pages: " + pages);
}
}
දැන් ග්රාහකයාට පොත සමඟ සම්බන්ධ විය හැකිය:
package com.deepam.hidden;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Subscriber {
BookInterface book;
/** constructor*/
public Subscriber() {
// TODO Auto-generated constructor stub
}
// injection I
public void setBook(BookInterface book) {
this.book = book;
}
// injection II
public BookInterface setBook(String bookName) {
try {
Class<?> cl = Class.forName(bookName);
Constructor<?> constructor = cl.getConstructor(); // use it for parameters in constructor
BookInterface book = (BookInterface) constructor.newInstance();
//book = (BookInterface) Class.forName(bookName).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return book;
}
public BookInterface getBook() {
return book;
}
public static void main(String[] args) {
}
}
එය ක්රියාත්මක කිරීම සඳහා පන්ති තුනම සැඟවිය හැක. දැන් අපට මෙම කේතය DI සඳහා භාවිතා කළ හැකිය:
package com.deepam.implement;
import com.deepam.hidden.Subscriber;
import com.deepam.hidden.FictionBook;
public class CallHiddenImplBook {
public CallHiddenImplBook() {
// TODO Auto-generated constructor stub
}
public void doIt() {
Subscriber ab = new Subscriber();
// injection I
FictionBook bookI = new FictionBook();
bookI.setHeight(30); // cm
bookI.setPages(250);
ab.setBook(bookI); // inject
System.out.println("injection I " + ab.getBook().toString());
// injection II
FictionBook bookII = ((FictionBook) ab.setBook("com.deepam.hidden.FictionBook")).setHeight(5).setPages(108); // inject and set
System.out.println("injection II " + ab.getBook().toString());
}
public static void main(String[] args) {
CallHiddenImplBook kh = new CallHiddenImplBook();
kh.doIt();
}
}
පරායත්ත එන්නත් භාවිතා කරන ආකාරය විවිධ ක්රම තිබේ. එය සිංගල්ටන් යනාදිය සමඟ සංයෝජනය කළ හැකි නමුත් තවමත් මූලික වශයෙන් එය සාක්ෂාත් කරගනු ලබන්නේ වෙනත් වස්තුවක් තුළ වස්තු වර්ගයේ ගුණාංග නිර්මාණය කිරීමෙන් පමණි. ප්රයෝජනවත් බව පමණක් සහ විශේෂාංගයෙන් පමණක් වන අතර, අප නැවත නැවතත් ලිවිය යුතු එම කේතය සෑම විටම සූදානම් කර ඉදිරියට ගෙන යනු ලැබේ. DI ප්රතිලෝම පාලක (IoC) සමඟ ඉතා සමීපව බැඳී ඇත්තේ මේ නිසාය, එයින් අදහස් වන්නේ අපගේ වැඩසටහන මඟින් තවත් කේත මොඩියුලයක් පාලනය කරන බවයි, එය අපගේ කේතයට බෝංචි එන්නත් කරයි. (එන්නත් කළ හැකි සෑම වස්තුවක්ම බෝංචි ලෙස අත්සන් කළ හැකිය.) උදාහරණයක් ලෙස වසන්තයේ දී එය සිදු කිරීම සහ ආරම්භ කිරීම මඟින් සිදු කෙරේ ApplicationContextකන්ටේනරය, මෙය අපට වැඩ කරයි. අපි අපගේ කේතයෙන් සන්දර්භය නිර්මාණය කර බෝංචි ආරම්භ කිරීම ඉල්ලා සිටිමු. ඒ මොහොතේ එන්නත් කිරීම ස්වයංක්රීයව සිදු කර ඇත.
අවුරුදු 5 ළමයින් සඳහා යැපුම් එන්නත් කිරීම.
ඔබ ගොස් ශීතකරණයෙන් දේවල් ඔබම ලබා ගත් විට, ඔබට ගැටළු ඇති විය හැකිය. ඔබට දොර විවෘතව තැබිය හැකිය, ඔබට අම්මා හෝ තාත්තා කැමති නැති දෙයක් ඔබට ලැබෙනු ඇත. ඔබ අප සතුව නැති හෝ කල් ඉකුත් වූ දෙයක් පවා සොයමින් සිටිය හැකිය.
ඔබ කළ යුත්තේ "දිවා ආහාරය සමඟ මට බොන්න යමක් අවශ්යයි" යන අවශ්යතාවය ප්රකාශ කිරීමයි, එවිට ඔබ කෑමට වාඩි වී සිටින විට ඔබට යමක් ඇති බවට අපි සහතික වෙමු.
ක්රිස්ටෝෆර් නොරිං වෙතින්, පැබ්ලෝ ඩීලමන්ගේ “ඉගෙනීමේ කෝණික - දෙවන සංස්කරණය” නම් පොත:
"අපගේ යෙදුම් වර්ධනය වන විට සහ පරිණාමය වන විට, අපගේ එක් එක් කේත ආයතනවලට අභ්යන්තරව මෘදුකාංග ඉංජිනේරු ලෝකයේ පරායත්තතා ලෙස හැඳින්වෙන වෙනත් වස්තූන් අවශ්ය වේ . එවැනි යැපීම් යැපෙන සේවාදායකයා වෙත යැවීමේ ක්රියාව එන්නත් කිරීම ලෙස හැඳින්වේ , එය ද නම්, තවත් කේතය ආයතනයක් සහභාගීත්වයෙන් සැළසුම් ඉන්ෙජක්ටරය . මෙම ඉන්ෙජක්ටරය සඳහා වගකීම දරනු ලබන instantiating හා bootstrapping අවශ්ය පරායත්තයන්එබැවින් ඒවා සේවාදායකයා තුළට සාර්ථකව එන්නත් කළ මොහොතේ සිටම භාවිතයට සූදානම්ය. මෙය ඉතා වැදගත් වන්නේ සේවාදායකයා තමන්ගේම පරායත්තයන් ක්ෂණිකව සකසා ගන්නේ කෙසේද යන්න ගැන කිසිවක් නොදන්නා නිසා සහ ඒවා භාවිතා කිරීම සඳහා ඔවුන් ක්රියාත්මක කරන අතුරු මුහුණත ගැන පමණක් දැන සිටින බැවිනි.
සිට: ඇන්ටන් මොයිසෙව්. පොත “යතුරු ලියනය සමඟ කෝණික සංවර්ධනය, දෙවන සංස්කරණය.”:
කෙටියෙන් කිවහොත්, කේතය ලිහිල්ව සම්බන්ධ කර ලිවීමට DI ඔබට උදව් කරන අතර ඔබේ කේතය වඩාත් පරීක්ෂා කළ හැකි සහ නැවත භාවිතා කළ හැකිය. ”
සරල වචන වලින් කිවහොත් පරායත්ත එන්නත් කිරීම (DI) යනු විවිධ වස්තූන් අතර පරායත්තතා හෝ තද සම්බන්ධතාවය ඉවත් කිරීමයි. පරායත්ත එන්නත් කිරීම එක් එක් වස්තුවට සංයුක්ත හැසිරීමක් ලබා දෙයි.
DI යනු වසන්තයේ IOC විදුහල්පතිවරයාගේ ක්රියාවට නැංවීමයි. එය “අපට අමතන්න එපා අපි ඔබට කතා කරන්නෙමු”. පරායත්ත එන්නත් ක්රමලේඛකය භාවිතා කිරීම නව මූල පදය භාවිතයෙන් වස්තුවක් නිර්මාණය කිරීම අවශ්ය නොවේ.
වස්තු වරක් වසන්ත බහාලුම්වල පටවා ඇති අතර පසුව අපට අවශ්ය විටෙක ඒවා නැවත භාවිතා කරන්නේ වසන්ත බහාලුමෙන් getBean (String beanName) ක්රමය භාවිතා කරමිනි.
යැපුම් එන්නත් කිරීම වසන්ත රාමුව හා සම්බන්ධ සංකල්පයේ හදවතයි. ඕනෑම ව්යාපෘති වසන්තයක රාමුව නිර්මාණය කිරීමේදී වැදගත් කාර්යභාරයක් ඉටු කළ හැකි අතර, මෙහි පරායත්ත එන්නත් කිරීම වළේ පැමිණේ.
ඇත්ත වශයෙන්ම, ජාවාහි ඔබ A පන්තිය සහ B පන්තිය ලෙස වෙනස් පන්ති දෙකක් නිර්මාණය කර ඇතැයි සිතමු. B පන්තියේ ඇති ඕනෑම කාර්යයක් ඔබට A පන්තියේදී භාවිතා කිරීමට අවශ්ය නම්, එම අවස්ථාවේ දී පරායත්ත එන්නත් භාවිතා කළ හැකිය. එහිදී ඔබට එක් පන්තියක වස්තුවක් අනෙක් පන්තියේ කූඩාරම් කළ හැකි අතර, ඒ ආකාරයෙන්ම ඔබට වෙනත් පන්තියකට සම්පූර්ණ පන්තියක් එන්නත් කළ හැකිය. මේ ආකාරයෙන් යැපීම ජය ගත හැකිය.
ඩිපෙන්ඩන්සි ඉන්ජෙක්ෂන් යනු සරලවම දෙවරක් මැලියම් කිරීම සහ එකම වේලාවක ඒවා වෙන්කර තබා ගැනීමයි.