ඉතින් සිංගල්ටන් නරකයි, එහෙනම් මොකක්ද?


571

සිංගල්ටන් භාවිතා කිරීමේ (සහ අධික ලෙස භාවිතා කිරීමේ) ගැටළු පිළිබඳව මෑතකදී විශාල කතාබහක් ඇති විය. මගේ වෘත්තීය ජීවිතයේ මීට පෙරත් මමත් ඒ අයගෙන් කෙනෙක්. මට දැන් ගැටලුව කුමක්දැයි දැක ගත හැකිය, එහෙත් තවමත්, මට හොඳ විකල්පයක් දැකිය නොහැකි අවස්ථා බොහෝමයක් ඇත - සහ සිංගල්ටන් විරෝධී සාකච්ඡා බොහොමයක් ඇත්ත වශයෙන්ම එකක් සපයන්නේ නැත.

මෑතදී මා සම්බන්ධ වූ ප්‍රධාන ව්‍යාපෘතියක සැබෑ උදාහරණයක් මෙන්න:

යෙදුම බොහෝ විට යාවත්කාලීන නොවන සේවාදායක තත්වයෙන් විශාල දත්ත ප්‍රමාණයක් භාවිතා කරන වෙනම තිර සහ සංරචක සහිත client න සේවාදායකයෙකි. මෙම දත්ත මූලික වශයෙන් සිංගල්ටන් "කළමණාකරු" වස්තුවක තැන්පත් කර ඇත - භයානක "ගෝලීය තත්වය". යෙදුම තුළ දත්ත එක්රැස් කර සමමුහුර්තව තබා ගන්නා යෙදුමේ මෙම එක් ස්ථානයක් තිබීම අදහස විය, පසුව විවෘත කරන ඕනෑම නව තිරයකට සේවාදායකයෙන් විවිධ උපකාරක දත්ත සඳහා පුනරාවර්තන ඉල්ලීම් නොකර ඔවුන්ට එතැන් සිට අවශ්‍ය බොහෝ දේ විමසිය හැකිය. සේවාදායකයා වෙත නිරන්තරයෙන් ඉල්ලීම ඕනෑවට වඩා කලාප පළලක් ගතවනු ඇත - තවද මම සතියකට ඩොලර් දහස් ගණනක් අමතර අන්තර්ජාල බිල්පත් කතා කරමි, එබැවින් එය පිළිගත නොහැකිය.

මූලික වශයෙන් මේ ආකාරයේ ගෝලීය දත්ත කළමණාකරු හැඹිලි වස්තුවක් තිබීමට වඩා සුදුසු වෙනත් ප්‍රවේශයක් මෙහි තිබේද? මෙම වස්තුව නිල වශයෙන් “සිංගල්ටන්” විය යුතු නැත, නමුත් එය සංකල්පමය වශයෙන් එකක් වීම අර්ථවත් කරයි. මෙහි හොඳ පිරිසිදු විකල්පයක් කුමක්ද?


10
විසඳීමට සිංගල්ටන් භාවිතා කිරීම යනු කුමක්ද? විකල්පයන්ට (ස්ථිතික පන්තියක් වැනි) වඩා එම ගැටළුව විසඳීම වඩා හොඳ වන්නේ කෙසේද?
ඇනොන්.

17
On ඇනොන්: ස්ථිතික පංතියක් භාවිතා කිරීමෙන් තත්වය වඩාත් යහපත් වන්නේ කෙසේද? තවමත් තද කප්ලිං තිබේද?
මාටින් යෝක්

6
Art මාටින්: මම යෝජනා කරන්නේ නැහැ එය “වඩා හොඳ” කරයි කියලා. මම යෝජනා කරන්නේ බොහෝ අවස්ථාවලදී සිංගල්ටන් යනු ගැටලුවක් සෙවීමේ විසඳුමකි.
ඇනොන්.

9
@ අනොන්: ඇත්ත නොවේ. ස්ථිතික පංති මඟින් ඔබට ක්ෂණිකකරණය පාලනය කළ නොහැකි අතර බහු-නූල් කිරීම සිංගල්ටන් වලට වඩා දුෂ්කර කරයි (ඔබට උදාහරණය වෙනුවට සෑම තනි ක්‍රමයකටම අනුක්‍රමිකව ප්‍රවේශ විය යුතු බැවින්). ස්ථිතික පංතිවලට නොහැකි අතුරු මුහුණතක් වත් සිංගල්ටෝනවලට ක්‍රියාත්මක කළ හැකිය. ස්ථිතික පංතිවලට නිසැකවම ඒවායේ වාසි ඇත, නමුත් මේ අවස්ථාවේ දී සිංගල්ටන් අනිවාර්යයෙන්ම සැලකිය යුතු නපුර දෙකකට වඩා අඩුය. ඕනෑම විකෘති තත්වයක් ක්‍රියාවට නංවන ස්ථිතික පංතියක් විශාල දැල්වෙන නියොන් වැනි ය "අවවාදයයි: නරක සැලසුම!" ලකුණ.
ආරොනොට්

7
Aaaronaught: ඔබ සිංගල්ටන් වෙත ප්‍රවේශය සමමුහුර්ත කරන්නේ නම්, එවිට ඔබේ සහසම්බන්ධය බිඳී යනු ඇත. සිංගල්ටන් වස්තුව ලබාගත් විගසම ඔබේ නූල් බාධා කළ හැකිය, තවත් නූල් එකක් පැමිණේ. ස්ථිතික පංතියක් වෙනුවට සිංගල්ටන් භාවිතා කිරීම, බොහෝ විට, අනතුරු ඇඟවීමේ සං away ා ඉවතට ගෙන ගැටලුව විසඳන සිතුවිල්ලකි .
ඇනොන්.

Answers:


838

තනි අවස්ථා සහ සිංගල්ටන් සැලසුම් රටාව අතර වෙනස හඳුනා ගැනීම වැදගත්ය .

තනි අවස්ථා හුදෙක් යථාර්ථයකි. බොහෝ යෙදුම් නිර්මාණය කර ඇත්තේ වරකට එක් වින්‍යාසයක්, වරකට එක් යූඅයි එකක්, වරකට එක් ගොනු පද්ධතියක් සහ යනාදිය සමඟ වැඩ කිරීමට පමණි. නඩත්තු කළ යුතු රාජ්‍ය හෝ දත්ත විශාල ප්‍රමාණයක් තිබේ නම්, නිසැකවම ඔබට අවශ්‍ය වන්නේ එක් අවස්ථාවක් පමණක් තබා එය හැකි තාක් කල් සජීවීව තබා ගැනීමයි.

මෙම සිංගල්ටන් නිර්මාණය රටාව ඉතා විශේෂිත වේ වර්ගය තනි අවස්ථා, බව විශේෂයෙන් එක්:

  • ගෝලීය, ස්ථිතික නිදර්ශන ක්ෂේත්‍රයක් හරහා ප්‍රවේශ විය හැකිය;
  • වැඩසටහන් ආරම්භයේදී හෝ පළමු ප්‍රවේශය මත නිර්මාණය කරන ලදි;
  • පොදු ඉදිකිරීම්කරුවෙකු නැත (කෙලින්ම ක්ෂණිකව දැක්විය නොහැක);
  • කිසි විටෙකත් පැහැදිළිව නිදහස් කර නැත (වැඩසටහන් අවසන් කිරීමෙන් ව්‍යංගයෙන් නිදහස් වේ).

රටාව දිගු කාලීන ගැටළු කිහිපයක් හඳුන්වා දෙන්නේ මෙම විශේෂිත සැලසුම් තේරීම නිසා ය:

  • වියුක්ත හෝ අතුරු මුහුණත් පන්ති භාවිතා කිරීමට ඇති නොහැකියාව;
  • උප පංතියට ඇති නොහැකියාව;
  • යෙදුම හරහා ඉහළ සම්බන්ධ කිරීම (වෙනස් කිරීමට අපහසු);
  • පරීක්ෂා කිරීමට අපහසුය (ඒකක පරීක්ෂණ වලදී ව්‍යාජ / සමච්චල් කළ නොහැක);
  • විකෘති තත්වයේ දී සමාන්තරගත කිරීම දුෂ්කර (පුළුල් අගුලු දැමීම අවශ්‍ය වේ);
  • සහ යනාදි.

මෙම රෝග ලක්ෂණ කිසිවක් ඇත්ත වශයෙන්ම තනි අවස්ථාවන්ට ආවේණික නොවේ, සිංගල්ටන් රටාව පමණි.

ඒ වෙනුවට ඔබට කුමක් කළ හැකිද? සරලවම සිංගල්ටන් රටාව භාවිතා නොකරන්න.

ප්රශ්නයෙන් උපුටා දැක්වීම:

යෙදුම තුළ දත්ත එක්රැස් කර සමමුහුර්තව තබා ගන්නා යෙදුමේ මෙම එක් ස්ථානයක් තිබීම අදහස විය, පසුව විවෘත කරන ඕනෑම නව තිරයකට සේවාදායකයෙන් විවිධ උපකාරක දත්ත සඳහා පුනරාවර්තන ඉල්ලීම් නොකර, එතැන් සිට ඔවුන්ට අවශ්‍ය බොහෝ දේ විමසිය හැකිය. සේවාදායකයා වෙත නිරන්තරයෙන් ඉල්ලීම ඕනෑවට වඩා කලාප පළලක් ගතවනු ඇත - මම සතියකට ඩොලර් දහස් ගණනක් අමතර අන්තර්ජාල බිල්පත් කතා කරමි, එබැවින් එය පිළිගත නොහැකිය.

ඔබ ඉඟි කරන නමුත් අවිනිශ්චිත බවක් පෙනෙන පරිදි මෙම සංකල්පයට නමක් ඇත. එය හැඳින්වූයේ වෙනවා හැඹිලි . ඔබට විසිතුරු බවක් ලබා ගැනීමට අවශ්‍ය නම් ඔබට එය "නොබැඳි හැඹිලියක්" හෝ දුරස්ථ දත්තවල නොබැඳි පිටපතක් ලෙස හැඳින්විය හැකිය.

හැඹිලියක් තනි පුද්ගලයෙකු වීමට අවශ්‍ය නොවේ. එය විය හැක ඔබ සතුව හැඹිලි අවස්ථා සඳහා එම දත්ත තර්ජනයක් වළක්වා ගැනීමට අවශ්ය නම් එක් උදාහරණයක් විය යුතුය; නමුත් එයින් අදහස් කරන්නේ ඔබ සැබවින්ම සියල්ලන්ටම නිරාවරණය කළ යුතු බව නොවේ .

මම කළ යුතු පළමු දෙය නම් හැඹිලියේ විවිධ ක්‍රියාකාරී ප්‍රදේශ වෙනම අතුරුමුහුණත් වලට වෙන් කිරීමයි. උදාහරණයක් ලෙස, ඔබ මයික්‍රොසොෆ්ට් ප්‍රවේශය මත පදනම්ව ලොව නරකම යූ ටියුබ් ක්ලෝනය සෑදූ බව කියමු:

                          MSAccessCache
                                ▲
                                |
              + ----------------- + ----------------- +
              | | |
         IMediaCache IProfileCache IPageCache
              | | |
              | | |
          VideoPage MyAccountPage MostPopularPage

මෙහිදී ඔබට කිහිපයක් අතුරු මුහුණත් විස්තර කරන විශේෂිත මාධ්ය, පරිශීලක පැතිකඩ, සහ ස්ථිතික පිටු (මුල් පිටුවේ වැනි) - දත්ත වර්ග යම් පන්තිය ප්රවේශය අවශ්ය විය හැක. ඒ සියල්ල එක් මෙගා හැඹිලියක් මඟින් ක්‍රියාත්මක කරනු ලැබේ, නමුත් ඒ වෙනුවට අතුරුමුහුණත් පිළිගැනීමට ඔබ ඔබේ තනි පන්ති සැලසුම් කරයි, එබැවින් ඔවුන් සතුව කුමන ආකාරයේ අවස්ථාවක් තිබේද යන්න ඔවුන් ගණන් ගන්නේ නැත. ඔබේ වැඩසටහන ආරම්භ වූ විට ඔබ එක් වරක් භෞතික අවස්ථාව ආරම්භ කර, පසුව ඉදිකිරීම්කරුවන් සහ පොදු දේපල හරහා සිදුවීම් (විශේෂිත අතුරුමුහුණත් වර්ගයකට දමන්න) ආරම්භ කරන්න.

මෙය යැපුම් එන්නත් කිරීම ලෙස හැඳින්වේ . ඔබේ සාමාන්‍ය පංතියේ සැලසුම , ඇමතුම්කරුගේ පරායත්තතාවයන් තමන් විසින්ම ස්ථාපනය කිරීම හෝ ගෝලීය තත්වය සඳහන් කිරීම වෙනුවට පිළිගන්නා තාක් කල් ඔබට වසන්තය හෝ විශේෂ අයිඕසී බහාලුමක් භාවිතා කිරීමට අවශ්‍ය නොවේ .

ඔබ අතුරු මුහුණත පදනම් කරගත් සැලසුම භාවිතා කළ යුත්තේ ඇයි? හේතු තුනක්:

  1. එය කේතය කියවීමට පහසු කරයි; යැපෙන පංති රඳා පවතින්නේ කුමන දත්තද යන්න ඔබට අතුරුමුහුණත් වලින් පැහැදිලිව තේරුම් ගත හැකිය .

  2. දත්ත පසුපෙළක් සඳහා මයික්‍රොසොෆ්ට් ඇක්සස් හොඳම තේරීම නොවන බව ඔබ තේරුම් ගත් විට, ඔබට එය වඩා හොඳ දෙයක් සමඟ ප්‍රතිස්ථාපනය කළ හැකිය - අපි SQL සේවාදායකය යැයි කියමු.

  3. SQL සේවාදායකය විශේෂයෙන් මාධ්‍ය සඳහා හොඳම තේරීම නොවන බව ඔබ තේරුම් ගත් විට , පද්ධතියේ වෙනත් කිසිදු කොටසකට බලපෑම් නොකර ඔබේ ක්‍රියාත්මක කිරීම බිඳ දැමිය හැකිය . වියුක්ත කිරීමේ සැබෑ බලය එන්නේ එතැනිනි.

ඔබට එය තවත් පියවරක් ඉදිරියට ගෙන යාමට අවශ්‍ය නම් ඔබට වසන්තය (ජාවා) හෝ යුනිටි (.නෙට්) වැනි අයිඕසී බහාලුමක් (ඩීඅයි රාමුව) භාවිතා කළ හැකිය. සෑම DI රාමුවක්ම පාහේ තමන්ගේම ජීවිත කළමණාකරණයක් සිදු කරනු ඇති අතර නිශ්චිත සේවාවක් තනි අවස්ථාවක් ලෙස අර්ථ දැක්වීමට ඔබට විශේෂයෙන් ඉඩ දෙයි (බොහෝ විට එය "සිංගල්ටන්" ලෙස හැඳින්වේ, නමුත් එය හුරුපුරුදුකම සඳහා පමණි). මූලික වශයෙන් මෙම රාමු මඟින් බොහෝ අවස්ථාවන්හිදී අතින් ගමන් කිරීමේ වඳුරු වැඩ වලින් ඔබව බේරා ගනී, නමුත් ඒවා දැඩි ලෙස අවශ්‍ය නොවේ. මෙම සැලසුම ක්‍රියාත්මක කිරීම සඳහා ඔබට විශේෂ මෙවලම් අවශ්‍ය නොවේ.

සම්පූර්ණත්වය උදෙසා, මා පෙන්වා දිය යුත්තේ ඉහත සැලසුම සැබවින්ම පරමාදර්ශී නොවන බවයි. ඔබ හැඹිලියක් සමඟ ගනුදෙනු කරන විට (ඔබ මෙන්), ඔබට ඇත්ත වශයෙන්ම සම්පූර්ණයෙන්ම වෙනම තට්ටුවක් තිබිය යුතුය . වෙනත් වචන වලින් කිවහොත්, මෙවැනි නිර්මාණයක්:

                                                        + - IMediaRepository
                                                        |
                          හැඹිලිය (සාමාන්‍ය) --------------- + - IProfileRepository
                                ▲ |
                                | + - IPageRepository
              + ----------------- + ----------------- +
              | | |
         IMediaCache IProfileCache IPageCache
              | | |
              | | |
          VideoPage MyAccountPage MostPopularPage

මෙහි ඇති වාසිය Cacheනම්, ඔබ ප්‍රතික්‍රියාකාරකයක් කිරීමට තීරණය කරන්නේ නම් කිසි විටෙකත් ඔබේ අවස්ථාව බිඳ දැමීමට අවශ්‍ය නොවේ ; විකල්පයක් ක්‍රියාත්මක කිරීමෙන් පෝෂණය කිරීමෙන් මාධ්‍ය සරලව ගබඩා කර ඇති ආකාරය ඔබට වෙනස් කළ හැකිය IMediaRepository. මෙය එකට ගැලපෙන්නේ කෙසේදැයි ඔබ සිතන්නේ නම්, එය තවමත් හැඹිලියේ එක් භෞතික අවස්ථාවක් පමණක් නිර්මාණය කරන බව ඔබට පෙනෙනු ඇත, එබැවින් ඔබ කිසි විටෙකත් එකම දත්ත දෙවරක් ලබා ගැනීමට අවශ්‍ය නොවේ.

ලෝකයේ සෑම මෘදුකාංගයක්ම ඉහළ සහජීවනය සහ ලිහිල් සම්බන්ධතාවයේ මෙම නිශ්චිත ප්‍රමිතීන්ට අනුකූලව සැකසිය යුතු බව මේ කිසිවක් නොකියයි; එය ව්‍යාපෘතියේ ප්‍රමාණය, විෂය පථය, ඔබේ කණ්ඩායම, ඔබේ අයවැය, නියමිත දින ආදිය මත රඳා පවතී. නමුත් ඔබ අසන්නේ හොඳම නිර්මාණය කුමක්ද (සිංගල්ටන් වෙනුවට භාවිතා කිරීම), එවිට මෙය එයයි.

ප්රාදේශීය සභා අය සඳහන් කර ඇති පරිදි, එය රඳා පන්ති ඔවුන් භාවිතා කරන දැනුවත් කිරීමට ඇති හොඳම අදහසක් නොවේ, බොහෝ දුරට හැඹිලි ඒවා හුදෙක් ගැන සැලකිලිමත් නොකළ යුතු ක්රියාත්මක කිරීමේ විස්තර බව -. මෙසේ පැවසුවහොත්, සමස්ත ගෘහ නිර්මාණ ශිල්පය තවමත් ඉහත පින්තූරයේ ඇති දේට බොහෝ සෙයින් සමාන වනු ඇත, ඔබ තනි අතුරුමුහුණත් හැඹිලි ලෙස සඳහන් නොකරයි . ඒ වෙනුවට ඔබ ඔවුන්ට සේවා හෝ ඒ හා සමාන දෙයක් නම් කරන්න.


139
ගෝලීය රාජ්‍යයට විකල්පයක් ලෙස DI පැහැදිලි කරන මා කියවූ පළමු ලිපිය. මේ සඳහා දැරූ කාලය හා වෑයමට ස්තූතියි. මෙම තනතුරේ ප්‍රති result ලයක් ලෙස අප සැවොම හොඳය.
මිස්ටර් ලේන්

4
හැඹිලිය තනි පුද්ගලයෙකු විය නොහැක්කේ ඇයි? ඔබ එය පසුකර යැපුම් එන්නත් භාවිතා කරන්නේ නම් එය තනි පුද්ගලයෙක් නොවේද? සිංගල්ටන් යනු අපව එක් අවස්ථාවකට පමණක් සීමා කිරීම මිස එය නිවැරදිව ප්‍රවේශ වන ආකාරය ගැන නොවේද? මේ පිළිබඳව මා ගන්නා පියවර බලන්න: assoc.tumblr.com/post/51302471844/the-misunderstood-singleton
එරික් එන්හයිම්

29
D ඇඩම්ස්මිත්: ඔබ ඇත්තටම මෙම පිළිතුර කිසිවක් කියවා තිබේද ? ඔබේ ප්‍රශ්නයට පළමු ඡේද දෙකෙන් පිළිතුරු සපයයි. තනි රටාව! == තනි අවස්ථාව.
ආරොනොට්

6
Aw කවාස් සහ ඇඩම් ස්මිත් - ඔබේ සබැඳි කියවීමෙන් ඔබ මෙම පිළිතුර සැබවින්ම කියවා නැති බව මට හැඟේ - සෑම දෙයක්ම දැනටමත් එහි තිබේ.
විල්බර්ට්

19
Aw කැවාස් මෙම පිළිතුරේ මස් යනු තනි-අවස්ථාව සහ සිංගල්ටන් අතර වෙනස බව මට හැඟේ. සිංගල්ටන් නරකයි, තනි අවස්ථාවක් නොවේ. පරායත්ත එන්නත් කිරීම යනු තනි බොත්තම් භාවිතා නොකර තනි අවස්ථා භාවිතා කිරීමට හොඳ, සාමාන්‍ය ක්‍රමයකි.
විල්බර්ට්

48

ඔබ ලබා දෙන අවස්ථාවෙහිදී, එය පෙනෙන්නේ සිංගල්ටන් භාවිතා කිරීම ගැටළුව නොව ගැටළුවක රෝග ලක්ෂණයයි - විශාල, වාස්තු විද්‍යාත්මක ගැටළුවක්.

දත්ත සඳහා හැඹිලි වස්තුව තිරයන් විමසන්නේ ඇයි? හැඹිලිය සේවාදායකයාට විනිවිද පෙනෙන විය යුතුය. දත්ත සැපයීම සඳහා සුදුසු සාරාංශයක් තිබිය යුතු අතර, එම සාරාංශය ක්‍රියාත්මක කිරීමෙන් හැඹිලි භාවිතා කළ හැකිය.

ගැටළුව වන්නේ පද්ධතියේ කොටස් අතර පරායත්තයන් නිවැරදිව සකසා නොමැති අතර මෙය බොහෝ විට පද්ධතිමය වීමයි.

තිර වලට ඔවුන්ගේ දත්ත ලබා ගත හැකි ස්ථානය පිළිබඳ දැනුමක් තිබිය යුත්තේ ඇයි? දත්ත සඳහා ඔවුන්ගේ ඉල්ලීම් ඉටු කළ හැකි වස්තුවක් තිරවලට ලබා නොදෙන්නේ ඇයි (හැඹිලිය පිටුපස සැඟවී ඇත). බොහෝ විට තිර නිර්මාණය කිරීමේ වගකීම මධ්‍යගත නොවන අතර එම නිසා පරායත්තයන් එන්නත් කිරීමේ පැහැදිලි කරුණක් නොමැත.

නැවතත්, අපි මහා පරිමාණ වාස්තු විද්‍යාත්මක හා සැලසුම් ගැටළු පිළිබඳව සොයා බලමු.

එසේම, වස්තුවක ආයු කාලය මුළුමනින්ම දික්කසාද කළ හැක්කේ වස්තුව භාවිතය සඳහා සොයාගත් ආකාරය අනුව බව තේරුම් ගැනීම ඉතා වැදගත් වේ .

හැඹිලියක් යෙදුමේ ජීවිත කාලය පුරාම ජීවත් වීමට සිදුවනු ඇත (ප්‍රයෝජනවත් වීමට), එම නිසා වස්තුවේ ආයු කාලය සිංගල්ටන් ය.

නමුත් සිංගල්ටන් සමඟ ඇති ගැටළුව (අවම වශයෙන් ස්ථිතික පංතියක් / දේපලක් ලෙස සිංගල්ටන් ක්‍රියාත්මක කිරීම), එය භාවිතා කරන වෙනත් පංති එය සොයා ගන්නේ කෙසේද යන්නයි.

ස්ථිතික සිංගල්ටන් ක්‍රියාත්මක කිරීමත් සමඟ සම්මුතිය යනු අවශ්‍ය ඕනෑම තැනක එය භාවිතා කිරීමයි. නමුත් එය යැපීම මුළුමනින්ම සඟවන අතර පංති දෙක තදින් බැඳ තබයි.

අපි නම් ලබා පන්ති සඳහා පරායත්ත බව පරායත්ත පැහැදිලි වන අතර, සියලු පානය පන්තියේ දැනුම තිබිය යුතු එය භාවිතා කිරීම සඳහා ලබා ගත හැකි මෙම කොන්ත්රාත්තුව වේ.


2
ඇතැම් තිරවලට අවශ්‍ය විය හැකි විශාල දත්ත ප්‍රමාණයක් ඇත, නමුත් අවශ්‍ය නොවේ. මෙය නිර්වචනය කරන පරිශීලක ක්‍රියාමාර්ග ගන්නා තෙක් ඔබ නොදනී - සහ බොහෝ සංයෝජන ඇත. එබැවින් එය සිදු කරන ආකාරය වූයේ සේවාදායකයා තුළ හැඹිලි සහ සමමුහුර්ත කර ඇති පොදු ගෝලීය දත්ත කිහිපයක් තිබීමයි (වැඩි වශයෙන් පිවිසීමේදී ලබාගෙන ඇත), පසුව කරන ලද ඉල්ලීම් මඟින් හැඹිලිය වැඩි කරයි, මන්ද පැහැදිලිවම ඉල්ලා ඇති දත්ත නැවත භාවිතා කිරීමට නැඹුරු වන බැවිනි. එකම සැසිය. සේවාදායකයා වෙත ඉල්ලීම අඩු කිරීම කෙරෙහි අවධානය යොමු කෙරේ, එබැවින් සේවාදායක පාර්ශවීය හැඹිලියක අවශ්‍යතාවය. <cont>
බොබී වගු

1
<cont> එය අත්‍යවශ්‍යයෙන්ම විනිවිද පෙනෙන ය. අවශ්‍ය දත්ත තවමත් හැඹිලිගත කර නොමැති නම් සේවාදායකයෙන් ඇමතුමක් ලබා ගත හැකිය. නමුත් එම හැඹිලි කළමණාකරු (තාර්කිකව හා භෞතිකව) ක්‍රියාත්මක කිරීම සිංගල්ටන් ය.
බොබී වගු

6
මම මෙහි qstarin සමඟ සිටිමි: දත්ත වලට ප්‍රවේශ වන වස්තූන් දත්ත හැඹිලිගත කර ඇති බව නොදැන සිටිය යුතුය (හෝ දැන ගැනීමට අවශ්‍යය) (එය ක්‍රියාත්මක කිරීමේ විස්තරයකි). දත්ත භාවිතා කරන්නන් හුදෙක් දත්ත ඉල්ලයි (නැතහොත් දත්ත ලබා ගැනීමට අතුරු මුහුණතක් ඉල්ලන්න).
මාටින් යෝක්

1
හැඹිලිය අත්‍යවශ්‍යයෙන්ම ක්‍රියාත්මක කිරීමේ විස්තරයකි. දත්ත විමසන අතුරු මුහුණතක් ඇති අතර, එය ලබා ගන්නා වස්තූන් එය හැඹිලියෙන් පැමිණියේ ද නැද්ද යන්න නොදනී. නමුත් මෙම හැඹිලි කළමනාකරුට යටින් සිංගල්ටන් ය.
බොබී වගු

2
Ob බොබී වගු: එවිට ඔබේ තත්වය පෙනෙන තරම් දරුණු නොවේ. එම සිංගල්ටන් (ඔබ අදහස් කරන්නේ ස්ථිතික පංතියක් යැයි උපකල්පනය කිරීම, යෙදුම පවතින තාක් කල් ජීවත්වන නිදසුනක් සහිත වස්තුවක් නොවේ) තවමත් ගැටළු සහගතය. ඔබගේ දත්ත සපයන වස්තුව හැඹිලි සැපයුම්කරුවෙකු මත යැපීමක් ඇති බව එය සඟවයි. එය පැහැදිලිව හා බාහිරකරණය කර ඇත්නම් වඩා හොඳය. ඒවා විසන්ධි කරන්න. එය අත්යවශ්ය ඔබට පහසුවෙන් ආදේශකයක් සංරචක හැකි බව testability සඳහා, සහ හැඹිලි සපයන්නා වන්නේ අගමැති එවැනි අංගයක් (ASP.Net විසින් පිටුබලය තොගයක් සැපයුම්කරු ආකාරය බොහෝ විට) උදාහරණයක්.
quentin-starin

45

මම මේ ප්‍රශ්නය ගැන සම්පූර්ණ පරිච්ඡේදයක්ම ලිව්වා . බොහෝ දුරට ක්‍රීඩා සන්දර්භය තුළ, නමුත් බොහෝ ඒවා ක්‍රීඩා වලින් පිටත අදාළ විය යුතුය.

tl; dr:

කල්ලියේ සිව් සිංගල්ටන් රටාව කාරණා දෙකක් කරයි: ඕනෑම තැනක සිට වස්තුවකට ඔබට පහසුවක් ලබා දිය හැකි අතර, එහි එක් අවස්ථාවක් පමණක් නිර්මාණය කළ හැකි බවට සහතික වන්න. 99% ක්ම, ඔබ සැලකිලිමත් වන්නේ එහි පළමු භාගය වන අතර, දෙවන භාගය පුරාම එය ලබා ගැනීම සඳහා කරත්ත දැමීම අනවශ්‍ය සීමාවක් එක් කරයි.

එපමණක් නොව, පහසු ප්‍රවේශයක් ලබා දීම සඳහා වඩා හොඳ විසඳුම් තිබේ. වස්තුවක් ගෝලීය කිරීම එය විසඳීම සඳහා න්‍යෂ්ටික විකල්පය වන අතර එය ඔබේ සංසරණය විනාශ කිරීමට පහසු කරයි. ග්ලෝබල් ගැන නරක වන සෑම දෙයක්ම තනි පුද්ගලයන්ට සම්පූර්ණයෙන්ම අදාළ වේ.

ඔබ එය භාවිතා කරන්නේ නම් ඔබට අවශ්ය එකම වස්තුව ස්පර්ශ කිරීමට බව කේතය ස්ථාන ගොඩක් ඇති නිසා, එය ලබා දීමට වඩා හොඳ ක්රමයක් සොයා ගැනීමට උත්සාහ පමණක් මුළු codebase එය හෙළි නොකර එම වස්තූන්. වෙනත් විසඳුම්:

  • එය සම්පූර්ණයෙන්ම ඉවත් කරන්න. කිසිදු රාජ්‍යයක් නොමැති සහ උපකාරක ක්‍රියාකාරකම්වල බෑග් වන සිංගල්ටන් පංති රාශියක් මම දැක ඇත්තෙමි. ඔවුන්ට කිසිසේත්ම උදාහරණයක් අවශ්‍ය නොවේ. ඒවා ස්ථිතික ශ්‍රිතයක් බවට පත් කරන්න, නැතහොත් ශ්‍රිතය තර්කයක් ලෙස ගන්නා එක් පන්තියකට ගෙන යන්න. Mathඔබට කළ හැකි නම් ඔබට විශේෂ පන්තියක් අවශ්‍ය නොවනු ඇත 123.Abs().

  • එය වටා ගමන් කරන්න. ක්‍රමයකට වෙනත් වස්තුවක් අවශ්‍ය නම් සරල විසඳුම නම් එය ඇතුළට ගෙන යාමයි. සමහර වස්තූන් වටා ගමන් කිරීමේ කිසිදු වරදක් නැත.

  • එය මූලික පන්තියට දමන්න. ඔබට කිසියම් විශේෂ වස්තුවකට ප්‍රවේශය අවශ්‍ය පංති රාශියක් තිබේ නම් සහ ඔවුන් මූලික පංතියක් බෙදා ගන්නේ නම්, ඔබට එම වස්තුව පාදමේ සාමාජිකයෙකු බවට පත් කළ හැකිය. ඔබ එය සාදන විට, වස්තුව තුළට යන්න. දැන් ව්‍යුත්පන්න වස්තූන් සියල්ලටම අවශ්‍ය විටෙක එය ලබා ගත හැකිය. ඔබ එය ආරක්‍ෂිත කළහොත්, වස්තුව තවමත් සංවෘතව පවතින බව ඔබ සහතික කරයි.


1
ඔබට මෙහි සාරාංශගත කළ හැකිද?
නිකොල්

1
සිදු විය, නමුත් සම්පූර්ණ පරිච්ඡේදය කියවීමට මම තවමත් ඔබව දිරිමත් කරමි.
අතිවිශිෂ්ට

4
තවත් විකල්පයක්: යැපුම් එන්නත් කිරීම!
බ්‍රැඩ් කූපිට්

1
@ බ්‍රැඩ්කූපිට් ඔහු ඒ ගැන සබැඳියෙන් ද කතා කරයි ... මම කිව යුතුයි මම තවමත් ඒ සියල්ල ජීර්ණය කිරීමට උත්සාහ කරමි. නමුත් එය මා මෙතෙක් කියවා ඇති සිංගල්ටන්වල ​​වඩාත්ම පැහැදිලිව කියවා ඇත. මේ දක්වා, මම ධනාත්මක singletons පමණක් ගෝලීය vars මෙන් අවශ්ය විය, මම ඒ ලදී ප්රවර්ධනය වන මෙවලම් ගොන්න . දැන් මම තවදුරටත් නොදනිමි. සේවා ලොකේටරය ස්ථිතික මෙවලම් පෙට්ටියක් නම් ඔබට කිව හැකිද? එය සිංගල්ටන් එකක් බවට පත් කිරීම වඩා හොඳ නොවේද (මේ අනුව, මෙවලම් පෙට්ටියක්)?
cregox

1
"මෙවලම් පෙට්ටිය" මට "සේවා ලොකේටර්" ට සමාන ය. ඔබ ඒ සඳහා ස්ථිතිකයක් භාවිතා කළත්, නැතහොත් එය තනි පුද්ගලයකු බවට පත් කළත්, බොහෝ වැඩසටහන් සඳහා එය එතරම් වැදගත් නොවන බව මම සිතමි. මම සංඛ්‍යාලේඛන වෙත නැඹුරු වන්නේ ඔබට අවශ්‍ය නැතිනම් කම්මැලි ආරම්භය සහ ගොඩවල් වෙන් කිරීම සමඟ කටයුතු කරන්නේ මන්ද?
ජනයා එක

21

එහි ගෝලීය තත්වය නොවේ.

ඇත්ත වශයෙන්ම ඔබ කනස්සල්ලට පත්විය යුතුය global mutable state. නිරන්තර තත්වයට අතුරු ආබාධවලින් බලපෑමක් නොවන අතර එමඟින් ගැටළුවක් අඩු වේ.

සිංගල්ටන් සමඟ ඇති ප්‍රධානතම කාරණය නම්, එය කප්ලිං එකතු කරන අතර එමඟින් දැඩි (එර්) පරීක්ෂා කිරීම වැනි දේ කරයි. වෙනත් ප්‍රභවයකින් සිංගල්ටන් ලබා ගැනීමෙන් ඔබට සම්බන්ධතාවය අඩු කළ හැකිය (උදා: කර්මාන්ත ශාලාවක්). විශේෂිත අවස්ථාවකින් කේතය විකේතනය කිරීමට මෙය ඔබට ඉඩ සලසයි (ඔබ කර්මාන්තශාලාවට වැඩි සම්බන්ධතාවයක් දැක්වුවද (නමුත් අවම වශයෙන් කර්මාන්ත ශාලාවට විවිධ අදියරයන් සඳහා විකල්ප ක්‍රියාත්මක කිරීම් තිබිය හැකිය)).

ඔබගේ තත්වය තුළ ඔබේ සිංගල්ටන් ඇත්ත වශයෙන්ම අතුරු මුහුණතක් ක්‍රියාත්මක කරන තාක් කල් ඔබට එයින් ගැලවිය හැකි යැයි මම සිතමි (එවිට වෙනත් අවස්ථාවන්හිදී විකල්පයක් භාවිතා කළ හැකිය).

නමුත් සිංගල්ටන් සමඟ ඇති තවත් ප්‍රධාන පසුබෑමක් නම්, ඒවා ස්ථානගත වූ පසු ඒවා කේතයෙන් ඉවත් කර වෙනත් දෙයක් සමඟ ප්‍රතිස්ථාපනය කිරීම සැබෑ දුෂ්කර කාර්යයක් බවට පත්වීමයි (නැවත එම සම්බන්ධතාවය පවතී).

// Example from 5 minutes (con't be too critical)
class ServerFactory
{
    public:
        // By default return a RealServer
        ServerInterface& getServer();

        // Set a non default server:
        void setServer(ServerInterface& server);
};

class ServerInterface { /* define Interface */ };

class RealServer: public ServerInterface {}; // This is a singleton (potentially)

class TestServer: public ServerInterface {}; // This need not be.

එය අර්ථවත් කරයි. මෙය මා සිතන්නේ මා කිසි විටෙකත් සිංගල්ටන් අපයෝජනයට ලක් නොකළ නමුත් ඒවා භාවිතා කිරීම ගැන සැක කිරීමට පටන් ගත් බවය. නමුත් මෙම කරුණු අනුව මා විසින් කර ඇති කිසිදු අපයෝජනයක් ගැන සිතිය නොහැක. :)
බොබී වගු

2
(ඔබ බොහෝ විට අදහස් අනුව SE "කියා එක්" නොවේ)
nohat

4
@nohat: මම "ක්වීන්ස් ඉංග්‍රීසි" හි ස්වදේශීය කථිකයෙක් වන අතර, එබැවින් අපි එය වඩා හොඳ නොකරන්නේ නම් ප්‍රංශ පෙනුම ප්‍රතික්ෂේප කරයි ( le weekendඅපොයි එය අපේ එකක් වැනි). ස්තූතියි :-)
මාටින් යෝක්

21
per se යනු ලතින් ය.
ඇනොන්.

2
@ අනොන්: හරි. එය එතරම් නරක නැත ;-)
මාටින් යෝක්

20

එහෙනම් මොකක්ද? කිසිවෙකු එය නොකියූ බැවින්: මෙවලම් පෙට්ටිය . ඔබට ගෝලීය විචල්‍යයන් අවශ්‍ය නම් එයයි .

ගැටළුව වෙනත් කෝණයකින් බැලීමෙන් සිංගල්ටන් අපයෝජනය වළක්වා ගත හැකිය. යෙදුමකට අවශ්‍ය වන්නේ පන්තියේ එක් අවස්ථාවක් පමණක් යැයි සිතමු. යෙදුම ආරම්භයේදීම එම පන්තිය වින්‍යාස කරයි: තනි පුද්ගලයකු වීමට පන්තියම වගකිව යුත්තේ ඇයි? යෙදුමට මේ ආකාරයේ හැසිරීමක් අවශ්‍ය බැවින් යෙදුමට මෙම වගකීම භාර ගැනීම තරමක් තර්කානුකූල බව පෙනේ. යෙදුම, සංරචකය නොව, තනි ඒකකය විය යුතුය. යෙදුම පසුව ඕනෑම යෙදුම්-විශේෂිත කේතයක් භාවිතා කිරීම සඳහා සංරචකයේ නිදසුනක් ලබා දෙයි. යෙදුමක් එවැනි සංරචක කිහිපයක් භාවිතා කරන විට, එය අප මෙවලම් පෙට්ටියක් ලෙස හැඳින්වූ දේට එකතු කළ හැකිය.

සරලව කිවහොත්, යෙදුමේ මෙවලම් පෙට්ටිය තනි වින්‍යාසයක් වන අතර එය වින්‍යාස කිරීමට හෝ යෙදුමේ ආරම්භක යාන්ත්‍රණයට එය වින්‍යාස කිරීමට ඉඩ දීම සඳහා වගකිව යුතුය.

public class Toolbox {
     private static Toolbox _instance; 

     public static Toolbox Instance {
         get {
             if (_instance == null) {
                 _instance = new Toolbox(); 
             }
             return _instance; 
         }
     }

     protected Toolbox() {
         Initialize(); 
     }

     protected void Initialize() {
         // Your code here
     }

     private MyComponent _myComponent; 

     public MyComponent MyComponent() {
         get {
             return _myComponent(); 
         }
     }
     ... 

     // Optional: standard extension allowing
     // runtime registration of global objects. 
     private Map components; 

     public Object GetComponent (String componentName) {
         return components.Get(componentName); 
     }

     public void RegisterComponent(String componentName, Object component) 
     {
         components.Put(componentName, component); 
     }

     public void DeregisterComponent(String componentName) {
         components.Remove(componentName); 
     }

}

නමුත් අනුමාන කරන්නේ කුමක්ද? ඒක තනිකඩයෙක්!

සිංගල්ටන් යනු කුමක්ද?

සමහර විට ව්යාකූලත්වය ආරම්භ වන්නේ එතැනිනි.

මට නම්, සිංගල්ටන් යනු එක් අවස්ථාවක් පමණක් සහ සැමවිටම තිබිය යුතු බලයක්. ඔබට එය ක්ෂණිකව අවශ්‍ය නොවී ඕනෑම තැනක, ඕනෑම වේලාවක ප්‍රවේශ විය හැකිය. එය එතරම් සමීපව සම්බන්ධ වන්නේ එබැවිනි static. සංසන්දනය කිරීම සඳහා, staticඑය නිදසුනක් නොවේ නම් හැර, මූලික වශයෙන් එකම දෙයකි. අපට එය ක්ෂණිකව කිරීමට අවශ්‍ය නැත, අපට එය කළ නොහැක, මන්ද එය ස්වයංක්‍රීයව වෙන් කර ඇති බැවිනි. එය ගැටළු ඇති කළ හැකි හා කළ හැකි දෙයකි.

මගේ අත්දැකීම් අනුව, staticසිංගල්ටන් වෙනුවට ආදේශ කිරීම මා සිටින මධ්‍යම ප්‍රමාණයේ පැච් වර්ක් බෑග් ව්‍යාපෘතියක බොහෝ ගැටලු විසඳීය. එයින් අදහස් කරන්නේ එය නරක ලෙස සැලසුම් කරන ලද ව්‍යාපෘති සඳහා යම් භාවිතයක් ඇති බවයි. මම ඕනෑවට වඩා තියෙනවා හිතන්නේ සාකච්ඡා කරන්නේ නම් තනි රටාව වේ ප්රයෝජනවත් නැද්ද හා, එය ඇත්තෙන්ම හිතලූවක් වේ නම් මම ඇත්තටම තර්ක කළ නොහැකි නරක . නමුත් තවමත් ස්ථිතික ක්‍රමවලට වඩා සිංගල්ටන් සඳහා හොඳ තර්ක තිබේ .

සිංගල්ටන් ගැන නරක යැයි මට විශ්වාසයි, හොඳ පුරුදු නොසලකා හරිමින් අපි ඒවා භාවිතා කරන විට. එය ඇත්ත වශයෙන්ම ගනුදෙනු කිරීමට එතරම් පහසු නොවන දෙයකි. නමුත් නරක පුරුදු ඕනෑම රටාවකට යොදා ගත හැකිය. ඒ වගේම, මම දන්නවා, ඒක කියන්න බැරි තරම් සාමාන්‍යයි ... මම කිව්වේ ඒකට ඕනෑවට වඩා දේවල් තියෙනවා.

මාව වැරදියට තේරුම් ගන්න එපා!

සරලව කිවහොත්, වගේ ගෝලීය vars , singletons යුතු තවමත් සෑම විටම මඟ හැරිය . විශේෂයෙන් ඔවුන් අධික ලෙස අපයෝජනයට ලක්වන බැවිනි. නමුත් ගෝලීය වර්‍ගයන් සැමවිටම වළක්වා ගත නොහැකි අතර අප ඒවා අවසාන අවස්ථාවෙහිදී භාවිතා කළ යුතුය.

කෙසේ වෙතත්, මෙවලම් පෙට්ටිය හැර වෙනත් බොහෝ යෝජනා තිබේ, සහ මෙවලම් පෙට්ටිය මෙන්, සෑම කෙනෙකුම එහි යෙදුම ඇත ...

වෙනත් විකල්ප

  • සිංගල්ටන් ගැන මා කියවා ඇති හොඳම ලිපිය විකල්පයක් ලෙස සේවා ලොකේටරය යෝජනා කරයි . මට නම් එය මූලික වශයෙන් " ස්ථිතික මෙවලම් පෙට්ටියක් " වේ, ඔබට අවශ්‍ය නම්. වෙනත් වචන වලින් කිවහොත්, සේවා ලොකේටරය තනි තනි කරන්න, ඔබට මෙවලම් පෙට්ටියක් තිබේ. එය ඇත්ත වශයෙන්ම සිංගල්ටන් වළක්වා ගැනීමේ ආරම්භක යෝජනාවට පටහැනිය, නමුත් එය සිංගල්ටන්ගේ ගැටළුව බලාත්මක කිරීම සඳහා පමණක් එය භාවිතා කරන ආකාරය මිස රටාවම නොවේ.

  • තවත් සමහරු විකල්පයක් ලෙස කර්මාන්තශාලා රටාව යෝජනා කරති . එය සගයකුගෙන් මා ඇසූ පළමු විකල්පය වන අතර ගෝලීය var ලෙස අපගේ භාවිතය සඳහා අපි එය ඉක්මනින් ඉවත් කළෙමු . එය නිසැකවම එහි භාවිතය ඇති නමුත් සිංගල්ටන් ද එසේමය.

ඉහත විකල්ප දෙකම හොඳ විකල්ප වේ. නමුත් ඒ සියල්ල ඔබගේ භාවිතය මත රඳා පවතී.

දැන්, තනි වියදමකින් වැළකී සිටිය යුතු යැයි ඇඟවීම වැරදිය.

  • ආරොනොට්ගේ පිළිතුර යෝජනා කරන්නේ හේතු කිහිපයක් නිසා කිසි විටෙකත් සිංගල්ටන් භාවිතා නොකරන ලෙසයි . නමුත් ඒවා සියල්ලම හේතු වී ඇත්තේ එය වැරදි ලෙස භාවිතා කර අපයෝජනයට ලක්වීමට එරෙහිව මිස රටාවට විරුද්ධව නොවේ. එම කරුණු පිළිබඳ කරදර වීම සමඟ මම එකඟ වෙමි, මට එය කළ නොහැක්කේ කෙසේද? මම හිතන්නේ එය නොමඟ යවන සුළුයි.

නොහැකියාවන් (වියුක්ත හෝ උප පංතියට) ඇත්ත වශයෙන්ම පවතී, නමුත් එසේ නම් කුමක් ද? එය ඒ සඳහා අදහස් නොකෙරේ. මට කිව හැකි තාක් දුරට අතුරු මුහුණතක් කිරීමට හැකියාවක් නැත . ඉහළ සම්බන්ධ කිරීම ද එහි තිබිය හැකිය, නමුත් එය බහුලව භාවිතා වන ආකාරය නිසා ය. එයට අවශ්‍ය නැත . ඇත්ත වශයෙන්ම, සම්බන්ධ කිරීම තනි තනි රටාවට කිසිදු සම්බන්ධයක් නැත. එය පැහැදිලි කිරීමෙන්, එය දැනටමත් පරීක්ෂා කිරීමේ දුෂ්කරතාවය ද ඉවත් කරයි. සමාන්තරකරණය කිරීමේ දුෂ්කරතාව සම්බන්ධයෙන්, එය භාෂාව සහ වේදිකාව මත රඳා පවතී, එබැවින් නැවතත්, රටාව පිළිබඳ ගැටළුවක් නොවේ.

ප්‍රායෝගික උදාහරණ

මම බොහෝ විට දකින්නේ 2 භාවිතා කරන බවයි. වෙබ් හැඹිලිය (මගේ නඩුව) සහ ලොග් සේවාව .

ල ging ු- සටහන්, සමහරු තර්ක කරනු ඇත , පරිපූර්ණ තනි උදාහරණයකි, මන්ද, සහ මම උපුටා දක්වන්නෙමි:

  • ඉල්ලුම්කරුවන්ට ලොග් වීමට ඉල්ලීම් යැවීමට ප්‍රසිද්ධ වස්තුවක් අවශ්‍ය වේ. මෙයින් අදහස් කරන්නේ ගෝලීය ප්‍රවේශ ස්ථානයක්.
  • ල ging ු-සටහන් සේවාව බහු සවන්දෙන්නන්ට ලියාපදිංචි විය හැකි තනි සිදුවීම් ප්‍රභවයක් බැවින්, අවශ්‍ය වන්නේ එක් අවස්ථාවක් පමණි.
  • විවිධ යෙදුම් විවිධ නිමැවුම් උපාංග වෙත ලොග් විය හැකි නමුත්, ඔවුන් සවන්දෙන්නන් ලියාපදිංචි කරන ආකාරය සැමවිටම සමාන වේ. සියලුම අභිරුචිකරණය ශ්‍රාවකයින් හරහා සිදු කෙරේ. පෙළ ලොග් වන්නේ කෙසේද හෝ කොතැනද යන්න නොදැන ගනුදෙනුකරුවන්ට ලොග් වීම ඉල්ලා සිටිය හැකිය. එබැවින් සෑම යෙදුමක්ම ල ging ු-සටහන් සේවාව එකම ආකාරයකින් භාවිතා කරයි.
  • ඕනෑම යෙදුමකට ල ging ු-සටහන් සේවාවේ එක් අවස්ථාවක් පමණක් ලබා ගත හැකිය.
  • ඕනෑම වස්තුවක් නැවත භාවිතා කළ හැකි සංරචක ඇතුළුව ලොග් ඉල්ලීමක් විය හැකිය, එවිට ඒවා කිසියම් විශේෂිත යෙදුමකට සම්බන්ධ නොවිය යුතුය.

අනෙක් අය තර්ක කරන අතර, ලොග් සේවාව සැබවින්ම එක් අවස්ථාවක් පමණක් නොවිය යුතු බව ඔබ තේරුම් ගත් පසු එය පුළුල් කිරීම දුෂ්කර කරයි.

හොඳයි, මම කියන්නේ තර්ක දෙකම වලංගු බවයි. මෙහි ගැටලුව, නැවතත්, සිංගල්ටන් රටාව මත නොවේ. ප්‍රතිව්‍යුහගත කිරීම ශක්‍ය අවදානමක් නම් එය වාස්තු විද්‍යාත්මක තීරණ සහ බර කිරා බැලීම මත වේ. සාමාන්‍යයෙන් නැවත සකස් කිරීම අවසාන වශයෙන් අවශ්‍ය නිවැරදි කිරීමේ පියවර වන විට එය තවත් ගැටළුවක් වේ.


ස්තූතියි! මම සිතුවේ පිළිතුර සංස්කරණය කිරීමේදී සිංගල්ටන් භාවිතා කිරීම පිළිබඳ අනතුරු ඇඟවීමක් එක් කිරීමටයි ... ඔබේ උපුටා දැක්වීම හොඳින් ගැලපේ!
cregox

2
ඔබ එයට කැමති වීම ගැන සතුටුයි. අඩු අගයන් වළක්වා ගැනීමට මෙය උපකාරී වේදැයි නිශ්චිතවම කිව නොහැක - බොහෝ විට පා post කයන්ට මෙම ලිපියේ සඳහන් කර ඇති ප්‍රශ්නය සම්බන්ධ කර ඇති ගැටළුවට සම්බන්ධ වීමට අපහසු වේ, විශේෂයෙන් පූර්ව පිළිතුරෙන් ලබා දී ඇති බිහිසුණු විශ්ලේෂණයන් දෙස බලන විට
gnat

ඔව්, මම දැනගෙන හිටියා මේක දිගු සටනක් කියලා. මම හිතනවා කාලය කියයි කියලා. ;-)
cregox

1
ඔබගේ සාමාන්‍ය දිශාවට මම එකඟ වෙමි, එය පුස්තකාලයක් ගැන තරමක් උද්යෝගිමත් වුවද, එය අතිශය හිස් ඇටකටු සහිත අයිඕසී බහාලුමකට වඩා වැඩි යමක් නොවේ (උදාහරණයක් ලෙස ෆන්ක් වලට වඩා මූලික ). සේවා ලොකේටරය ඇත්ත වශයෙන්ම ප්‍රති-රටාවකි; එය ප්‍රධාන වශයෙන් උරුමය / බ්‍රවුන්ෆීල්ඩ් ව්‍යාපෘති වල “දුප්පත් මිනිසාගේ ඩීඅයි” සමඟ ප්‍රයෝජනවත් මෙවලමක් වන අතර එහිදී අයිඕසී බහාලුමක් නිසියාකාරව භාවිතා කිරීම සඳහා සෑම දෙයක්ම ප්‍රතිචක්‍රීකරණය කිරීමට නොහැකි තරම් මිල අධික වනු ඇත.
ආරොනොට්

1
Aw කවාස්: අහ්, සමාවෙන්න - ව්‍යාකූල විය java.awt.Toolkit. මගේ කාරණය එක හා සමානයි: Toolboxඑක අරමුණක් සහිත සුසංයෝගී පංතියකට වඩා, සම්බන්ධයක් නැති බිටු සහ කෑලි උදුරා ගත් මල්ලක් වගේ. මට හොඳ නිර්මාණයක් ලෙස පෙනෙන්නේ නැත. (ඔබ සඳහන් කරන ලිපිය යැපුම් එන්නත් කිරීම සහ DI බහාලුම් සාමාන්‍ය දෙයක් බවට පත්වීමට පෙර 2001 සිට බව සලකන්න.)
ජෝන් ස්කීට්

6

සිංගල්ටන් සැලසුම් රටාව පිළිබඳ මගේ ප්‍රධාන ගැටළුව වන්නේ ඔබේ යෙදුම සඳහා හොඳ ඒකක පරීක්ෂණ ලිවීම ඉතා අපහසු වීමයි.

මෙම "කළමණාකරු" වෙත යැපීමක් ඇති සෑම සංරචකයක්ම එසේ කරන්නේ එහි තනි උදාහරණය විමසීමෙනි. ඔබට එවැනි සංරචකයක් සඳහා ඒකක පරීක්ෂණයක් ලිවීමට අවශ්‍ය නම් ඔබට මෙම සිංගල්ටන් උදාහරණයට දත්ත එන්නත් කළ යුතුය, එය පහසු නොවනු ඇත.

අනෙක් අතට ඔබේ "කළමනාකරු" රඳා පවතින සංරචක වලට ඉදිකිරීම් පරාමිතියක් හරහා එන්නත් කරනු ලැබුවහොත් සහ සංරචකය කළමනාකරුගේ කොන්ක්‍රීට් වර්ගය නොදන්නේ නම්, කළමනාකරු ක්‍රියාත්මක කරන අතුරු මුහුණතක් හෝ වියුක්ත පාදක පන්තියක් පමණි, එවිට ඒකකයක් පරායත්තතා පරීක්ෂා කිරීමේදී කළමනාකරුගේ විකල්ප ක්‍රියාත්මක කිරීම් පරීක්ෂණයට සැපයිය හැකිය.

ඔබේ යෙදුම සෑදෙන සංරචක වින්‍යාස කිරීමට සහ ක්ෂණිකව ස්ථාපනය කිරීමට ඔබ අයිඕසී බහාලුම් භාවිතා කරන්නේ නම්, එවිට ඔබට "කළමනාකරු" ගේ එක් අවස්ථාවක් පමණක් නිර්මාණය කිරීම සඳහා ඔබේ අයිඕසී බහාලුම පහසුවෙන් වින්‍යාසගත කළ හැකි අතර, එය සාක්ෂාත් කර ගැනීමට ඔබට ඉඩ සලසයි, ගෝලීය යෙදුම් හැඹිලිය පාලනය කරන එක් අවස්ථාවක් පමණි .

නමුත් ඔබ ඒකක පරීක්ෂණ ගැන තැකීමක් නොකරන්නේ නම්, සිංගල්ටන් මෝස්තර රටාවක් පරිපූර්ණ විය හැකිය. (නමුත් මම එය කෙසේ හෝ නොකරමි)


1
සිංගල්ටන් පරීක්ෂා කිරීම පිළිබඳ ගැටළුව වඩාත් හොඳින් පැහැදිලි කරන පිළිතුර මෙයයි
හෝසේ ටොමස් ටොසිනෝ

4

ඕනෑම නිර්මාණ පරිගණකයක් හොඳ හෝ නරක විය හැකි අර්ථයෙන් සිංගල්ටන් එකක් මූලික ආකාරයකින් නරක නැත. එය කවදා හෝ නිවැරදි විය හැකිය (අපේක්ෂිත ප්‍රති results ල ලබා දෙයි) හෝ නැත. එය කේතය වඩාත් පැහැදිලි හෝ කාර්යක්ෂම කරන්නේ නම් එය ප්‍රයෝජනවත් විය හැකිය.

සිංගල්ටන් ප්‍රයෝජනවත් වන එක් අවස්ථාවක් නම් ඒවා අද්විතීය වූ ආයතනයක් නියෝජනය කරන විටය. බොහෝ පරිසරවල, දත්ත සමුදායන් අද්විතීයයි, ඇත්ත වශයෙන්ම ඇත්තේ එක් දත්ත සමුදායක් පමණි. එම දත්ත සමුදායට සම්බන්ධ වීම සංකීර්ණ විය හැක්කේ එයට විශේෂ අවසරයන් අවශ්‍ය නිසා හෝ සම්බන්ධතා වර්ග කිහිපයක් හරහා ගමන් කිරීමෙනි. එම සම්බන්ධතාවය තනි පුද්ගලයකු ලෙස සංවිධානය කිරීම බොහෝ විට මෙම හේතුව නිසා පමණක් අර්ථවත් කරයි.

නමුත් සිංගල්ටන් යනු සැබවින්ම සිංගල්ටන් එකක් මිස ගෝලීය විචල්‍යයක් නොවන බවට ඔබ සහතික විය යුතුය. තනි, අද්විතීය දත්ත සමුදාය සැබවින්ම දත්ත සමුදායන් 4 ක් වන අතර මෙය නිෂ්පාදනය, වේදිකාගත කිරීම, සංවර්ධනය කිරීම සහ පරීක්ෂණ සවිකිරීම් සඳහා එකකි. දත්ත සමුදා සිංගල්ටන් විසින් එය සම්බන්ධ කළ යුත්තේ කාටද යන්න සොයා ගනී, එම දත්ත සමුදාය සඳහා තනි අවස්ථාව අල්ලාගෙන, අවශ්‍ය නම් එය සම්බන්ධ කර එය අමතන්නා වෙත ආපසු එවනු ඇත.

සිංගල්ටන් එකක් ඇත්ත වශයෙන්ම සිංගල්ටන් නොවන විට (මෙය බොහෝ ක්‍රමලේඛකයින් කලබලයට පත්වන විට), එය කම්මැලි ක්ෂණික ගෝලීයයකි, නිවැරදි අවස්ථාවක් එන්නත් කිරීමට අවස්ථාවක් නොමැත.

හොඳින් සැලසුම් කරන ලද සිංගල්ටන් රටාවක තවත් ප්‍රයෝජනවත් ලක්ෂණයක් වන්නේ එය බොහෝ විට නිරීක්ෂණය කළ නොහැකි වීමයි. අමතන්නා සම්බන්ධතාවයක් ඉල්ලා සිටී. එය සපයන සේවාවට සංචිත වස්තුවක් ආපසු ලබා දිය හැකිය, නැතහොත් එය පරීක්ෂණයක් කරන්නේ නම්, එය සෑම ඇමතුමකටම නව එකක් නිර්මාණය කළ හැකිය, නැතහොත් ඒ වෙනුවට ව්‍යාජ වස්තුවක් සැපයිය හැකිය.


3

තථ්‍ය වස්තූන් නියෝජනය කරන සිංගල්ටන් රටාව භාවිතා කිරීම සම්පූර්ණයෙන්ම පිළිගත හැකිය. මම අයිෆෝන් සඳහා ලියන අතර කොකෝවා ස්පර්ශ රාමුව තුළ සිංගල්ටන් ගොඩක් තිබේ. යෙදුමම පන්තියේ තනි පුද්ගලයකු විසින් නිරූපණය කෙරේ UIApplication. ඔබ සතුව ඇත්තේ එක් යෙදුමක් පමණි, එබැවින් එය තනි තනිව නිරූපණය කිරීම සුදුසුය.

දත්ත කළමණාකරණ පංතියක් ලෙස සිංගල්ටන් භාවිතා කිරීම නිවැරදිව නිර්මාණය කර ඇති තාක් කල් එය හරි ය. එය දත්ත ගුණාංග බාල්දියක් නම්, එය ගෝලීය විෂය පථයට වඩා හොඳ නැත. එය ලබා ගන්නන් සහ කට්ටල කට්ටලයක් නම්, එය වඩා හොඳයි, නමුත් තවමත් විශිෂ්ට නොවේ. එය දුරස්ථ දත්ත ලබා ගැනීම, හැඹිලිගත කිරීම, පිහිටුවීම සහ ඉරීම ඇතුළුව දත්ත සඳහා සියලු අතුරු මුහුණත් සැබවින්ම කළමනාකරණය කරන පන්තියක් නම් ... එය ඉතා ප්‍රයෝජනවත් විය හැකිය.


3

සිංගල්ටෝන යනු සේවා මත පදනම් වූ ගෘහ නිර්මාණ ශිල්පයක් වැඩසටහනකට ප්‍රක්ෂේපණය කිරීම පමණි.

ඒපීඅයි යනු ප්‍රොටෝකෝල මට්ටමින් සිංගල්ටන් සඳහා උදාහරණයකි. ඔබ ට්විටර්, ගූගල් යනාදිය වෙත ප්‍රවේශ වන්නේ අත්‍යවශ්‍යයෙන්ම තනි බොත්තම් හරහාය. ඉතින් වැඩසටහනක් තුළ සිංගල්ටන් නරක වන්නේ ඇයි?

එය වැඩසටහනක් ගැන ඔබ සිතන ආකාරය මත රඳා පවතී. අහඹු ලෙස බැඳී ඇති හැඹිලි අවස්ථාවන්ට වඩා සේවා සමාජයක් ලෙස ඔබ වැඩ සටහනක් සිතන්නේ නම්, ඒකලයන් පරිපූර්ණ අර්ථයක් ලබා දෙයි.

සිංගල්ටන් යනු සේවා ප්‍රවේශ ස්ථානයකි. ඉතා සංකීර්ණ අභ්‍යන්තර ගෘහ නිර්මාණ ශිල්පයක් සඟවන ක්‍රියාකාරීත්වයේ තදින් බැඳී ඇති පුස්තකාලයකට පොදු අතුරු මුහුණත.

ඒ නිසා මම කර්මාන්ත ශාලාවකට වඩා වෙනස් තනි පුද්ගලයෙක් දකින්නේ නැහැ. සිංගල්ටන්ට ඉදිකිරීම් පරාමිතීන් සම්මත කළ හැකිය. නිදසුනක් ලෙස, හැකි සෑම තේරීම් යාන්ත්‍රණයකටම පෙරනිමි මුද්‍රණ යන්ත්‍රය නිරාකරණය කරන්නේ කෙසේදැයි දන්නා යම් සන්දර්භයක් මඟින් එය නිර්මාණය කළ හැකිය. පරීක්ෂා කිරීම සඳහා ඔබට ඔබේම විහිළුවක් ඇතුළත් කළ හැකිය. එබැවින් එය තරමක් නම්‍යශීලී විය හැකිය.

වැඩසටහන ක්‍රියාත්මක කිරීමේදී යතුර අභ්‍යන්තරව පවතින අතර මට යම් ක්‍රියාකාරීත්වයක් අවශ්‍ය වන විට සේවාව ඉහළ මට්ටමක පවතින අතර භාවිතයට සුදානම් බවට පූර්ණ විශ්වාසයෙන් මට සිංගල්ටන් වෙත පිවිසිය හැකිය. ක්‍රියාවලියක ආරම්භ වන විවිධ නූල් ඇති විට මෙය ප්‍රධාන ය. එය සූදානම් යැයි සැලකීමට රාජ්‍ය යන්ත්‍රයක් හරහා යා යුතුය.

සාමාන්‍යයෙන් මම XxxServiceපංතියක් වටා තනි තට්ටුවක් ඔතා පන්තියක් ඔතා Xxx. සිංගල්ටන් කිසිසේත් පන්තියේ නැත Xxx, එය වෙනත් පන්තියකට වෙන් කර ඇත XxxService. මෙයට හේතුව Xxxබොහෝ අවස්ථාවන් තිබිය හැකි නමුත් එය එසේ නොවිය හැකි නමුත් අපට තවමත් අවශ්‍ය වන්නේ Xxxඑක් එක් පද්ධතියට ගෝලීයව ප්‍රවේශ විය හැකි එක් අවස්ථාවක්. XxxServiceඋත්සුකයන්ගෙන් හොඳ වෙන්වීමක් සපයයි. Xxxසිංගල්ටන් ප්‍රතිපත්තියක් බලාත්මක කිරීමට අවශ්‍ය නැත, නමුත් Xxxඅපට අවශ්‍ය විටදී සිංගල්ටන් ලෙස භාවිතා කළ හැකිය .

වැනි දෙයක්:

//XxxService.h:
/**
 * Provide singleton wrapper for Xxx object. This wrapper
 * can be autogenerated so is not made part of the object.
 */

#include "Xxx/Xxx.h"


class XxxService
{
    public:
    /**
     * Return a Xxx object as a singleton. The double check
     * singleton algorithm is used. A 0 return means there was
     * an error. Developers should use this as the access point to
     * get the Xxx object.
     *
     * <PRE>
     * @@ #include "Xxx/XxxService.h"
     * @@ Xxx* xxx= XxxService::Singleton();
     * <PRE>
     */

     static Xxx*     Singleton();

     private:
         static Mutex  mProtection;
};


//XxxService.cpp:

#include "Xxx/XxxService.h"                   // class implemented
#include "LockGuard.h"     

// CLASS SCOPE
//
Mutex XxxService::mProtection;

Xxx* XxxService::Singleton()
{
    static Xxx* singleton;  // the variable holding the singleton

    // First check to see if the singleton has been created.
    //
    if (singleton == 0)
    {
        // Block all but the first creator.
        //
        LockGuard lock(mProtection);

        // Check again just in case someone had created it
        // while we were blocked.
        //
        if (singleton == 0)
        {
            // Create the singleton Xxx object. It's assigned
            // to a temporary so other accessors don't see
            // the singleton as created before it really is.
            //
            Xxx* inprocess_singleton= new Xxx;

            // Move the singleton to state online so we know that is has
            // been created and it ready for use.
            //
            if (inprocess_singleton->MoveOnline())
            {
                LOG(0, "XxxService:Service: FAIL MoveOnline");
                return 0;
            }

            // Wait until the module says it's in online state.
            //
            if (inprocess_singleton->WaitTil(Module::MODULE_STATE_ONLINE))
            {
                LOG(0, "XxxService:Service: FAIL move to online");
                return 0;
            }

            // The singleton is created successfully so assign it.
            //
            singleton= inprocess_singleton;


        }// still not created
    }// not created

    // Return the created singleton.
    //
    return singleton;

}// Singleton  

1

පළමු ප්‍රශ්නය, ඔබ යෙදුමේ දෝෂ රාශියක් සොයාගෙන තිබේද? හැඹිලිය යාවත්කාලීන කිරීමට අමතක වී තිබේද, නැතිනම් නරක හැඹිලියක් හෝ වෙනස් කිරීමට අපහසුද? (මට මතකයි ඔබ වර්ණය වෙනස් නොකළහොත් යෙදුමක් ප්‍රමාණ වෙනස් නොකරන බව ... කෙසේ වෙතත් ඔබට වර්ණය නැවත වෙනස් කර ප්‍රමාණය තබා ගත හැකිය).

ඔබ කළ යුත්තේ එම පංතියයි, නමුත් සියලු ස්ථිතික සාමාජිකයන් ඉවත් කරන්න. හරි, මෙය අනවශ්‍ය දෙයක් නොවේ, නමුත් මම එය නිර්දේශ කරමි. ඇත්ත වශයෙන්ම ඔබ සාමාන්‍ය පන්තියක් මෙන් පන්තිය ආරම්භ කර දර්ශකය පසුකර යන්න. පංති කියන්න එපා ClassIWant.APtr (). LetMeChange.ANYTHINGATALL (). Andhave_no_structure ()

එහි වැඩි වැඩක් නමුත් ඇත්ත වශයෙන්ම එය අඩු අවුල් සහගතය. ගෝලීය නොවන බැවින් ඔබට දැන් කළ නොහැකි දේවල් වෙනස් නොකළ යුතු සමහර ස්ථාන. මගේ කළමනාකරු පන්ති සියල්ලම සාමාන්‍ය පන්ති වේ, එය එසේ සලකන්න.


1

IMO, ඔබේ උදාහරණය හරි. පහත දැක්වෙන පරිදි සාධකකරණය කිරීමට මම යෝජනා කරමි: එක් එක් (සහ එක් එක් පිටුපස) දත්ත වස්තුව සඳහා හැඹිලි වස්තුව; හැඹිලි වස්තු සහ db ප්‍රවේශ වස්තු එකම අතුරු මුහුණතක් ඇත. මෙය කේත තුළට සහ පිටතට හැඹිලි මාරු කිරීමේ හැකියාව ලබා දෙයි; ප්ලස් එය පහසු පුළුල් කිරීමේ මාර්ගයක් ලබා දෙයි.

ග්‍රැෆික්:

DB
|
DB Accessor for OBJ A
| 
Cache for OBJ A
|
OBJ A Client requesting

ඩීබී ඇක්සෙසරය සහ හැඹිලිය එකම වස්තුවකින් හෝ තාරාවන්ගේ වර්ගයෙන් එකම වස්තුවක් මෙන් පෙනේ. ඔබට ප්ලග් / කම්පයිල් / ටෙස්ට් කළ හැකි තාක් කල් එය ක්‍රියාත්මක වේ.

මෙය දේවල් විකේතනය කරන බැවින් ඔබට ඇතුළට නොගොස් නව හැඹිලි එකතු කළ හැකි අතර සමහර Uber-Cache වස්තුව වෙනස් කළ හැකිය. වයි.එම්.එම්.වී. ඉනාල්. ඊ.ටී.සී.


1

සාදයට ටිකක් පරක්කුයි, නමුත් කෙසේ හෝ.

සිංගල්ටන් යනු වෙනත් ඕනෑම දෙයක් මෙන් මෙවලම් පෙට්ටියක ඇති මෙවලමකි. තනි මිටියකට වඩා ඔබේ මෙවලම් පෙට්ටියේ වැඩි යමක් ඇතැයි සිතමු.

මෙය සලකා බලන්න:

public void DoSomething()
{
    MySingleton.Instance.Work();
}

එදිරිව

public void DoSomething(MySingleton singleton)
{
    singleton.Work();
}
DoSomething(MySingleton.instance);

1 වන අවස්ථාව ඉහළ සම්බන්ධතාවයට හේතු වේ; දෙවන ක්‍රමයට කිසිදු ගැටළුවක් නොමැත @ මට කිව හැකි තාක් දුරට ඇරෝනාට් විස්තර කරයි. ඔබ එය භාවිතා කරන ආකාරය පිළිබඳ සියල්ලම.


එකඟ නොවන්න. දෙවන ක්‍රමය "වඩා හොඳ" (සම්බන්ධ කිරීම අඩුවීම) වුවද, එය තවමත් DI විසින් විසඳන ගැටළු ඇත. ඔබේ සේවාවන් ක්‍රියාත්මක කිරීම සඳහා ඔබ ඔබේ පන්තියේ පාරිභෝගිකයා මත විශ්වාසය නොතැබිය යුතුය - එය පන්තිය නිර්මාණය කරන විට ඉදිකිරීම්කරු තුළ වඩාත් හොඳින් සිදු වේ. ඔබේ අතුරුමුහුණතට අවශ්‍ය වන්නේ අවම වශයෙන් තර්ක විතර්ක පමණි. ඔබේ පන්තියට ක්‍රියාත්මක වීමට එක් අවස්ථාවක් අවශ්‍ය බවට හොඳ අවස්ථාවක් තිබේ - නැවතත්, මෙම රීතිය බලාත්මක කිරීම සඳහා පාරිභෝගිකයා මත යැපීම අවදානම් සහ අනවශ්‍යය.
ඇලෙක්ස්ෆොක්ස්ගිල්

සමහර විට ඩී යනු යම් කාර්යයක් සඳහා අධික ලෙස මරා දැමීමයි. නියැදි කේතයක ඇති ක්‍රමය ඉදිකිරීම්කරුවෙකු විය හැකි නමුත් අවශ්‍ය නොවේ - සංයුක්ත උදාහරණය දෙස නොබලා එහි වැදගත් තර්කය. එසේම, DoSomething හට ISomething ගත හැකි අතර MySingleton විසින් එම අතුරුමුහුණත ක්‍රියාත්මක කළ හැකිය - හරි, එය නියැදියක නොවේ .. නමුත් එය නියැදියකි.
එව්ගනි

1

සෑම තිරයක්ම ඒවායේ ඉදිකිරීම්කරු තුළ කළමනාකරු වෙත ගෙන යන්න.

ඔබ ඔබේ යෙදුම ආරම්භ කරන විට, ඔබ කළමනාකරුගේ එක් අවස්ථාවක් නිර්මාණය කර එය පසුකර යන්න.

මෙය ප්‍රතිලෝම පාලක ලෙස හැඳින්වෙන අතර වින්‍යාසය වෙනස් වන විට සහ පරීක්ෂණ වලදී පාලකය මාරු කිරීමට ඔබට ඉඩ සලසයි. මීට අමතරව, ඔබට ඔබගේ යෙදුමේ අවස්ථා කිහිපයක් හෝ ඔබගේ යෙදුමේ කොටස් සමාන්තරව ධාවනය කළ හැකිය (පරීක්ෂා කිරීමට හොඳයි!). අවසාන වශයෙන් ඔබේ කළමනාකරු තමන්ගේම වස්තුවකින් (ආරම්භක පන්තිය) මිය යනු ඇත.

එබැවින් ඔබගේ යෙදුම ගසකට සමාන ලෙස සකසන්න, ඉහත දේවල් ඒවාට පහළින් භාවිතා කරන සියල්ල සතු වේ. දැලක් වැනි යෙදුමක් ක්‍රියාත්මක නොකරන්න, එහිදී සෑම කෙනෙකුම සෑම කෙනෙකුම දන්නා අතර ගෝලීය ක්‍රම මගින් එකිනෙකා සොයා ගනී.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.