Хадгалагч (Memento)

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

Хэвийг хаана ашиглах

  • Дараа нь сэргээх боломжтойгоор обьектын төлвийг хадгалах хэрэгтэй бол
  • Обьектын төлвийн хадгалалт хайрцаглалтын зарчмыг зөрчихгүйгээр хийгдэх хэрэгтэй бол

Энэхүү хэвийн түлхүүр ойлголт нь дотоод төлөв, хайрцаглалтын зарчим хоорондын балансыг сахин хадгалах юм. Хэрвээ бид хайрцаглалтыг зөрчихгүй бол обьектын төлвийг ердийн хувьсагчид хадгалах боломжтой шүү дээ. Харин эдгээр хувьсагчдад хандан утга олгох /setter/, утгыг авах /getter/ арга эсхүл шинжүүд үргэлж байгаад байдаггүй. Жишээ нь тоглоомд баатрыг удирддаг. Баатрын зэвсэг, амины хэмжээ, хүч гэх мэтээр бусад үзүүлэлтүүд тухайн баатрын обьект дотор агуулагддаг. Сүүлд өмнөх түвшиндээ буцан тоглоомыг шинээр эхлүүлэхийн тулд эдгээр бүх үзүүлэлтийг гадна хадгалах тохиолдол олонтаа гардаг. Энэ тохиолдолд хадгалагч хэв тусалж болно.
Хэвийн бүтцийн диаграмыг дараах байдлаар дүрсэлж болно.

patt_22_01

Хэвийн бүтцийг C# -аар харуулбал

class Memento
{
    public string State { get; private set;}
    public Memento(string state)
    {
        this.State = state;
    }
}
 
class Caretaker
{
    public Memento Memento { get; set; }
}
 
class Originator
{
    public string State { get; set; }
    public void SetMemento(Memento memento)
    {
        State = memento.State;
    }
    public Memento CreateMemento()
    {
        return new Memento(State);
    }
}

Оролцогчид

  • Memento - Originator обьектын төлвийн хадгалагч ба зөвхөн энэхүү Originator обьетод бүрэн хандалтыг олгоно.
  • Originator - өөрийн төлвийг хадгалах хадгалагч обьектыг үүсгэнэ.
  • Caretaker - зөвхөн Memento обьектыг хадгалах үүргийг гүйцэтгэх бөгөөд түүнд хадгалагчид хандах бүрэн эрх байхгүй. Өөрөөр хэлбэл класс хадгалах үйлдлээс өөр юуг ч хийж чадахгүй.

Одоо бодит жишээ авч үзье. Бидэнд тоглоомын баатрын төлвийг хадгалах хэрэг гарлаа гэе.

    class Program
    {
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;
            Hero hero = new Hero();
            hero.Shoot(); // Буудлага хийлээ, 9 сум үлдсэн
            GameHistory game = new GameHistory();

            game.History.Push(hero.SaveState()); // тоглоомыг хадгалах

            hero.Shoot(); // Буудлага хийлээ, 8 сум үлдсэн

            hero.RestoreState(game.History.Pop());

            hero.Shoot(); // Буудлага хийлээ, 8 сум үлдсэн

            Console.Read();
        }
    }

    // Originator
    class Hero
    {
        private int patrons = 10; // сумны тоо
        private int lives = 5; // амины тоо

        public void Shoot()
        {
            if (patrons > 0)
            {
                patrons--;
                Console.WriteLine("Буудлаа. {0} сум үлдсэн", patrons);
            }
            else
                Console.WriteLine("Сум дууссан");
        }
        // төлвийн хадгалалт
        public HeroMemento SaveState()
        {
            Console.WriteLine("Тоглоомыг хадгалах. Параметрүүд: {0} сум, {1} амь", patrons, lives);
            return new HeroMemento(patrons, lives);
        }

        // төлвийн сэргээлт
        public void RestoreState(HeroMemento memento)
        {
            this.patrons = memento.Patrons;
            this.lives = memento.Lives;
            Console.WriteLine("Тоглоомыг сэргээх. Параметрүүд: {0} сум, {1} амь", patrons, lives);
        }
    }
    // Memento
    class HeroMemento
    {
        public int Patrons { get; private set; }
        public int Lives { get; private set; }

        public HeroMemento(int patrons, int lives)
        {
            this.Patrons = patrons;
            this.Lives = lives;
        }
    }

    // Caretaker
    class GameHistory
    {
        public Stack<HeroMemento> History { get; private set; }
        public GameHistory()
        {
            History = new Stack<HeroMemento>();
        }
    }

Програмыг ажлуулбал

patt_22_02

үр дүн гарна. Энд Originator -ийн үүргийг төлөв нь сум, амины тоогоор тодорхойлогдох Hero класс гүйцэтгэнэ. HeroMemento класс тоглоомын баатрын төлвийг хадгалахад зориулагдсан. Hero обьект өөрийн төлвийг SaveState() аргаар HeroMemento -д хадгалаад RestoreState() аргаар сэргээнэ. GameHistory класс төлвийг хадгалахад зориулагдсан бөгөөд бүх төлвүүдийг стекд хадгалах тул сүүлийн төлвийг амархан гарган ирэх боломжтой.
Memento хэв дараах давуу талтай.

  • Системийн холбоог багасгана
  • Мэдээллийг хайрцаглан хадгална
  • Төлвийг хадгалах, сэргээхэд энгийн интерфейсийг тодорхойлно

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

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

  Нээгдсэн тоо: 33 Бүртгүүлэх

Ажиглагч (Observer) бол нэг -> олон (1->∞) харьцааг илэрхийлэх төлөв байдлын хэв. Энэ утгаараа ажиглагдах нэг харин ажиглагч олон обьектууд байдаг. Ажиглагдаж буй обьектын өөрчлөлтүүд ажиглагчдад автоматаар тараагдана. Нийтлэгч, бүртгүүлэгчийн харилцаа нь энэхүү хэвийн үйлдлийг тодорхойлдог болохоор бас Publisher-Subscriber (нийтлэгч - бүртгүүлэгч) гэж ч нэрлэдэг. Жишээ нь бүртгүүлэгч буюу хэрэглэгчид сайтаас цахим шуудангаар мэдээлэл авахаар бүртгүүлэгч болно.

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

Боловсруулагчид C# дээр програм зохиохдоо голдуу Visual Studio эсхүл ямар нэгэн JetBrains компаний Rider мэтийн IDE (integrated development environment) боловсруулалтын хэрэгслийг ашигладаг. Гэхдээ бүхий л IDE -нууд боловсруулалтын ажиллагааг хөнгөвчилж өгдөг ч програм үүсгэх ажиллагааны олон жижиг зүйлүүдийг цаанаа хийдэг. Үнэн хэрэгтэй бид зөвхөн .NET CLI -ийн боломжийг ашиглан боловсруулалтын орчингүйгээр ажиллах боломжтой.

  Нээгдсэн тоо: 242 Нийтийн

Програм зохиох бол нарийн төвөгтэй ажил. Ямар ч програмын хувьд өөрийн хийх ажлаа гүйцэтгэхийн чацуу цаашдаа хөгжих, ажлын хүрээнд шинээр гарч ирэх илүү нарийн асуудлыг шийдвэрлэх боломжтой илүү уян хатан байдлаар зохиогдсон байх хэрэгтэй. Хэрвээ та програмын төслийн ахлагч, зохион бүтээгчээр ажиллаж байсан бол програмын ажиллагааг цаашдаа дэмжих, үйлчилгээ үзүүлэх, өргөжүүлэн хөгжүүлэхэд цаг хугацаа хожихын тулд кодыг нэг удаа хэрхэн яаж бичихийг тодорхойлох хамгийн төвөгтэй асуудал гэдгийг мэдэрсэн байх.

  Нээгдсэн тоо: 249 Бүртгүүлэх

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

Санамж. Програмчлалын хэлийг сурахад дадлага чухал үүрэгтэй. Жижиг гэлтгүй асуудлуудыг өөрөө шийдэхээс л дадлагажин код бичиж сурдаг. Эхлэн суралцагсад асуудлыг бэлэн сангууд ашиглан шийдэх гэдэг нь цаашид асуудал үүсгэх үндэс болдог. Хичээлийн жишээнүүдийг бэлэн сан ашиглан маш хурдан шийдэж болох ч чухам ямар ажиллагаануудыг хийсэнг мэдэлгүй өнгөрнө. Өөрөөр хэлбэл кодийн алгоритмийг ойлголгүй ажиллагааг шийднэ гэсэн үг. Ийм аргаар бүх асуудлыг шийдэх боломжгүй гэдэг нь тодорхой. Ер код бичих суурь бол асуудлыг шийдэх алгоритмыг зохиож сурах. Үүнд суралцахгүйгээр код бичиж сурахгүй гэдгийг сануулъя.

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

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

 

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

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

 

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

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

 

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

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

 

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

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

 

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

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

 

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

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

 

react програмд олон хуудас үүсгэн удирдахын тулд react -ийн бүрэлдхүүнд ордоггүй ч түүнтэй нягт холбоотой ажилладаг нэмэлт пакетийг…

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

 

Үржвэр дэх үржигдэгч болон үржигчийн өөрчлөлт үржвэрт хэрхэн нөлөөлөхийг авч үзье.

Үржигдхүүнийг ихэсгэх

Үржигдэгч…

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

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

илэрхийллийн a=36,7 тэнцүү байх утгыг ол.

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

 

ABCDA1B1C1D1 тэгш өнцөгт паралеллепипедийн AB=3, AD=7, AA1=8 бол A,B,C,D,C1 оройнуудтай олон талстын эзэлхүүнийг ол.

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

 

Ногдвор нь 2 -той тэнцүү геометрийн прогрессийн 8-р гишүүн 256 бол 1-р гишүүн болон эхний 8 гишүүний нийлбэрийн үржвэрийг ол.

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