Хадгалагч (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 хэв дараах давуу талтай.

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

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

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

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

Програмчлалын бусад хэлүүдийн адилаар C# -д хувьсагчийг үүсгэхэд ашиглах өөрийн өгөгдлийн төрлүүд бий. Өгөгдлийн төрөл обьект авч болох, обьектод хэрэглэж болох үйлдлүүдийн өгөгдлийн дотоод илэрхийлэл, утгын олонлогийг тодорхойлдог тул өгөгдлийн төрлүүдийг маш сайн ойлгон зөв хэрэглэж сурах нь програмийн код бичихид маш чухал зүйл гэдгийг сануулъя.

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

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

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

Юуны өмнө ОХП-ын хэлүүд болон C# хэлэнд байдаг тодорхой суурь ухагдхууны талаар ойлголтыг авах хэрэгтэй. ОХП-ын хэлэнд бараг бүх обьектууд өгөгдлийн төрлүүд байдаг.

  • Хувьсагч гэдэг нь төрөл бүрийн утгуудыг авч болдог дараа нь тэдгээрийг өөр төрлийн утгаар өөрчилж болдог хэлний элемент юм. Иймээс түүнийг хувьсагч гэж нэрлэдэг. Тогтмол утга гэж бас байдаг. Тогтмол утга нь хувьсагчаас ялгаатай нь өөрийн утгаа компиляц хийх үед ганц удаа аваад тухайн утгаа дахин өөрчилдөггүй. Хувьсагч гэдгийг ямар нэгэн зүйлийг эсхүл тухайн зүйл хаана байгааг заах мэдээллийг хадгалж болдог хайрцагтай зүйрлэж болно.
  • Өгөгдлийн төрөл гэдгийг хувьсагч авч болох утгуудын олонлог гэж ойлгоно. Хэрвээ бид хувьсагчийг бүхэл тоон төрлийнх гэж заавал түүнд зөвхөн бүхэл тоог эсхүл логик төрлийнх гэвэл зөвхөн логик утгыг авна гэсэн үг. Өөрөөр хэлбэл хувьсагч өөрийн төрөлд багтах утгуудын олонлогоос л утгаа авах ёстой гэсэн үг.
  • Обьект гэдэг нь хувьсагч авсан тодорхой утга эсхүл тухайн утгыг авах холбоосын утгыг хувьсагчид олгосонг хэлнэ. Энэ ойлголт нь ОХП-ын үндсэн гол ойлголт байдаг.

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

Абстракт үйлдвэр (Abstract Factory) хэв өөр хоорондоо холбоотой тодорхой интерфейстэй обьектуудын бүлгийг тухайн обьектуудын төрлийг заахгүйгээр үүсгэх боломжийг олгодог.

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

  • Систем шинэ обьектын бүрдүүлэгч ба үүсгэх аргаас хамааралгүй байх хэрэгтэй үед
  • Үүсгэгдэж буй обьектууд өөр хоорондоо холбоотойн дээр хамтдаа ашиглагдах үед

Үйл явдал /event/ тодорхой үйлдэл хийгдсэн талаар системд мэдэгддэг. Хэрвээ бид энэхүү үйлдлийг ажиглах хэрэгтэй бол яг энд…

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

 

Манай төсөл олон хуудсуудтай болон тэдгээрийн хооронд динамикаар шилжилт хийж байгаа ч тухайн үед шилжилт хийгдсэн хуудаст тохирох…

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

 

Зочин (Visitor) паттерн классуудыг өөрчлөхгүйгээр тэдгээрийн обьектуудын үйлдлийг тодорхойлох боломжийг олгоно. Зочин хэвийг ашиглахдаа классуудын хоёр ангилалыг тодорхойлно.…

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

 

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

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

 

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

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

 

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

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

 

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

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

 

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

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

 

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

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

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

функцийн интервал дахь хамгийн бага утгыг ол.

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

 

Зөв дөрвөн өнцөгт пирамидын өндөр 4. Хажуу ирмэг суурийн хавтгайд 30 градусын өнцгөөр налсан бол пирамидын хажуу ирмэгийг ол.

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

 

бол M·N=?

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