Skip to content

Яагаад кодын стандарт ашиглах шаардлагатай байдаг вэ?

December 1, 2006

Кодын стандарт шаардлага нь дараахи шалтгаануудын улмаас гарч ирдэг байна. Үүнд: Software Project-ийн амьдралын циклийн 80% зардал нь нэмэлт үйлчилгээ, засвар үйлчилгээнд явдаг. Тэгтэл Software Project засвар үйлчилгээ нь зохиосон хүнээрээ явагдах нь маш ховор байдаг.


<!–[if !supportLists]–>

· <!–[endif]–>Кодын стандарттай болсоноор программ зохиогч нар шинэ кодыг илүү хурдан, сайтар ойлгохоос гадна програмыг уншихад илүү хялбар болгодог.

<!–[if !supportLists]–>

· <!–[endif]–>Хэрэв эх кодоо эцсийн бүтээгдэхүүн болгох гэж байгаа бол түүнийг сайтар баглагдсан(Packaged) болон цэвэр(clean) эсэхийг магадлах хэрэгтэй.

Програм бичиж буй хүн бүр кодын стандартыг баримтлах шаардлагатай.

Todd Hoff –н гаргасан кодын стандартын сайн талуудыг доор үзүүлэв.

Нэгэн зүйл. Стандартчилах нь хэрэгтэй юу?

– Сайн тал

Хэрэв төслийг ерөнхий стандарттай болговол дараах хэдэн сайн талтай.

<!–[if !supportLists]–>· <!–[endif]–>Программистууд нь ямарч кодыг юу хийж байгааг нь тодорхойлж чадна.

<!–[if !supportLists]–>· <!–[endif]–>Шинэ хүмүүс кодинг хийх үед хурдан учраа олно.

<!–[if !supportLists]–>· <!–[endif]–>Хүмүүс ижил нөхцөл байдалд илүү бага алдаа гаргах болно.

– Дүгнэлт
Олон төслүүдийг удирдсан туршилгаас харахад кодын стандарт ашиглаж байгаа төсөл нь саадгүй явагддаг. Стандарт нь амжилтанд хүрэхэд шаардлагатай зүйл үү? Мэдээж үгүй. Гэвч тэд бидэнд төслийг амжилттай хэрэгжүүлэхэд тусалдаг ба харин бидэнд авч чадах бүх л тусламж хэрэгтэй байдаг.

Эхлэл. Ерөнхий эх кодын форматын дүрэм
(General Source Code Formatting Rules)

Догол мөр (Indentation)

Догол мөр нь түвшин бүрт хоёр хоосон нүд(space) байна. Таб (Tab) тэмдэгтийг эх кодонд хадгалж болохгүй. Учир нь таб тэмдэгт нь өөр өөр хэрэглэгчид өөр өөр код удирдах хэрэгсэлээр (хэвлэх, архивлах, хувилбар удирдах г.м) ялгаатай өргөнтэй болж өргөсдөг.Хадгалахыг хүчингүй болгохын тулд Tool menu -> Editor Option –н General tab доторх “Optimal fill” болон “Use tab character” check box –уудыг идэвхгүй болгох хэрэгтэй. Зөв догол мөртэй болгохын тулд [Tools | Editor Options | General] tab дотороос ‘Tab Stops’ –г 3,5,7,9,11,13,15,17,19,21 гэсэн утгуудын аль нэгээр нь тавина.

Зах ирмэгүүд (Margins)

Зах ирмэгийг 80 тэмдэгт гэж тогтооно. Ерөнхийдөө бол үгийг гүйцээж бичихээс бусад тохиолдолд кодыг зах ирмэгээс хэтрүүлэхгүй (энэ заавар нь бага зэрэг уян хатан). Илэрхийлэл нь нэг мөрөндөө хэт уртасвал түүнийг таслал юмуу үйлдэлээр хуваах боломжтой юм. Хэрэв илэрхийлэл нь таслагдсан бол тэд догол мөрөнд байх хэрэгтэй ба логикоор бүлэглэсэн хэсэг нь догол мөрийн нэг түвшинд байна.

Тайлбар бичих (Comments)

Тайлбар бичихэд үргэлж { } хосыг ашиглана. (* *) гэсэн сонгох тэмдэглэлийг(alternative notation) хөгжүүлэх явцдаа устгах түр зуурын кодуудыг тодорхойлоход ашиглана. // -н хэрэглээ нь нэг мөр тайлбаруудаар хязгаарлагдана.

Method Тусгаарлагчууд (Method Breaks)

Тусгаарлагч тайлбар мөрийг “{— ~ —}” нэг method -н төгсгөл, дараагын method –н эхлэлийн хооронд тавина (шулуун нь зүүн ирмэгээс баруун талын хуудасны тасралт хүртэл үргэлжилнэ). Мөн method –уудыг бичих явцад тэр нь дэлгэцийн хэмжээний талаас ийлүү том бол end командын ард уг method -н нэрийг бичиж өгнө.

Жишээ нь:

procedure TfrmMainForm.LargeMethod;
begin
[Lots of code here...]
end; // LargeMethod

{---------------------------------------------------------------------------}

procedure TfrmMainForm.SomeMethod;
begin
[More code here...]

Нөхцөл тодорхойлох (Conditional Defines)

Нөхцөл тодорхойлолт нь – “{“, “}” – угалзан хаалтууд дотор томоор бичигдсэн нөхцөлийн командууд байна. Нөхцөл тодорхойлолт бүр нь нэрлэгдсэн байх нь кодыг илүү ойлгомжтой болгоно. Тэдгээр нь ижил хэв загвараар догол мөр авсан байна. Жишээ нь:

 if ... then
begin
{$IFDEF VER90}
raise Exception.CreateRes(SError);
{$ELSE}
raise Exception.Create(SError);
{$ENDIF VER90}
end;

Begin..End хос

Begin statement нь зөвхөн өөрийнхөө л мөрөнд байрлана. Жишээ нь доорх эхний мөр нь буруу хоёр дахь мөр нь зөв юм.

 for I := 0 to 10 do begin // Incorrect, begin on same line as for

for I := 0 to 10 do       // Correct, begin appears on a separate line
begin

Begin statement нь else –н хэсэг болж байвал өмнөх дүрэмээс гажиж болно. Жишээ нь:

 if some statement = ... then
begin
...
end
else begin
SomeOtherStatement;
end;

Гэвч бичилтийн илүү дээр гэж үздэг арга зам бол энэ юм.


if some statement = ... then
begin
...
end
else
begin
SomeOtherStatement;
end;

Тэгээд begin statement нь үргэлж өөрийн if statement –тэй ижил түвшиний догол мөрд байрлаж байна.End statement нь үргэлж өөрийн мөрөндөө байрлана.Хэрэв begin тэмдэглэгээ нь else –н хэсэг болоогүй л (өмнө дүрэмээс гажиж болох жишээг үзүүлсэн) бол харгалзах end тэмдэглэгээ нь үргэлж begin –тэй ижил түвшиний догол мөрөнд байрлана.

Обьект паскал (Object Pascal)

Хаалт (Parenthesis)

Нээх хаалт болон дараагын тэмдэгт хоёрын хооронд хэзээ ч хоосон зай авах хэрэггүй. Мөн үүнтэй ижил хаах хаалтанд сул зай авахгүй. Дараах жишээнд зөв буруу хэрэглээг үзүүлэв.

 CallProc( AParameter ); // incorrect
CallProc(AParameter);   // correct

Илэрхийлэлд илүүдэл хаалтыг хэзээ ч бүү оруул. Эх кодонд хаалтыг зөвхөн хийх гэж буй үйлдэлд шаардлагатай бол оруулна. Дараах жишээнд зөв буруу хэрэглээг үзүүлэв.

 if (I = 42) then              // incorrect - extraneous parentheses
if (I = 42) or (J = 42) then  // correct - parentheses required

Нөөцлөгдсөн үгс болон Түлхүүр үгс (Reserved Words and Key Words)

Обьект паскалд хэлэнд нөөцлөгдсөн үгс болон түлхүүр үгсийг нь үргэлж жижигээр (бүх үсэг нь жижиг) бичинэ. Default –оор бол IDE –н онцлолж тодруулах үгүүдийг аль хэдийн bold хэлбэртэй болгож хэвлэдэг (begin, end, if , else . . .). Эдгээр үгсүүдийг том үсэгээр илэрхийлэх гэсэний хэрэггүй юм.

Процедур болон Функцүүд (Тогтсон загвар)

Procedures and Functions (Routines)

Нэрлэх / Формат

Нэрлэлт нь уншихад хялбар байх үүднээс үргэлж том үсгээр эхэлж тэмээн бөх хэлбэртэй байна. Дараах жишээн дээр буруу форматтай процедурын нэрийг үзүүлэв.

 Procedure thisisapoorlyformattedroutinename;

Доорх жишээн дээр зүй зохистойгоор том үсэг хэрэглэсэн тогтсон нэрийг харуулав.


Procedure ThisIsMuchMoreReadableRoutineName;

Нэр нь гүйцэтгэж буй үүргийнхээ утга санааг агуулж байх ёстой.
Мөн гүйцэтгэх үйлдэлийн үйл үгийг угтвартаа авч явна. Жишээ нь:

Procedure FormatHardDrive;

Утга олгох болон параметр оруулах гэж буй бол set гэсэн үгийг угтвартаа авна.

Procedure SetUserName;

Утга буцаах бол get гэсэн үгийг угтвартаа авах хэрэгтэй.

function GetUserName: string;

Томоохон функц процедур бичиж буй бол үүнээс гажина. Delphi мэтийн обьект хандалтат хөгжүүлэгч хэрэгсэл ашиглан сайн програмчлах дадлага туршлагатай байх гэдэг нь бичиж байгаа код нь хоорондоо хүчтэй хамааралтай, бага давтагдсан байх явдал юм.. Энэ нь кодыг босгох/уншихад амархан болгох ба боломж бололцоог ихэсгэснээр дахин ашиглагдах зэрэг сайн тал өгч болно.

Албан ёсны параметр (Formal Parameters)
Формат

Ижил төрөлтэй параметрүүдийг боломжийнх нь хэрээр нэг statement -ээр нэгтгэнэ.

 procedure Foo(Param1, Param2, Param3: Integer; Param4: string);

Нэрлэх

Бүх параметрүүдийн нэр нь тэдний зорилгыг агуулж байна. Параметрийн нэр нь угтвартаа A тэмдэг авах нь зүйтэй. Жишээ нь:

 procedure SomeProc(AUserName: string; AuserAge: integer);

Учир нь A угтвар нь class-н property болон талбартай ижил нэртэй болохоос зайлсхийхэд ашиглагдана.

Параметрийн дараалал

Хэрэглэгчийн хамгийн их ашиглаж байгаа параметр нь эхний параметрийн нүдэнд байрлана. Түүнээс багаар ашиглагдаж байгаа параметрүүд нь харгалзан зүүнээсээ баруун тал руу дараалан байрлана.

Оролтын параметрүүдийн дараалал нь гаралтын параметрүүдын дараалалын өмнө зүүнээс баруун руу дараалан байрлана.

Илүү ерөнхий параметр нь тусгай параметрүүдийнхээ өмнө зүүнээс баруун руу дараалан байрлана. Жишээ нь: SomeProc(APlanet, AContinent, ACountry, AState, ACity).

Event handler –н тохиолдолд эдгээр дүрмүүдээс гадна байж болно. Жишээ нь TObject төрөлтэй Sender нэртэй параметр нь үргэлж эхний параметр болно.

Тогтмол параметрүүд

Record, array, ShortString, эсвэл interface төрөлийн параметрүүд нь тогтсон загвараар өөрчлөгдөшгүй юм.

SysUtils.FindClose(SR);
эсвэл
Windows.FindClose(Handle);

Хувьсагч (Variables)
Хувьсагч нэрлэх болон формат

Хувьсагчийн нэр нь түүний зорилгын утга санааг агуулсан байдаг.

Давталтыг удирдах хувьсагчын нэрийг ерөнхийдөө i, j, k гэх мэт нэг тэмдэгтээр өгдөг. Энэ нь UserIndex мэтийн утга бүхий нэр өгсөнөөс илүү тохиромжтой юм.

Boolean хувьсагчидийн нэрийг хангалттай тайлбарлах ёстой.

Ихэнх тохиолдолд хувьсагчийн нэрийг түүний зорилгыг хангалттай тодорхойлохоос гадна түүний төрөлийг илэрхийлсэн байхаар өгдөг. Жишээ нь CustName нь string төрөлтэйг илэрхийлж байхад OutstandingBalance нь currency төрөлтэй юм байна гэж ойлгогдож байна. Хэрэв өгөгдөлийн төрөлийг нарийн тодорхойлж чадаагүй бөгөөд өгөгдөлийн төрөлийг тодорхойлох шаардлагатай бол яах вэ? Ийм нөхцөл шалтгааны улмаас угтвар ашигладаг. Жишээ нь:

i : Integer  c : Character  d : Double  o : [An Object]  v : Variant
l : Long  w : Word  r : Real  f : File  b : Boolean
by : Byte  s : String  dt : TDateTime  lst : TStringList  ov : OleVariant

Хувьсагч зарлах

Хувьсагч зарлахдаа нэг төрөлтэй олон зарлалтуудийг хийнэ. Хувьсагч бүр нь тусдаа өөр өөрийн төрөлөөр хангагдсан байна. Жишээ нь:

 Var
i: Integer;
j: Integer;

Хувьсагч зарлах бүрийн өмнө нь var түлхүүр үг өмнө нь бичих нь тохиромжтой. Жишээ нь:

 var i: Integer;
var j: Integer;

Олон зарлалт хийж байх үед давхар цэгээр нь зэрэгцүүлэлт хийвэл гаргацтай байхад тус болно. Мөн өгөгдөлийн төрөлөөр нь бүлэглэх нь ач холбогдолтой. Жишээ нь:

// Difficult to read.
var
sDateTime : string;
dtNow : TDateTime;
i, j: Integer;
sDay : string;
iTotalDays : Integer;

// Clearly legible.
var
dtNow      : TDateTime;
iTotalDays : Integer;
i          : Integer;
j          : Integer;
sDateTime  : string;
sDay       : string;

Локаль хувьсагч

Локаль хувьсагчийн нэрлэх дүрэм нь бусад хувьсагч нэрлэх дүрэмтэй адилхан. Temp хувьсагчид нь зүй зохистойгоор нэрлэгдсэн байх хэрэгтэй.

Хэрэв шаардлагатай бол дүрэм журамандаа локаль хувьсагчид анхны утга өгөхийг тусгана. Локаль AnsiString хувьсагч нь автоматаар хоосон string –г анхны утга болгон авдаг байхад, локаль interface болон disinterface төрөлүүд нь nil утга, локаль Variant болон OleVariant төрөлүүд нь Unassigned утгыг автоматаар тус тус авдаг байна.

Global Хувьсагчийг хэрэглэх

Global хувьсагч ашиглахийг хориглодог. Хэдий тийм боловч тэднийг шаардлагатай гэж үзвэл хэрэглэнэ. . When this is the case, you are encouraged to keep global variables within the context where they are used. Жишээ нь: Global хувьсагчийн цар хүрээ нь зөвхөн нэг unit –н мужид байж болно.

Хэд хэдэн unit –үүд ашиглах Global өгөгдөлийг бүх unit ашигладаг ерөнхий unit –рүү шилжүүлнэ.Global хувьсагчид зарлагдсан var хэсэгт нь шууд анхны утга олгогдож болно. Бүх global хувьсагчид нь автоматаар zero анхны утга авдаг. Иймээс global хувьсагчидад “хоосон” анхны утга олгох хэрэггүй юм. Жишээ нь 0, nil, Unassigned гэх мэт. Учир нь zero анхны утга олгогдсон global хувьсагч нь exe файлд зай эзэлдэггүй. Zero анхны утга олгогдсон өгөгдөл нь ‘virual’ өгөгдөлийн segment –д хадгалагдах ба application нь ажиллахад санах ойд байрлана. Харин zero –оос ондоо анхны утга олгогдсон хувьсагчууд нь диск дээрх exe file –д зай эзэлдэг.

Zero анхны утга олгогдсон global хувьсагчид тодорхой тайлбар нэмж өгөх хэрэгтэй. Жишээ нь:

 Var
I: Integer { = 0 };

Төрөл (Types)
Том үсэг хэрэглэх журам (Capitalization Convention)

Нөөцлөгдсөн үгс төрөлийн нэрүүд бүгд жижигээр бичигдэнэ (integer, string . . .). Win32 API –н төрөлүүд нь ерөнхийдөө бүгд томоор бичигддэг. Төрөлийн нэрийг бичихдээ Windows.pas болон бусад API unit –үүд дээр бичигдсэн тогтсон бичилтийг ашиглах нь зүйтэй юм. Хувьсагчийн нэр нь томоор эхэлсэн тэмээний бөх мэт хэлбэртэй бол илүү цэвэрхэн уншихад амар болно. Жишээ нь:

 Var
MyString: string;  // reserved word
WindowHandle: HWND; // Win32 API type
I: Integer;         // type identifier introduced in System unit

Floating point төрөл

Real төрөлийг ашиглахыг хориглодог, учир нь энэ төрөл нь өмнөх үеийн Pascal –д ашиглагддаг байсан ба одоо хоцрогдсон юм. Floating point хэрэг болсон бол ерөнхий зориулалтаар Double –г ашиглана. Also, Double is what the processor instructions and busses are optimized for. Double нь IEEE –аас тодорхойлсон стандарт өгөгдөлийн төрөл юм. Extended –г зөвхөн Double –аас илүү том хэмжээ хэрэгтэй бол ашиглаж болно. Extended бол Intel –ээс тодорхойлсон төрөл ба Java дээр дэмжигддэггүй юм. Single –г зөвхөн floating point өгөгдөлийн бодит хэмжээ нь олон талын зориулалттай бол ашиглана. (жишээ нь өөр хэл дээр бичигдсэн DLL –г ашиглах г.м.)

Тоочих төрөл (Enumerated Type)

Тоочих төрөлийн нэр нь тоочиж буй зорилгоо агуулсан утгатай байх ёстой. Төрөлийн нэр нь урдаа Т угтвар авч явах ёстой ба энэ нь төрөлийн зарлагаа гэдэгийг товчлон бичиж буй хэлбэр юм. Тоочих төрөлийн элементүүд нь жижигээр бичигдсэн 2-3 тэмдэгтийг өөрийн нэрийн угтварт авах бөгөөд энэ нь тоочих төрөлтэй нь холбож өгнө. Жишээ нь:

 TSongType = (stRock, stClassical, stCountry);

Тоочих төрөлтэй зарлагдаж байгаа хувьсагчидийн нэр нь уг тоочих төрөлтэй ижил нэртэй ба Т угтваргүй байна (SongType) Үгүй бол илүү тодорхой нэр өгнө. Жишээ нь FavoriteSongType1, FavoriteSongType2 г.м.

Variant болон OleVariant

Variant болон OleVariant –н хэрэглээг ерөнхийдөө хориглодог боловч өгөгдөлийн төрөл нь зөвхөн runtime үед л мэдэж болдог програмчилалд зайлшгүй хэрэгтэй юм. Жишээ нь COM, өгөгдөлийн сантай ажиллах зэрэгт үргэлж тохиолдоно. COM –дээр үндэслэгдсэн програмчилалд (Автоматжуулах, ActiveX) OleVariant-г, non-COM програмчилалд Variant төрөлүүдийг тус тус ашиглана. Үүний учир шалтгаан нь Variant нь Delphi –н үндсэн string –г амжилттай хадгалж чаддаг(string төрөл шиг) байхад OleVariant нь бүх string –г OleString (WideChar string) –рүү хөрвүүлдэг мөн not reference counted-they are always copied.

Бүтэцлэгдсэн төрөл (Structured Types)
Массив төрөл (Array type)

Array төрөлийн нэр нь түүний зорилгоо агуулсан утгатай байх ёстой. Төрөлийн нэр нь угтвартаа T үсэг авах ёстой. Хэрэв array төрөлийн заагч зарлах бол нэрын өмнө нь P үсэг тавих ба зарлагаа нь array төрөлийн зарлагааны яг өмнө байрлах болно. Жишээ нь:

  Type
PCycleArray = ^TCycleArray;
TCycleArray = array[1..100] of Integer;

Хэрэв array төрөлийн хувьсагчийг түүнтэй ижил нэртэйгээр зарлах болсон бол нэрийн угтварт T үсэг тавихгүй.

Бүтэц төрөл (Record types)

Record төрөлийн нэр нь түүний зорилгоо агуулсан утгатай байх ёстой. Төрөлийн нэр нь угтвартаа T үсэг авах ёстой. Хэрэв record төрөлийн заагч зарлах бол нэрын өмнө нь P үсэг тавих ба зарлагаа нь record төрөлийн зарлагааны яг өмнө байрлах болно. Record төрөл дотор зарлагдаж байгаа элементүүд нь нэг догол мөрд зэрэгцүүлэгдсэн байх нь тохиромжтой. Жишээ нь:

 Type
PEmployee = ^TEmployee;
TEmployee = record
Name: string;
Rate: Double;
End;

Бичилт (Statement)

If statement

If statement –н гинжин цуваанаас аль болох зайлсхийх хэрэгтэй. Бүх if statement -н оронд case statement –г ашиглана.

If statement –г 5 түвшингээс илүү байгуулахгүй байх.

If statement-д шаардлагагүй хаалт ашиглахгүй байх.

Хэрэв if statement –д хэд хэдэн нөхцөл байвал хялбар үйлдэлтэйг нь зүүн талд тооцоо ихтэйг баруун тал руу харгалзуулан байрлуулна. This enables your code to take advantage of short-circuit Boolean evaluation logic built into the compiler. Жишээ нь: Condition1 нь Condition2 оос илүү хурдан, Condition2 нь Condition3 аас илүү хурдан ажилладаг бол if statement-г доор үзүүлсэн дараалалаар байрлуулна.

 if Condition1 and Condition2 and Condition3 then

Хэрэв хэд хэдэн нөхцөл шалгаж байвал заримдаа нөхцөл бүрийг нэг мөрөнд байрлуулах нь дээр байдаг. Ялангуяа нөхцөлүүд урт байхад энэ нь чухал юм. Хэрэв энэ загварыг сонгосон бол нөхцөлүүд нь бие биендээ зэрэгцүүлэгдсэн байна. Жишээ нь:

 if Condition1 and
Condition2 and
Condition3 then

Дээрээс доошоо унших нь зүүнээс баруун руу уншихаас үргэлж хялбар байдаг. Ялангуяа урт, цогц кодтой ажиллаж байхад хялбар байна.

Хэрэв if statement –н хэсэг нь нэг мөрөөс хэтэрвэл begin/end хосыг ашиглаж бүлэглэх нь дээр. This rule shall also apply when only a comment line is present or when a single statement is spread over multiple lines.

Else үг(clause) нь үргэлж харгалзах If үгтэй зэрэгцсэн байна.

Case Statements

Ерөнхий сэдэв

Case statement доторх нөхцөлүүд нь нөхцөл шалгах тогтмол болох тоогоороо эсвэл үсгийн дараалалаараа эрэмблэгдэж байрлана. Хэрэв хэрэглэгчийн тодорхойлсон төрөл ашиглаж байгаа бол бичлэгүүдийн дараалал нь уг төрөлүүдийн зарласан дараалалтай адил байна.

Зарим тохиолдолд case statetment –үүдийг дараалуулахдаа чухал эсвэл олон дахин ашиглагддагаар нь байрлуулах нь дээр байдаг.

Case statement доторх нөхцөл бүрийн харгалзах код нь ганц байвал дээр ба 4-5 хэтэрэхгүй байх ёстой. Хэрэв шаардлагатай үйлдэл нь илүү цогц бол хэд хэдэн процедур, функцүүд ашиглах нь зүйтэй. Локаль процедур, функцүүд нь энэ тохиолдолд илүү тохиромжтой юм.

Case statement дэхь else clause –г зөвхөн албан ёсны default -уудад (legitimate defaults) ашигласах хэрэгтэй. Ө.х алдаа илрүүлэх, document assumptions, raising an exception зэрэгт ашиглана.

Case statement –н хэсэг тус бүр нь догол мөрд байрлах ба бүх нөхцөлийн statement –үүдийн код нь begin..end дотор бичигдэнэ. Харин else clause нь case statement –тай зэрэгцэнэ. Жишээ нь

 case Condition of

condition:
begin
...
end;

else { case }
...
end;

else clause-г case statement –д харьяалагдана гэдэгийг илэрхийлэх тайлбар бичиж өгнө.

Case statement нь бусад форматын дүрэм (догол мөр гаргах) нэрлэх дүрмүүдийг мөрдөнө.

While Statements

Давталт хийгдэж байхад Exit процедурын тусламжтайгаар давталтаас гарахыг хориглоно. Аль болох давталтаас өөрийн давталтын нөхцөлийг ашиглан гарах хэрэгтэй.

While давталтын бүх анхны утга тогтоох кодыг while давталт руу орохын яг өмнө байрлуулах ба бусад non-related statement –ээр салгах хэрэггүй.

For Statements

for statements should be used in place of while statements when the code must execute for a known number of increments.

In those cases, where stepping is needed, use a while statement that starts from the known end of the loop down to start condition – for example:

i := AList.Count-1;
while i => 0 do
i := i - 2;

repeat statements

repeat statements нь while давталттай ижил ба адил дүрэм баримтлана.

With Statements

With statement -г цөөн, илүү болгоомжтой ашиглах хэрэгтэй. With statement-г давхардуулан хэрэглэхээс зайлсхийж, хэд хэдэн object, record зэрэг ашиглахдаа болгоомжой хандах хэрэгтэй. Жишээ нь:

with Record1, Record2 do

With statement –г давхардуулахаас зайлсхийх хэрэгтэй. Жишээ нь:


with Object1 do
begin
with Object2 do
begin
{ Do some code ...}
end;
end;

Эдгээр зүйлүүд нь програмистуудыг андууруулж төөрөгдүүлэх ба програмыг хүнд болгох, bug –тай болгоход хөтлөх болно. Нэмж хэлэхэд комплятор нь ямар нэг шалгах үйлдэл хийж чадахгүй ба debugger нь run-time –н үед хувьсагчуудыг задалж харж чадахгүй.

Case statement нь бусад форматын дүрэм(догол мөр гаргах) нэрлэх дүрэмүүдийг мөрдөнө.

Бүтэцлэгдсэн Exception Handling (Structured Exception Handling)

Exception handling алдааг зүгшрүүлэх, resource хамгаалахад хоёуланд нь ашиглагдах хэрэгтэй. try..finally нь resource –г зөвөөр чөлөөлөгдсөнд итгэлтэй байхад ашигладаг.

try..finally –н хэрэглээ

Аль болох бүх байгуулагчууд try .. finally бүтэцтэй харгалзан байх хэрэгтэй. Жишээ нь: доорх код нь байж болох bug –г удирдана.

SomeClass1 := TSomeClass.Create
SomeClass2 := TSomeClass.Create;
try
{ do some code }
finally
SomeClass1.Free;
SomeClass2.Free;
end;

Дээрх байгуулагчийг илүү аюулгүйгээр доор үзүүлсэнээр байгуулж болно.


SomeClass1 := TSomeClass.Create
try
SomeClass2 := TSomeClass.Create;
try
{ do some code }
finally
SomeClass2.Free;
end;
finally
SomeClass1.Free;
end;
try..except –н хэрэглээ

try..except –г зөвхөн exception raised болох үед зарим үйлдэл хийхийн тулд ашиглана. Ерөнхийдөө try..except –г энгийн алдааны мэдээлэлийг дэлгэцэнд харуулахад ашиглах хэрэггүй юм. Учир нь үүнийг Apllication object автоматаар гүйцэтгэдэг.

try..except блокт нөхцөл шалгах үйлдэл хэзээ ч ашиглаж болохгүй.

// The following code should be avoided.
var
iMyInt : Integer;

begin
try
iMyInt := StrToInt(GetSomeValue);
except
ShowMessage('Error: not an integer value.');
end;
end

// A better solution.
var
iMyInt : Integer;

begin
// The method IsInteger checks for the correct 
if IsInteger(GetSomeValue) then  data type.
iMyInt := StrToInt(GetSomeValue)
else
ShowMessage('Error: not an integer value.');
end

Класс (Classes)
Нэрлэх / Формат

Class -н нэр нь түүний зорилгоо агуулсан утгатай байх ёстой. Төрөлийн нэр нь урдаа Т угтвар авч явах ёстой ба энэ нь төрөлийн зарлагаа гэдэгийг товчлон бичиж буй хэлбэр юм. Жишээ нь:

Type
TCustomer = class(TObject)

Тухайн Class –аар зарлагдаж байгаа обьектийн нэр нь class –н нэртэй ижил бөгөөд T угтваргүй байна. Жишээ нь:

Var
Customer: TCustomer;
Талбар (Field)
Нэр / формат

Class –н талбаруудын нэрийг хувьсагчын нэрийг өгөхтэй ижил дүрэмээр өгөх ба ялгаатай нь F үсэг угтвартаа авна. Энэ нь талбарын нэр гэдэгийг илэрхийлдэг.

Харагдалт (Visibility)

Бүх талбарууд private байх хэрэгтэй. Class –н мужийн гаднаас талбарт хандахын тулд property –г ашиглаж хандана.

Зарлагаа

Талбар бүр нь өөр өөрийн төрөл болон мөрөнд зарлагдах хэрэгтэй. Жишээ нь:

TNewClass = class(TObject)
private
FField1: Integer;
FField2: Integer;
end;

Method
Нэр / формат

Method –н нэрийг өгөхдөө энэ бичиг баримтанд дурдсан функц процедурын нэр өгөх дүрэмийг мөрдөнө.

Static Method –н хэрэглээ

Статик method –г хүү class уудад дахин тодорхойлогдохгүй гэж шийдсэн тохиолдолд ашиглана.

Virtual / dynamic method-н хэрэглээ

Virtual method –г хүү class –уудад дахин тодорхойлогдоно гэж шийдсэн үед ашиглана. Динамикыг зөвхөн маш олон хүү class уудтай болох тохиолдолд ашиглах хэрэгтэй (шууд болон шууд бус). Жишээ нь class нь хааяа хэрэглэддэг дахин тодорхойлогдсон method -той ба 100 хүүт class -тай бол method –г динамик болгосоноор 100 хүү class –н ашиглах санах ойг багасгана.Энэ нь хэдийгээр батлагдаагүй боловч method-г virtual –н оронд динамик болгосоноор санах ойн шаардлагыг багасгана.Үргэлж virtual method ашигла, зөвхөн онцгой шаардлагын доор л динамикыг ашигла.

Abstract Method –н хэрэглээ

Обьект зарлагддаг Class –д abstract method –г ашиглах хэрэггүй. Зөвхөн хэзээ ч обьект үүсдэггүй үндсэн class –д abstract –г ашиглана.

Property Access Methods

Бүх хандах method нь class-н зарлагааны private юмуу protected хэсэгт байрлах ёстой.

Property access method –н нэрлэхдээ функц, процедур нэрлэх дүрэмийг баримтална. Унших хандалттай method нь Get угтвар, бичих хандалттай method нь Set угтвар тус тус авах ёстой. Бичигч method нь Value нэртэй параметртэй байх ба and its type will be that of the property it represents

TSomeClass = class(TObject)
private
FSomeField: Integer;

protected
function GetSomeField: Integer;
procedure SetSomeField(Value: Integer);

public
property SomeField: Integer
read GetSomeField
write SetSomeField;
end;

Properties
Нэр / Формат

Private талбар луу хандагч болж ашиглагдаж байгаа property –н нэр нь тухайн талбарынхаа нэртэй адил байх ба харин F угтваргүй байна.

Property –н нэр нь нэр үг байх нь зүйтэй(Үйл үг биш). Property өгөдөлийг илэрхийлж байхад method нь үйлдэлийг илэрхийлнэ.

Array property –н нэр нь олон тоон дээр байна. Хэвийн property –н нэр нь энгийн байна.

Албан ёсоор property –ууд нь доор үзүүсэнчлэн форматлагдсан байх хэрэгтэй.


property SomeField: Integer
read GetSomeField
write SetSomeField;
Access Method –н хэрэглээ

Хэдийгээр шаардагддаггүй боловч property –уудын private талбарт байрлах бичих хандалттай method-уудыг хамгийн багаар хэрэглэхийг дэмждэг.

Файлууд
Project files

Project file –ууд нь тайлбарласан нэртэй байна. Жишээ нь The Delphi 4 Developer’s Guide Bug Manager –д өгсөн project –н нэр нь DDGBugs.dpr гэж өгсөн байхад системийн мэдээлэлийн програмын нэр нь SysInfo.dpr байна.

Form File

Form file нь түүний зорилгыг тодорхойлсон нэрийн араас Frm гэсэн 3 тэмдэгтийг залгуулж бичнэ. Жишээ нь About Form –н file –н нэр нь AboutFrm.dfm байх юм. Main Form –н file –н нэр нь MainFrm.dfm .

Data Module File

Data module –н нэр нь түүний зорилгыг тодорхойлсон байна. Нэрийн төгсгөлд DM гэсэн 2 тэмдэгтийг залгуулан бичнэ. Жишээ нь: Customers data module –н file –н нэр нь CustomersDM.dfm байна.

Remote Data Module File

Remote Data module –н нэр нь түүний зорилгыг тодорхойлсон байна. Нэрийн төгсгөлд RDM гэсэн 3 тэмдэгтийг залгуулан бичнэ. Жишээ нь: Customers remote data module –н file –н нэр нь CustomersRDM.dfm байна.

Unit File
Unit Name

Unit file –н нэр нь тайлбарласан шинжтэй байна. Жишээ нь unit нь application –н main form –г агуулж байгаа бол MainFrm.pas гэсэн нэртэй байна.

Uses Clause

Interface хэсэгт байгаа uses clause –д зөвхөн кодонд шаардлагатай unit –үүдийг л байрлуулна. Delphi –ээс автоматаар оруулагдсан шаардалагагүй unit –н нэрийг устгана.

Implementation хэсэгт байгаа uses clause –д зөвхөн кодонд шаардлагатай unit –үүдийг л байрлуулна. Шаардлагагүй unit –н нэрийг устгана.

Interface хэсэг (Interface section)

Interface хэсэгт зөвхөн дараах зарлагаанууд байна : төрөл, хувьсагч, процедур/функцын өмнөх зарлагаа. Эдгээр нь гадаад unit –ээс хандах боломжтой юм. Үүнээс өөр тохиолдод эдгээр зарлагаанууд нь implementation хэсэгт байрлана.

Implementation хэсэг

Implementation хэсэгт төрөл, хувьсагч, процедур/функц зэрэг ямарч зарлагаа байж болох ба тэдгээр нь тухайн агуулж буй unit –нхээ private хэсэг болно.

Анхны утга тогтоох хэсэг (Initialization section)

Initialization section –ий хэсэгт хугацаа ихээхэн зарцуулах код байрлуулж болохгүй. Энэ нь application –г эхэлж ачаалахад их удаан мэт санагдуулдаг.

Төгсгөх хэсэг (Finalization Section)

Initialization хэсэгт байгуулагдсан зүйлс бүгд чөлөөлөгдсөн байхыг хангаж өгнө (ensure).

Form Units

Form –н unit file –н нэр нь харгалзах form file –н нэртэй адил байна. Жишээ нь: About Form –н unit –н нэр нь AboutFrm.pas байна. Main Form –н unit file –н нэр нь MainFrm.pas байна.

Data Module Unit

Data module –н unit file –н нэр нь харгалзах form file –н нэртэй адил байна. Жишээ нь: Customers data module –н unit-н нэр нь CustomersDM.pas байна.

Ерөнхий зориулалтын unit (General Purpose Units)

Ерөнхий зориулалтын unit –н нэр нь тухайн unit-н зорилгоо агуулсан утгатай байна. Жишээ нь: Хэрэгсэл (utility) unit –н нэр нь BugUtilities.pas байна. Глобаль хувьсагчуудыг агуулж буй unit –н нэр нь CustomerGlobals.pas байна.

Ашиглаж байгаа project –н бүхий л хэсэгт(packages) unit –н нэр нь цор ганц байна гэдэгийг сайтар тогтоож аваарай.

Component Units

Component unit –үүд ондоо хавтсанд хуваарилагддаг ба ингэснээр тэднийг component тодорхойлох unit –үү эсвэл component –н суулгасан unit –үү гэдэгийг ялгаж өгнө. Unit –н нэр нь агуулгын хаа утга санааг илэрхийлэхээр байна.

Файлын толгой (File Header)

Бүх source file, units, project file –н толгой хэсэгт мэдээлэлийн File Header –н хэрэглээг сайшааж үздэг. Шаардлагын дагуух file header нь доорх мэдээлэлүүдийг агуулж байх ёстой.

 {
Copyright © YEAR by AUTHORS
}

Header -т холбоо барих мэдээлэл, нэг мөр тодорхойлолтыг үргэлж тусгаж өгдөг. Үүний жишээ нь дараах байдалтай байж болно.

{***************************************************************}
{                                                               }
{  This line describes the purpose of the unit                  }
{                                                               }
{  Copyright (c) 1998 WidgetMakers, Ltd.                        }
{                        contact@WidgetMakers.corp              }
{                                                               }
{     All rights reserved.                                      }
{                                                               }
{***************************************************************}
Forms and Data Modules
Forms
Form –н төрөл, нэрлэх стандарт

Form –н төрөлийн нэр нь form –н зорилгыг тодорхойлсон байна. Угтварт нь Т үсэг тавьсанаар төрөл гэдэгийг илэрхийлнэ. Т үсэгийн дараа нэр байрлах ба нэрийн дараа Frm гэсэн төгсгөл авна. Жишээ нь: About Form –н төрөлийн нэр нь

TAboutFrm = class(TForm)
Main Form –нх
TMainFrm = class(TForm)

Үйлчлүүлэгчидийн тэмдэглэлийн form -н (customer entry form) нэр нь дараахь байдалтай байна.

TCustomerEntryFrm = class(TForm)

Form обьект, нэрлэх стандарт (Form Instance Naming Standard)

Form обьектын нэр нь харгалзах form –н төрөлийн нэртэй адил ба Т угтваргүй байна. Жишээ нь :

Type Name Instance Name
TAboutFrm AboutFrm
TMainFrm MainFrm
TCustomerEntryFrm CustomerEntryFrm
Auto-creating Forms

Зөвхөн Main Form –л автоматаар үүсгэнэ. Бусад бүх form –ууд нь auto-create жагсаалтаас хасагдсан байх ёстой(Project ->Option dialog box).

Modal Form Instantiation Functions

Бүх form –н unit –үүд нь instantiation function агуулах ба тэд form –г modal байдлаар үүсгэж, суулгаж(set up), үзүүлнэ(show). Энэ функц нь form –оос буцсан modal үр дүнг буцаана. Функц рүү параметр дамжуулахдаа уг бичиг баримтанд дуртдсан параметр дамжуулах стандартыг мөрдөнө. Доорх Unit -д UserData form –д зориулсан функцын жишээг үзүүлэв.

unit UserDataFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;
type
TUserDataForm = class(TForm)
edtUserName: TEdit;
edtUserID: TEdit;
private
{ Private declarations }
public
{ Public declarations }
end;

function TUserDataForm.GetUserData(var aUserName: string; var aUserID: Integer): Word;

implementation

{$R *.DFM}

function GetUserData(var aUserName: string; var aUserID: Integer): Word;
var
UserDataForm: TUserDataForm;
begin

UserDataForm := TUserDataForm.Create(Application);
try

UserDataForm.Caption := 'Getting User Data';
Result := UserDataForm.ShowModal;
if Result = mrOK then
begin
aUserName := UserDataForm.edtUserName.Text;
aUserID := StrToInt(UserDataForm.edtUserID.Text);
end;

finally
UserDataForm.Free;
end;

end;

end.

Data Modules

Data module –н төрөлийн нэр нь түүний зорилгыг тодорхойлсон байна. Угтварт нь Т үсэг тавьсанаар төрөл гэдэгийг илэрхийлнэ. Т үсэгийн дараа нэр байрлах ба нэрийн дараа DM гэсэн төгсгөл авна. Жишээ нь: Customer data module –н төрөлийн нэр нь доорх байдалтай байж болно.

 TCustomerDM = class(TDataModule)
Orders data module –н нэр доорх байдалтай байж болно.
TOrdersDM = class(TDataModule)

Data Module–н обьект нэрлэх стандарт
(Data Module Instance Naming Standard)

Form обьектын нэр нь харгалзах form –н төрөлийн нэртэй адил ба Т угтваргүй байна. Жишээ нь :

Type Name Instance Name
TCustomerDM CustomerDM
TOrdersDM OrdersDM
Packages
Runtime болон Design Package –уудын хэрэглээ

Runtime package –ууд нь тухайн package доторх componentуудад шаардалагатай unit/component –уудыг агуулна. Бусад property агуулсан unit / component editor зэрэг зөвхөн design үед хэрэглэгдэх кодууд нь design package дотор байрлана. Registration unit –үүд нь design package –д байрлана.

File –г нэрлэх стандарт

Package –үүд нь доорх загварын дагуу нэрлэгдэнэ.

"iiilibvv.pkg" - design package
"iiistdvv.pkg" - runtime package

“iii” гэж угтвартаа авсан 3 тэмдэгт нь identify зорилгоор ашиглагдана. Энэ угтварт компани, хувь хүн зэрэг бусад таниж болох зүйлс(identifying entity) байна.
“vv” гэсэн тэмдэглэгээ нь Delphi –н ямар хувилбарт таарахыг илэрхийлнэ.
“lib” , “std” тэмдэглэгээ нь тогтмолоороо байх ба runtime package –уу designtime package –уу гэдэгийг тодорхойлно.

Жишээ нь Delphi 4 Developer's Guide package –н нэр нь:
DdgLib40.pkg - design package
DdgStd40.pkg - runtime package

Components
Хэрэглэгчийн тодорхойлсон component –ууд (User-defined Components)

Component –г нэрлэх дүрэм нь “Class”-г нэрлэх дүрэмтэй адил байх ба ялгаа нь 3 тэмдэгт угтвартаа авна. Энэ угтвараар компани, хувь хүн болон бусад зүйлсийг танихад (identify) ашиглаж болно. Жишээ нь: Delphi 4 Developer’s Guide –д зориулсан Clock component нь доорх байдалаар бичигдсэн байна.

TddgClock = class(TComponent)

Угтвартаа авч буй 3 тэмдэгтийг жижигээр бичигдсэнийг анхаарах хэрэгтэй.

Component Units

Component unit –үүд нь нэг гол component –д (Major component) харяалагдана. Гол component гэдэг нь Component Palette дээр байрлаж байгаа ямар ч component байж болно. Any ancillary components / objects may also reside in the same unit for the major component.

Registration Unit –үүдийн хэрэглээ (Use of Registration Units)

Component-г registration procedure нь componet unit –ээс арилгагдаж ялгаатай unit –д байрлана. Registration unit нь component, property editor, component editor, expert зэрэгийг бүртгэхэд ашиглагдана.
Component бүртгэх үйл явц зөвхөн design package -аас хийгдэнэ. Иймээс registration unit нь runtime package –д биш designtime package -д агуулагдана.
registration unit –г доорх байдлаар нэрлэхийг зөвлөдөг.

XxxReg.pas

“Xxx” нь компани, хувь хүн болон бусад зүйлийг илэрхийлж болно. Жишээ нь: Delphi 4 Developer’s Guide –н registration unit нь DdgReg.pas байдлаар нэрлэгдэж болно.

Component-н обьектын нэрлах дүрэм
(Component Instance Naming Conventions)

Бүх component –ууд нь тодорхойлсон нэртэй байх ёстой.

Standard Tab
Prefix Component
mm TMainMenu
pm TPopupMenu
mmi TMainMenuItem
pmi TPopupMenuItem
lbl TLabel
edt TEdit
mem TMemo
btn TButton
chk TCheckBox
rb TRadioButton
lb TListBox
cb TComboBox
scb TScrollBar
gb TGroupBox
rg TRadioGroup
pnl TPanel
cl TCommandList
Additional Tab
Prefix Component
bbtn TBitBtn
sb TSpeedButton
me TMaskEdit
sg TStringGrid
dg TDrawGrid
img TImage
shp TShape
bvl TBevel
sbx TScrollBox
clb TCheckListbox
spl TSplitter
stx TStaticText
cht TChart

Win32 Tab
Prefix Component
tbc TTabControl
pgc TPageControl
il TImageList
re TRichEdit
tbr TTrackBar
prb TProgressBar
ud TUpDown
hk THotKey
ani TAnimate
dtp TDateTimePicker
tv TTreeView
lv TListView
hdr THeaderControl
stb TStatusBar
tlb TToolBar
clb TCoolBar

System Tab
Prefix Component
tm TTimer
pb TPaintBox
mp TMediaPlayer
olec TOleContainer
ddcc TDDEClientConv
ddci TDDEClientItem
ddsc TDDEServerConv
ddsi TDDEServerItem

Internet Tab
Prefix Component
csk TClientSocket
ssk TServerSocket
wbd TWebDispatcher
pp TPageProducer
tp TQueryTableProducer
dstp TDataSetTableProducer
nmdt TNMDayTime
nec TNMEcho
nf TNMFinger
nftp TNMFtp
nhttp TNMHttp
nMsg TNMMsg
nmsg TNMMSGServ
nntp TNMNNTP
npop TNMPop3
nuup TNMUUProcessor
smtp TNMSMTP
nst TNMStrm
nsts TNMStrmServ
ntm TNMTime
nudp TNMUdp
psk TPowerSock
ngs TNMGeneralServer
html THtml
url TNMUrl
sml TSimpleMail
Data Access Tab
Prefix Component
ds TDataSource
tbl TTable
qry TQuery
sp TStoredProc
db TDataBase
ssn TSession
bm TBatchMove
usql TUpdateSQL

Data Controls Tab
Prefix Component
dbg TDBGrid
dbn TDBNavigator
dbt TDBText
dbe TDBEdit
dbm TDBMemo
dbi TDBImage
dblb TDBListBox
dbcb TDBComboBox
dbch TDBCheckBox
dbrg TDBRadioGroup
dbll TDBLookupListBox
dblc TDBLookupComboBox
dbre TDBRichEdit
dbcg TDBCtrlGrid
dbch TDBChart
Decision Cube Tab
Prefix Component
dcb TDecisionCube
dcq TDecisionQuery
dcs TDecisionSource
dcp TDecisionPivot
dcg TDecisionGrid
dcgr TDecisionGraph

QReport Tab
Prefix Component
qr TQuickReport
qrsd TQRSubDetail
qrb TQRBand
qrcb TQRChildBand
qrg TQRGroup
qrl TQRLabel
qrt TQRText
qre TQRExpr
qrs TQRSysData
qrm TQRMemo
qrrt TQRRichText
qrdr TQRDBRichText
qrsh TQRShape
qri TQRImage
qrdi TQRDBMImage
qrcr TQRCompositeReport
qrp TQRPreview
qrch TQRChart

Dialogs Tab
Prefix Component
TOpenDialog OpenDialog
TSaveDialog SaveDialog
TOpenPictureDialog OpenPictureDialog
TSavePictureDialog SavePictureDialog
TFontDialog FontDialog
TColorDialog ColorDialog
TPrintDialog PrintDialog
TPrintSetupDialog PrinterSetupDialog
TFindDialog FindDialog
TReplaceDialog ReplaceDialog

Win31 Tab
Prefix Component
dbll TDBLookupList
dblc TDBLookupCombo
ts TTabSet
ol TOutline
tnb TTabbedNoteBook
nb TNoteBook
hdr THeader
flb TFileListBox
dlb TDirectoryListBox
dcb TDriveComboBox
fcb TFilterComboBox
Samples Tab
Prefix Component
gg TGauge
cg TColorGrid
spb TSpinButton
spe TSpinEdit
dol TDirectoryOutline
cal TCalendar
ibea TIBEventAlerter

ActiveX Tab
Prefix Component
cfx TChartFX
vsp TVSSpell
f1b TF1Book
vtc TVTChart
grp TGraph

Midas Tab
Prefix Component
prv TProvider
cds TClientDataSet
qcds TQueryClientDataSet
dcom TDCOMConnection
olee TOleEnterpriseConnection
sck TSocketConnection
rms TRemoteServer
mid TmidasConnection

ExpressBars Tab
Prefix Component
xbm TdxBarManager
xbpm TdxBarPopUpMenu
xbc TdxBarConverter
xdbnav TdxBarDBNavigator
xsbs TdxSideBarStore
xsb TdxSideBar
xsbpm TdxSideBarPopUpMenu
xilb TdxImageListBox
xicb TdxImageComboBox
xspi TdxSpinImage
Dev Express Tab
Prefix Component
xcalc TdxCalculator
xcalcd TdxCalcDisplay
xtrlst TdxTreeList
xdbg TdxDBGrid
xdbgll TdxDBGridLayoutList
xmem TdxMemData
xdbins TdxDBInspector
xins TdxInspector

Express DBTreeList Tab
Prefix Component
xtv TdxTreeView
xdbtv TdxDBTreeView
xtve TdxTreeViewEdit
xdbtve TdxDBTreeViewEdit
xlutv TdxLookUpTreeView
xdblutv TdxDBLookUpTreeView
xdbtpd TdxDBTreePrintData
ExpressOrgCharts Tab
Prefix Component
xoc TdxOrgChart
xdboc TdxDBOrgChart
Эх сурвалжыг : http://khishgee-it.blogspot.com/
No comments yet

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: