Եզակի օգտագործման (նախագծման ձևանմուշ)

Եզակի օգտագործման նախագծման ձևանմուշը ստեղծող ձևանմուշ է, որը միահոսքային ծրագրերում գլոբալ հասանելիության տեսանկյունից հանդիսանում է դասի եզակի նմուշը։ Ձևանմուշի օգտագործումը օգտակար է կիրառել, երբ ողջ համակարգի մեջ միայն մի օբյեկտ պետք է կոորդինացնել։ Եզակի ձևանմուշի հասկացողությունը ծագել է մաթեմատիկական համապատասխան () հասկացությունից։

Գոյություն ունի քննադատություն այս ձևանմուշի համար, քանի որ շատերը նրան համարում են անտի-ձևանմուշ ()։ Ըստ որոշ մարդկանց ձևանմուշը ոչ արդարացված սահմանափակումներ է մտցնում այնտեղ՝ որտեղ պետք չէ սահմանափակել դասի օգտագործման քանակը։ Ինչպես նաև գլոբալ փոփոխական է հայտարարում։

C++ լեզվում դինամիկ ինիցիալիզացիայի ժամանակ կատուրում է բաժանարարի դեր, որը ծրագրավորողին է վերադարձնում կառավարումը։

Ընդհանուր հասկացողություններ
 Client - հայցող
 Instance - նմուշ
 Implementation - իրականացում
 Product - արգասիք

Կիրառություն 
Եզակի օգտագործման նախագծման ձևանմուշը կիրառվում է, երբ.
 բոլոր հասանելի հայցողների համար պետք է լինի դասի ընդամենը մեկ նմուշ 
 միակ նմուշը պետք է ընդարձակվի ենթադասեր ստեղծելու ճանապարհով, իսկ հայցողները պետք է կարողանան աշխատել ընդլայնված նմուշի հետ առանց ծրագրային կոդի փոփոխության։

UML դասի սխեմա

Նպատակը 
երաշխավորում է, որ դասի մոտ կա ընդամենը մի օրինակ և նրա համար ապահովում է գլոբալ հասանելիություն։ Հատկանշական է նշել այն, որ կարելի է օգտվել հենց դասի օրինակից։ Այսպիսով շատ դեպքերում կարելի է ապահովել ավելի լայն ֆունցկիոնալիություն։ Օրինակ դասի նկարագրված կոմպոնենտներին կարելի է դիմել հատուկ ինտերֆեյսի միջոցով, եթե, իհարկե, լեզուն նման հնարավորություն թույլ է տալիս։

Գլոբալ «եզակի» օբյեկտը, այլ ոչ թե պրոցեդուրաների հավաքածուն, որը կապված չէ ոչ մի օբյեկտի, անհրաժեշտ է.
 եթե օգտագործվում է գոյություն ունեցող օբյեկտ-կոմնորոշված գրադարան
 եթե կա հնարավորություն, որ օբյեկտը որոշ ժամանակ անց կարող է դառնալ մի քանի հատ
 եթե օբյեկտի ինտերֆեյսը (օրինակ խաղերի ոլորտում) բավականին բարդ է և պետք չէ աղտոտել հիմնական անվանումների դաշտը մեծաքանակ ֆունկցիաներով
 եթե, որոշ պայմաններից և կարգավորումներից կախված, ստեղծվում է մեկ օբյեկտ մի քանի օբյեկտներից։

Այսպիսի օբյեկտները կարելի է ստեղծվել նաև ծրագրերի ինիցիալիզացիայի համար։ Դա կարելի է բերել հետևյալ դժվարություններին.
 Եթե օբյեկտը պետք է ինիցիալիզացիայի համար, այն պետք է պահանջել ավելի շուտ, քան այն ստեղծվել է։
 Լինում է, երբ օբյեկտները միշտ չէ, որ անհրաժեշտ են։ Այս դեպքում նրա ստեղծումը կարելի է բաց թողնել։

Առավելությունը 
Առավելությունն հանդիսանում է նրանում ապահովում է ղեկավարվող հասանելիություն «եզակի» նմուշին։

Թերությունները 
 Գլոբալ օբյեկտները կարող են վնասակար լինել օբյեկտային ծրագրավորման համար, որը որոշ դեպքերում կարող է հանգեցնել ծրագրային մասշտաբի չափերի փոփոխության։
 Դժվարեցնում է մոդուլային թեսթերի գրելը, թեսթային հետազոտությունները և թեսթավորումը։

Օրինակ C++ լեզվով 
Ներքևում բերված է եզակի օգտագործման ձևանմուշի իրականացման մի օրինակ C++ ծրագրավորման լեզվով, որն առավել հայտնի է որպես «Սքոթ Մայերսի եզակի օգտագործման ձևանմուշ» անվանումով։ Այստեղ եզակի նմուշն իրենից ներկայացնում է ստատիկ լոկալ օբյեկտ։ Կարևոր հանգաման է հանդիսանում այն, որ այստեղ դասի կոնստրուկտորը հայտարարվում է որպես private, որն իր հերթին արգելում է դասի նմուշների ստեղծումը դասի իրականացման դաշտից դուրս։ Բացի այդ փակ են հայտարարված նաև պատճենման և վերագրման օպերատորի կոնստրուկտորները։ Վերջինները պետք է հայտարարել, բայց չսահմանել, քանի որ նրանց ծրագրային կոդի պատահական կանչի դեպքում հնարավոր կլինի կոմպանովկայի ժամանակ հեշտությամբ հայտնաբերել սխալը։

Նշենք որ, ներքևում բերված կոդը հոսքերի առումով ապահով չի հանդիսանում С++03 տարբերակի համար։ Դրա համար դասի որոշ հոսքերից պետք է պաշտպանել theSingleInstance փոփոխականը միաժամանակյա օգտագործումից՝ օրինակ մյուտեքսների կամ կրիտիկական սեկտորների միջոցով։ Ի դեպ C++11 լեզվում Մայերսի եզակի օգտագործման ձևանմուշը ապահով է հանդիսանում առանց ավելորդ բլոկավորումների։

class OnlyOne
{
public:
        static const OnlyOne& Instance()
        {
                static OnlyOne theSingleInstance;
                return theSingleInstance;
        }
private:        
        OnlyOne(){}
        OnlyOne(const OnlyOne& root);
        OnlyOne& operator=(const OnlyOne&);
};

Եվս մի ինտերֆեյսի ստեղծման իրականացման օրինակ բերված է ստորև։ Կոդը թույլ է տալիս ժառանգել, որի համար հիմնակմախք է հանդիսանում հենց ինքը՝ եզակի օգտագործման նմուշը։ Օբյեկտի «կյանքի» տևողությունը հարմար է ղեկավարել հղումների քանակի հաշվարկի միջոցով։

class Singleton
{
protected:
	static Singleton* _self;
	Singleton() {}
	virtual ~Singleton() {}

public:
	static Singleton* Instance()
	{
		if(!_self)
		{
			_self = new Singleton();
		}
		return _self;
	}

	static bool DeleteInstance()
	{
		if(_self)
		{
			delete _self;
			_self = 0;
			return true;
		}
		return false;
	}
};

Singleton* Singleton ::_self = 0;

Ծանոթագրություններ 

Ծրագրավորում