Програм зохиох жишээ 1

Практикгүй онол бол хоосон зүйл гэж ярьдаг. Иймээс энэ хичээлээр .NET Framework -ийн стандарт сан WinForms -ийг ашиглан бүрэн хэмжээний програмыг зохиох болно. Хичээлийн зорилго бол өмнөх хичээлүүдэд үзсэн бүх аргчлалуудыг практикт хэрхэн ашиглахыг сурах юм. Эдгээрээс  интерфейсийг ашиглахыг түлхүү үзэх болно. Бидний зохиох програм бол энгийн текст засварлагч байх бөгөөд дараах зүйлсийг хийдэг байхаар боловсруулагдана.

Үүнд:

  1. Текстэн файлыг нээх
  2. Файлын агуулгыг засварлах
  3. Засварлахаар нээгдсэн файлын тэмдэгтийн тоог үзүүлэх
  4. Файлд оруулсан өөрчлөлтийг хадгалах
  5. Файлын агуулгын текстийн фонтын хэмжээг ихэсгэх ба багасгах боломж

Эдгээрийг бид програмын техникийн даалгавар гэж үзэж болох юм. Ингээд програм зохиох ажлаа эхлэе.

Visual Studio дээр төсөл /project/ үүсгэх

Visual Studio -г нээгээд File->New->Project гэж ороход нээгдэх New Project цонхонд зурагт үзүүлснээр тохиргоо хийгээд Ok товчийг дарна.

Төслийн нэрийг TextEditor гэж өгье. Location талбарт төслийг хадгалах хавтасны нэрээ сонгон өгч болно. Ok товчийг дарахад Windows програмын суурь хэвээр төслийг үүсгэнэ.

Ажлын цонх хэсэгт форм, програмын кодын засвар гээд үндсэн ажлуудыг гүйцэтгэнэ. Solution Explorer цонхонд таны төслийн агуулга харагдана. Ажлын дэлгэц дээрх цонхнуудыг View цэсийг ашиглан удирдаж болно. Visual Studio -той ажиллах нь ердийн Windows програмтай ажиллахтай төстэй тул ажиллаж сурахад амархан. Иймд Visual Studio -гийн ажиллагааны талаар хичээлд нарийн авч үзэхгүй. Шаардлагатай зүйлийг тухай бүрд нь тэмдэглээд явна. Нэг шийдэл буюу Solution -д олон төслүүд байж болдог. Одоо манай шийдэлд Windows орчинд шууд ажиллах exe өргөтгөлтэй файл болон компиляц хийгдэх TextEditor гэсэн нэг төсөл байгаа. Бидэнд бас нэгэн төсөл хэрэгтэй. Үүний тулд Solution -ний нэр дээрээс баруун даралт хийхэд гарч ирэх цэснээс Add->New Project командыг өгөхөд шинэ төсөл үүсгэхтэй ижилхэн шинэ төсөл нэмэх цонх нээгдэнэ. Цонхны дунд хэсгээс төслийн төрлийг Class Library гэж сонгоод төслийн нэрийг TextEditor.BL гэж өгье. Ингэснээр манай шийдэл доорх бүтэцтэй боллоо.

Шийдэлд багтсан хоёр төслийн TextEditor нь манай програмын хэрэглэгчид ашиглах төрөл бүрийн удирдах элементүүдийг харуулах интерфейсийн үүргийг гүйцэтгэнэ. Хоёрдахь төсөл TextEditor.BL -нь програмын логикийг агуулсан DLL сан байх юм. Өөрөөр хэлбэл програмын техникийн даалгаварт заагдсан функцуудыг хэрэгжүүлнэ. Програмын хэрэглэгчийн интерфейсийн хэсэг програмын цөмд хэрэгжүүлсэн функцуудыг ашиглах боломжтой болгохын тулд програмын графикийн хэсэг буюу TextEditor төсөлд TextEditor.BL төслийн холбоосыг үүсгэх шаардлагатай. Үүний тулд TextEditor төслийн References хэсгээс баруун даралт хийхэд гарах цэснээс Add Reference цэсээр ороод нээгдэх цонхонд дараах тохиргоог хийгээд

OK товчийг дарахад TextEditor төслийн References хэсгийн жагсаалтад TextEditor.BL төсөл орж ирнэ. Одоо TextEditor төслөөс TextEditor.BL төслийн функцуудад хандах боломжтой боллоо.

Програмын бизнес логикийн кодчлол

Програмын боловсруулалтаа бид түүний суурь функцууд буюу цөмөөс эхлэе. Анхдагч байдлаар Visual Studio -гоос TextEditor.BL төсөлд үүсгэсэн Class1.cs нэртэй файлыг устгаад TextEditor.BL төсөлд FileManager.cs шинэ классыг нэмэн өгөөрэй. FileManager класст бид програмын техникийн даалгаварт тусгагдсан бүх функцуудыг хэрэгжүүлэх юм. Visual Studio классыг анхдагч байдлаар үүсгэхдээ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TextEditor.BL
{
    class FileManager
    {

    }
}

гэсэн кодыг оруулан өгдөг. FileManager класст гаднаас хандахын тулд түүнийг public хандалтын төрөлтэй болгох хэрэгтэй. Кодын дээд хэсэгт байгаа using гэсэн удирдамжаар анхдагч байдлаар ашиглах нэрийн орон зайнуудыг зааж байгаа. Жишээ нь using System; гэх мэтээр
namespace буюу нэрийн орон зай гэж юу вэ? Нэрийн орон зай гэдгийг классуудын хавтас гэж ойлгож болно. Классуудыг төрөл зориулалтаар нь өөр өөр нэрийн орон зайд /хавтасуудад/ байрлуулснаар тэдгээрийг илүү нарийн зааглан хандалтыг ойлгомжтой, амархан болгон өгдөг. Та компьютер дээрх файлуудаа бүгдийг нэг хавтаст байрлуулбал ямар байх билээ. Файлуудыг цэгцтэй байлгах үүднээс тэдгээрийг хавтаст хувиарлан байрлуулдагтай адилаар төслийн классуудыг нэрийн орон зай буюу хавтасуудад хуваан өгөх нь цэгцтэй болоод ойлгомжтой болгоно. Жишээ нь манай FileManager класс TextEditor.BL нэртэй нэрийн орон зайд байрлана.
Visual Studio төслийг үүсгэхдээ анхдагч байдлаар оруулан ирсэн нэрийн орон зайнууд ашиглагдахгүй байх нь бий. Ийм тохиолдолд тэдгээрийг төслөөс хасах хэрэгтэй. Үүнийг доорх зурагт үзүүлснээр хасан өгнө.

FileManager классын кодын using удирдамжуудын хэсэгт хулганы заагчийг аваачихад зураг дээрх улаан хүрээн доторх тэмдэг гарч ирэх бөгөөд дүрсний баруун байрлах товчийг дарахад ашиглагдахгүй байгаа орон зайны нэрүүдийг үзүүлнэ. Remove Unnecessary Usings даран  ашиглагдаагүй орон зайн using удирдамжуудыг устгаад файлтай ажиллахад шаардлагатай System.IO орон зай, тект, кодчлол гэх зэрэгтэй ажиллахад хэрэгтэй System.Text орон зайг using System.IO; , using System.Text; гэж нэмэн өгөөрэй.
Манай техникийн даалгаварын 1-р зүйлээр програм текстийн файлыг нээж чаддаг байх ёстой. Энэ функцийг FileManager класс доорх кодод үзүүлснээр хэрэгжүүлнэ.

using System.IO;
using System.Text;

namespace TextEditor.BL
{
    public class FileManager
    {
        public string GetContent(string filePath, Encoding encoding)
        {
            string content = File.ReadAllText(filePath, encoding);
            return content;
        }

    }
}

Бид класст эхний параметрээр файлын замыг, хоёрдахь параметрээр файлын кодчлолыг авах GetContent аргыг тодорхойлон өгсөн. Арга File статик классын ReadAllText аргыг ашиглан өгөгдсөн файлын агуулгыг content хувьсагчид уншин аваад түүнийг удирдах кодод буцаана. Кодод бид File классын хувийг үүсгэлгүй шууд ашиглаж байгаа учраас энэ нь статик класс гэдгийг бид урд нь үзсэн. File класс System.IO орон зайд байрладаг. Нэрийн орон зайнд ямар классууд байдгийг мэддэг байх шаардлагатай.
Бид ихэнх тохиолдолд тодорхой кодчлолтой /өөрөөр хэлбэл UTF/ файлуудыг ашиглана гэдгийг бодох хэрэгтэй. Үүний тулд GetContent аргын хэт ачаалалтай /overloaded/ зөвхөн файлын замыг параметрээр авах аргыг тодорхойлоод файлын кодчлолыг талбараар заан өгсөн кодыг нэмье.

    public class FileManager
    {
        private readonly Encoding _defaultEncoding = Encoding.GetEncoding(65001);

        public string GetContent(string filePath)
        {
            return GetContent(filePath, _defaultEncoding);
        }

        public string GetContent(string filePath, Encoding encoding)
        {
            string content = File.ReadAllText(filePath, encoding);
            return content;
        }

    }

Кодод _defaultEncoding талбар үүсгээд түүнд анхдагч кодчлолын кодыг олгосон. Дараа нь хэт ачаалалтай зөвхөн файлын замыг параметрээр авах GetContent арга өмнө зарлагдсан байсан GetContent аргыг дуудахдаа _defaultEncoding талбарыг хоёрдахь параметр болгон дамжуулна. Ингэснээр бид програмын уян хатан байдлыг хангаж өгнө. Хэрвээ кодчлолыг заан өгөөгүй бол _defaultEncoding талбарын утгыг анхдагчаар авна. Үүнээс гадна нээх гэж байгаа файлын кодчлол _defaultEncoding талбарын утгаас өөр гэдгийг мэдэж байвал бид агуулыг уншихдаа түүний кодчлолыг шууд заан өгөх боломжтой. Хэт ачаалалтай аргын утга санаа үүнд л оршиж байгаа юм. Файлын агуулгыг унших ажиллагааг дээрх хоёр арга гүйцэтгэх болно.
Техникийн даалгаварын бас нэгэн шаардлага болох файлын агуулгыг хадгалах ажиллагааг нэмэн оруулъя.

    public class FileManager
    {
        private readonly Encoding _defaultEncoding = Encoding.GetEncoding(65001);

     // ...

        public void SaveContent(string content, string filePath)
        {
            SaveContent(content, filePath, _defaultEncoding);
        }

        public void SaveContent(string content, string filePath, Encoding encoding)
        {
            File.WriteAllText(filePath,content,encoding);
        }
    }

Файл хадгалах ажиллагаа нь агуулгыг уншихтай төстэй. Файлын агуулга, файлын зам, кодчлолыг параметрээр авах SaveContent арга File классын WriteAllText стандарт аргыг ашиглан агуулгыг заагдсан файлд хадгална. Үүний зэрэгцээ анхдагч кодчлолыг ашиглах SaveContent аргын хэт ачааллагдсан хувилбарыг тодорхойлсон.
Одоо FileManager класс файлын агуулгыг унших, түүнийг хадгалах боломжтой болсон. Гэхдээ дикс дээрх файлд хандахын өмнө тухайн файл үнэхээр байгаа эсэхийг шалгасан нь илүү. Файл байгаа эсэхийг шалгахын тулд IsExist аргыг

    public class FileManager
    {
        private readonly Encoding _defaultEncoding = Encoding.GetEncoding(65001);

        public bool IsExist(string filePath)
        {
            bool isExist = File.Exists(filePath);
            return isExist;
        }

        // ...
    }

гэж хэрэгжүүлье. Арга энгийн. Өгөгдсөн замаар файл байгаа эсэхийг File классын Exists стандарт аргыг ашиглан шалгана. Exists арга файл байвал True байхгүй бол False утгыг буцаана.   
Эцэст нь FileManager классын сүүлийн функционал болох файлын тэмдэгтийн тоолох GetSymbolCount аргыг тодорхойлон өгцгөөе.

    public class FileManager
    {
        private readonly Encoding _defaultEncoding = Encoding.GetEncoding(65001);

        // ...

        public int GetSymbolCount(string content)
        {
            int count = content.Length;
            return count;
        }
    }

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

Мэдээлэл таалагдсан бол найзуудтайгаа хуваалцаарай.

  Нээгдсэн тоо: 140 Төлбөртэй

Виртуал аргууд, шинжүүд хичээлд виртуал аргуудыг тодорхойлох, дахин тодорхойлохыг үзсэн. Суурь классаас өвлөн авсан функцтоналуудыыг өөрчлөх өөр арга бол нуух (shadowing / hiding) юм. Арга, шинжүүдийг нуух нь үнэндээ суурь классийн арга эсхүл шинжүүдтэй нэр, параметрүүдийн багцаар тохирох арга, шинжийг удамшсан класст тодорхойлох юм. Классийн гишүүнийг нуухдаа new түлхүүр үгийг хэрэглэдэг.

  Нээгдсэн тоо: 180 Төлбөртэй

Утгатай төрлийн хувьсагч болон параметрүүдэд null утгыг шууд олгож болдоггүйгээрээ холбоосын төрлөөс ялгаатай. Гэсэн хэдий ч утгатай төрлийн хувьсагч болон параметрүүдэд null утгыг олгох шаардлага гардаг. Жишээ нь өгөгдлийн сангаас тоон утга ирнэ гэсэн хүлээлттэй байтал өгөгдлийн сангийн талбар утгагүй байх. Өөрөөр хэлбэл өгөгдлийн санд утга байвал тоо үгүй бол null ирнэ гэсэн үг.

  Нээгдсэн тоо: 274 Төлбөртэй

Төрөл бүрийн классууд, структуруудийг тусдаа сан хэлбэрээр бүрдүүлэн компиляц хийн dll файлд багцлаад дараа нь өөр төслүүдэд оруулан ашиглах нь элбэг байдаг. Үүний ачаар програмд олон дахин ашиглагдах ижил ажиллагаатай хэсгүүдийг сан хэлбэрээр тодорхойлоод төрөл бүрийн төслүүдэд оруулах эсхүл өөр боловсруулагч нарт ашиглуулах боломж бүрдэнэ.

  Нээгдсэн тоо: 156 Төлбөртэй

.NET фреймворк ердийн төрлүүдээс гадна ерөнхийлөгдсөн (generics) төрлүүд болон ерөнхийлөгдсөн аргуудын үүсгэлтийг дэмждэг. Энэхүү боломжийн онцлогийг судлахын өмнө ерөнхийлөгдсөн төрлүүд байхгүй бол үүсч болох асуудлуудыг авч үзье. Жишээ нь

class Person
{
    public int Id { get;}
    public string Name { get;}
    public Person(int id, string name)
    {
        Id = id;
        Name = name;
    }
}

гэж хэрэглэгчийн өгөгдлийг хадгалах классийг тодорхойллоо гэж үзье. Person класст Id - хэрэглэгчийн давтагдахгүй идентификатор, Name - хэрэглэгчийн нэр гэсэн хоёр шинжийг тодорхойлсон. Энд хэрэглэгчийн идентификаторийг тоон утгаар өгсөн тул шинж 1, 2, 3, 4 гэх мэтээр утгуудыг авна.

Лямбда-илэрхийлэл нь нэргүй аргын хураангуй бичилтийг илэрхийлнэ. Лямбда-илэрхийлэл утга буцаадаг, буцаасан утгыг өөр аргын…

Нээгдсэн тоо : 83

 

Кодийн сайжруулалт /рефакторинг/ хичээлээр програмийн кодоо react -ийн зарчимд нийцүүлэн компонентод салгасан.…

Нээгдсэн тоо : 114

 

Хадгалагч (Memento) хэв обьектын дотоод төлвийг түүний гадна гаргаж дараа нь хайрцаглалтын зарчмыг зөрчихгүйгээр обьектыг сэргээх боломжийг олгодог.

Нээгдсэн тоо : 118

 

Делегаттай нэргүй арга нягт холбоотой. Нэргүй аргуудыг делегатийн хувийг үүсгэхэд ашигладаг.
Нэргүй аргуудын тодорхойлолт delegate түлхүүр үгээр…

Нээгдсэн тоо : 135

 

Математикт харилцан урвуу тоонууд гэж бий. Ямар нэгэн тооны урвуу тоог олохдоо тухайн тоог сөрөг нэг зэрэг дэвшүүлээд…

Нээгдсэн тоо : 136

 

Төсөлд react-router-dom санг оруулан чиглүүлэгчдийг бүртгүүлэн тохируулсан Санг суулган тохируулах хичээлээр бид хуудас…

Нээгдсэн тоо : 194

 

Хуваах нь нэг тоо нөгөө тоонд хэдэн удаа агуулагдаж буй тодорхойлох арифметикийн үйлдэл.
Хуваалтыг нэг бус удаа…

Нээгдсэн тоо : 138

 

Зуучлагч (Mediator) нь олон тооны обьектууд бие биетэйгээ холбоос үүсгэхгүйгээр харилцан ажиллах боломжийг хангах загварчлалын хэв юм. Ингэснээр…

Нээгдсэн тоо : 134

 

Делегатууд хичээлд ухагдхууны талаар дэлгэрэнгүй үзсэн ч жишээнүүд делегатийн хүчийг бүрэн харуулж чадахааргүй байсан.…

Нээгдсэн тоо : 142

 
Энэ долоо хоногт

илэрхийллийг хялбарчил.

Нээгдсэн тоо : 1584

 

Нээгдсэн тоо : 634

 

prob09_163_01Зурагт өгсөн ABC гурвалжны AN=9, BM=12 байх медианууд перпендикуляр ба O цэгт огтлолцох бол ONCM дөрвөн өнцөгтийн талбайг ол.

Нээгдсэн тоо : 65