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

Վիքիպեդիայից՝ ազատ հանրագիտարանից
Եզակի օգտագործման
ՏեսակՍտեղծող
ՆշանակությունՎերահսկում է, որ նմուշը լինի միակը
Կառուցվածք
ԿիրառությունԵրբ համակարգում օբյեկտը միակն է
ԱռավելություններԿառավարում է հասանելիությունը եզակի նմուշի համար
ԹերություններՀետևյալն է.
  • Գլոբալ օբյեկտները կարող են վնասակար լինել օբյեկտ կողմոնորոշված ծրագրավորման համար
  • Դժվարացնում է մոդուլային թեսթեր ստեղծելը և թեսթավորումը։
Նկարագրությունը ԳօՖի
"Design Patterns" գրքում
Այո

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

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

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;

Ծանոթագրություններ[խմբագրել | խմբագրել կոդը]