deleqatlar-praktikada-observer-patterninin-deleqatlarla-realizasiyasi

Deleqatlar praktikada. Observer patterninin deleqatlarla realizasiyası

Proqram strukturu quran zaman bəzən bir neçə klasın, bir-birini birbaşa tanımadan bir-biriylə məlumat mübadilə etməsi prosesinə ehtiyac duyulur. Bununla da, həmin klasları bir-birindən asılı olmadan müşayiət etmək, onları rahat genişləndirmək mümkün olur.


PS: butun kodları buradan yükləyə bilərsiniz.


               Observer Design patterni(Proyektləşdirmə şablonu) real həyatda rastlaşdığımız notification,subscription(Abunə sistemi) prosesini həyata keçirtmək üçündür. Siz hər hansı bir şəxsə,kanala sosial şəbəkələrdə,müxtəlif sayt və portallarda abunə ola bilirsinizsə, bu o deməkdir ki, həmin sistem Observer proyektləşdirmə şablonunu(design pattern) istifadə edir.

               .NET/C# öyrənərkən rastlaşdığımız ən maraqlı mövzulardan olan, çoxlarının tam anlamadığı deleqatları bu məqaləmizdə klaslar arasında 1-in 1-ə münasibəti quran zaman istifadə edəcəyik .Belə ki, proqramımız ona subcribe(abunə olan) obyektə özündə baş verən dəyişikliklər haqda məlumat verəcək.

               Yazacağımız proqram , əməliyyat sistemində hər hansı bir qovluğu monitor edəcək və əgər həmin qovluqda hər hansı bir fayl silinərsə ozaman bu haqda abunə olana(subcriber) məlumat verəcək.

               Proqramda ilk öncə Abunəçi(Subscriber) klasını hazırlayaq. Bu klasın görəcəyi iş sadəcə NotifyMe metodu vasitəsilə silinmiş fayl və faylın silindiyi qovluğun adını almaq və ekranda göstərməkdir.

               public class Subscriber
              {
                  private string _name;
          
          
                  public Subscriber(string name)
                  {
                      this._name = name;
                  }
          
          
                  public void NotifyMe(string filename,string folder)
                  {
                      Console.WriteLine($"{_name}, `{filename}` removed from {folder}");
                  }
              }

                DirectoryMonitor klasımız StartMonitoring() metodu vasitəsilə seçilmiş qovluğu monitor etməyə başlayır. Əgər qovluqda hansısa bir və ya birneçə fayl silinərsə bu haqda məlumatı bizə GetDeletedFiles() adlanan metodumuz verir.

         public class DirectoryMonitor
    {
        private readonly List<string> _filesInFolder;


        public string MonitoredDirectory { get; private set; }
        public DirectoryMonitor(string foldernameToMonitor)
        {
            MonitoredDirectory = foldernameToMonitor;
            _filesInFolder = new List<string>();
        }


        /// 
        /// Check if we can monitor given folder from ctor..
        /// 
        /// 
        public bool StartMonitoring()
        {
            if (!Directory.Exists(MonitoredDirectory))
            {
                return false;
            }
            var directoryInfo = new DirectoryInfo(MonitoredDirectory);
            foreach (var fileInfo in directoryInfo.GetFiles())
            {
                _filesInFolder.Add(fileInfo.FullName);
            }
            return true;
        }


        public List<string> GetDeletedFiles()
        {
            var result = new List<string>();
            foreach (var file in _filesInFolder.ToArray())
            {
                if (!File.Exists(file))
                {
                    _filesInFolder.Remove(file);
                    result.Add(file);
                }
            }


            return result;
        }
    }

               İndi isə işin ən maraqlı tərəfinə gələk. Gördüyümüz kimi, nə Subscriber klasının nə də DirectoryMonitor klasının bir-birindən xəbəri yoxdur. Amma onlar arasında məlumat mübadilə etmək mümkün olacaq. Bununçün FolderMonitorDelegate klasımız var. Bu klas öz içərəsində DirectoryMonitor klasını saxlayır və konstruktordan çox maraqlı bir parametr alır. Bu parametr Action deleqatıdır.

  private readonly DirectoryMonitor _directoryMonitor;
        private readonly Action<string,string> _subscriber;
        public FolderMonitorDelegate(string folderToMonitor,Action<string,string> subscriber)
        {
            _directoryMonitor = new DirectoryMonitor(folderToMonitor);
            _subscriber = subscriber;
          ................................
         }

Həmin deleqatın şablonu Subscriber klasının NitofyMe() metodunun şablonuna düz gəlir. Məhz bu deleqat vasitəsilə DirectoryMonitor klası Subscriber ilə əlaqə saxlayacaq.

               FolderMonitorDelegate klası öz içərisində Timer klasını istifadə edərək müəyyən vaxt kəsiyindən bir qovluqdakı faylların siyahısının alınması metodunu çağırır.

  public class FolderMonitorDelegate : IDisposable
    {
        private readonly Timer _timer;
        private readonly DirectoryMonitor _directoryMonitor;
        private readonly Action<string,string> _subscriber;
        public FolderMonitorDelegate(string folderToMonitor,Action<string,string> subscriber)
        {
            _directoryMonitor = new DirectoryMonitor(folderToMonitor);
            _subscriber = subscriber;
            if (_directoryMonitor.StartMonitoring())
            {
                _timer = new Timer(1000);
                _timer.Elapsed += CheckIfRemoved;
                _timer.Start();
            }
            else
            {
                Console.WriteLine("Directory doesn't exists");
                this.Dispose();
            }
        }


        private void CheckIfRemoved(object sender, ElapsedEventArgs e)
        {
            //get lists of removed files
            foreach (var fileName in _directoryMonitor.GetDeletedFiles())
            {
                //notify user about changing in folder..
                _subscriber(fileName,_directoryMonitor.MonitoredDirectory);
            }
        }


        public void Dispose()
        {
            _timer.Dispose();
        }
    }

İndi artıq proqramımızı istifadə edən zaman sadəcə belə bir şey yazmağımız kifayət edəcək.

 static void Main(string[] args)
        {
            //create subscriber
            Subscriber subscriber = new Subscriber("Simon");


            FolderMonitorDelegate folderMonitorDelegate
                                    = new FolderMonitorDelegate("C:/mycode", subscriber.NotifyMe);


            Console.ReadLine();
            folderMonitorDelegate.Dispose();
        }

Proqramı işə saldıqdan sonra göstərilən qovluqda hər hansı bir fayl silindikdə avtomatik olaraq bizim proqramda Subsciber məlumatlandırılır və ekranda bu haqda yazı görünür.


PS: butun kodları buradan yükləyə bilərsiniz.

 


Tural

Tural Süleymani

Süleymani Tural Microsoft-un MCSD statuslu mütəxəssisidir, 2008-ci ildən bu yana proqramlaşdırma üzrə tədris aparır

Müəllifin bu dildə ən son postları

Bu yazıları da bəyənə bilərsiniz