Python ile Singleton Patern’i

Pratikte herhangi bir sınıf türünde birçok kez nesne örneği (object instance) yaratmak istenebilir. Bu işlem normal yollarla yapıldığında yaratılan her bir nesne örneği için bellekte farklı bir yer tahsis edilecek ve nesnenin veri elemanlarında taşıyacağı değerler yani durum bilgisi bu alanlara yerleştirilecektir. Ancak bazı durumlarda ve bazı nesneler için kaç kez nesne örneği yaratılmak istenilirse istenilsin ilk seferinde yapılan yaratma işleminden sonra -yaratma işlemi tekrar edilse bile- yeni bir nesne daha yaratılmaksızın hep bu ilk nesne örneğinin kullanılmasına ihtiyaç duyulabilir. Başka bir deyişle söz konusu sınıf nesnesinin sadece bir kereliğine yaratılıp, daha sonra sürekli olarak kendisinin kullanılması isteniyor olabilir. İşte bu ihtiyacı karşılayan tasarım çözümünün ismi; Singleton patern’idir.

Singleton Patern’inin Uygulanmasıyla İlgili Esaslar

  1. Bu paternin uygulandığı sınıflarda, kendi türünde private ve static bir nesne olmalıdır. Statik olmasının sebebi; taşıyacağı adresin nesneden bağımsız ve sabit şekilde kullanılması ihtiyacıdır. (Örnekteki ismi; m_smp’dir)
  2. Söz konusu sınıfın türündeki nesnenin yaratılışı sadece bir kez yapılmak istendiği için sınıfın init fonksiyonu (initializer’ı) private tanımlanarak kullanıcı taraftan gizlenmelidir. Böylece sınıfı kullanacak olan programcı init() fonksiyonunu doğrudan çağıramaz hale gelir.
  3. init() fonksiyonunun bir anlamda yerini alacak olan, bir class üye fonksiyon (singleton nesne yaratıcı fonksiyon) olmalıdır. Bu fonksiyon 1. maddede anlatılmış olan statik nesnenin taşıyacağı adresi geriye döndürecek şekilde yazılmalıdır. Ancak kuşkusuz bu değer geriye döndürülmeden önce nesne için tahsisat yapılmış olmalıdır ki tahsisatın başlangıç adresi bu nesneye atansın ve geriye döndürülebilsin. Bu işlemler söz konusu fonksiyon içerisinde gerçekleştirilir. (Örnekteki ismi; CreateObject()’tir.)

class Sample:

    m_Smp = None

    class __Sample:

        def __init__(self):

            self.val = None

            print(“Sample nesnesi yaratıldı”)

    #CreateObject

    def __new__(cls):

        if not Sample.m_Smp:

            Sample.m_Smp = Sample.__Sample()

        return Sample.m_Smp

    #GetData

    def __getattr__(self, name):

        return getattr(self.m_Smp, name)

    #SetData

    def __setattr__(self, name):

        return setattr(self.m_Smp, name)

obj1 = Sample()

obj2 = Sample()

obj3 = Sample()

obj1.val = 7877

print(“obj1-Data: ” + str(obj1.val))

print(“obj2-Data: ” + str(obj2.val))

print(“obj3-Data: ” + str(obj3.val))

print(“———–“)

obj2.val = 1999

print(“obj1-Data: ” + str(obj1.val))

print(“obj2-Data: ” + str(obj2.val))

print(“obj3-Data: ” + str(obj3.val))

Bu durum şöyle yorumlanabilir; 7877 değeri obj1 ile set edildikten sonra, diğer nesneler de aynı veriyi referanse ettiklerinden dolayı, veri alındığında hep aynı değerlere ulaşılmaktadır. Keza obj2 ile 1999 değeri set edilip, veri tekrar alındığında bu kez üç sefer de 1999 değerine ulaşılmaktadır.

Reklamlar

Swift Delegation Pattern

Aşağıdaki yazı yakında çıkacak olan kitabımdan bir alıntıdır izinsiz kopyalanıp, kullanılamaz.

Bu patern bir nesnenin yerine getirmesi gereken bir görevi kendisi yapmak yerine başka bir nesneye -delege ederek- görevi delege ettiği nesneye yaptırmasını tematize eder. Başka bir deyişle, nesne söz konusu görevi farklı bir nesnenin yardımıyla gerçekleştirir.

Bu patern’in implementasyonunda anahtar nokta delege eden ve edilenin aynı protokolü (interface’i) desteklemesidir. Ayrıca delege eden bu protokol türünde bir nesne referansı (property) içermelidir. Bu sayede o property’e atanacak olan nesneye görev delege edilmiş olur.

swift delegation patern uml diagram

swift delegation patern uml diagram

Şekil 6.1’deki UML diyagramında görülen C sınıfı, Task() isimli fonksiyonla sembolize edilen görevi A veya B’den yardım alarak (A veya B türündeki bir nesneye delege ederek) gerçekleştirecektir. Bu karar, ToDelegation() isimli fonksiyona gönderilen parametrenin polimorfik şekildeki kullanımına dayandırılmıştır. Yani ToDelegation() isimli fonksiyona A veya B türünde bir nesne parametre olarak geçilmekte ve görev o nesneye delege edilmektedir.

protocol Delegation

{

func Task()

}

class A : Delegation

{

func Task()

{

print(“Görevi A nesnesi gerçekleştirdi”)

}

}

class B : Delegation

{

func Task()

{

print(“Görevi B nesnesi gerçekleştirdi”)

}

}

class C : Delegation

{

var delegate:Delegation?

func ToDelegation(delegate:Delegation)

{

self.delegate = delegate

}

func Task()

{

self.delegate!.Task()

}

}

////// TEST ///////

var c = C()

// A’ya delege et

c.ToDelegation(A())

c.Task()

// B’ye delege et

c.ToDelegation(B())

c.Task()

Çıktı:

Görevi A nesnesi gerçekleştirdi

Görevi B nesnesi gerçekleştirdi

Chain of Responsibility Dizayn Patern’i (C++, Java ve C# ile)

Chain of Responsibility

İsmi Türkçeye “sorumluluk zinciri” diye çevirilmiş olan bu patern, istemcinin bir işi (görev ya da sorumluluğu) hakkında bilgi sahibi olmadığı bir dizi nesneye talep göndererek yaptırmasını tematize eder. Görevi yerine getirecek olan nesneler ile istemci nesne arasında doğrudan bir ilişki olmamalıdır. Yani birbirlerine gevşek bağlı olmalıdırlar. Paternin ismindeki zincir benzetmesi ise sorumluluğu üstlenecek olan nesnelerin (handler nesneler) belirli bir sırayla ve duruma göre görevi bir sonraki nesneye iletmesinden gelir. İstemcinin bilgisi dışında yani ondan bağımsız şekilde zincire yeni nesneler eklenebilir ya da çıkartılabilir.

NOT : Bu yazı Aykut TAŞDELEN’in C++ Java ve C# ile UML ve Dizayn Paternleri kitabından alıntıdır izinsiz kullanılıp alıntı yapılamaz ! Konunun devamı söz konusu kitapta yer almaktadır.

Okumaya devam et

WPF MVC Patern’i Nedir

WPF ‘te MVC (Model View Controller) Patern’i Nasıl Kullanılır ?

Not : Bu yazı Aykut TAŞDELEN’in WPF kitabından alıntıdır izinsiz kullanımı suçtur ! Konuyla ilgili diğer kısımlar kitapta yer almaktadır.

MVC (Model-View-Controller) patern’inin kısaca ne olduğunu anlatmak, hatta kabaca bir tanım getirmek gerekirse;

  • Model nitelemesi; uygulamanın üzerinde çalıştığı verileri,
  • View; model’in sunumunu,
  • Controller ise; klavye, mouse, stylus gibi sistem girdilerinin ve bunlara ilişkin event’lerin yönetimini ifade etmektedir.

Gevşek bağlı modüllerden oluşan böylesi bir sistemin esası; parçalar arasındaki doğrudan referans’ları azaltmaktır. Yapılması gereken şey; parçalar arasında interface’ler veya soyut sınıflar kullanılarak (dependency injection ve object mocking diye bilinen kavramlar) gevşek bağlar oluşturulmasıdır.

MVC’nin WPF’teki İmplementasyonu

WPF’te MVC patern’i implemente edilirken şu dört  temel WPF özelliğinden faydalanılır. Bu özelliklerin tümü, MVC’ye ilişkin Model-View-Controller kısımlarının birbirlerine loosely coupled yani gevşek bağlı olmasını sağlar.

  1. Rotalanmış Komutlar (Routed Commands)
  2. Veri Bağlama (Data Binding)
  3. Collection View
  4. Kaynak (Resource) kullanımı

Örnek : Aşağıdaki uygulamada MVC patern’inin nasıl kullanılabileceği gösterilmektedir. Senaryo kısaca şöyledir :

Model kısmında yer alan CStok sınıfı ve bu sınıf türündeki nesneleri bir kolleksiyon olarak barındıran StokCollection uygulamanın üzerinde çalıştığı verileri ifade eder. Amaç bu kolleksiyonun elemanlarının bir ListBox’ta gösterilmesidir. Ancak listeleme gibi görevleri (aksiyonları) işleyen bir de Controller isimli sınıf söz konusudur.

MVC’ye ilişkin temek unsurlar ve bu unsurları temsil eden sınıflar ekran çıktısında da görüldüğü gibi ayrı ayrı klasörlere alınmıştır. Şüphesiz gerçek hayatta bu sınıfların ayrı ayrı dll’lerin içinde yer almaları tercih edilmelidir.

 

Şekil 11.3 :Uygulamanın temel yapıları

Model Kısmı

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Collections.ObjectModel;

namespace WPF_MVC.Model

{

    public class CStok : INotifyPropertyChanged

    {

        private int m_StokID;

        public int StokID

        {

            get { return m_StokID; }

            set { m_StokID = value; }

        }

        private int m_Adet;

        public int Adet

        {

            get { return m_Adet; }

            set

            {

                m_Adet = value;

                OnChanged(“Adet”);

            }

        }

        private string m_Urun;

        public string Urun

        {

            get { return m_Urun; }

            set

            {

                m_Urun = value;

                OnChanged(“Urun”);

            }

        }

public CStok(int StokID, string urun, int adet)

        {

            m_StokID = StokID; 

            m_Adet = adet;

            m_Urun = urun;

        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnChanged(string prop_name)

        {

            if (this.PropertyChanged != null)

            {

                PropertyChanged(this,
                   new PropertyChangedEventArgs(prop_name));

            }

        }

    }

    //////////////////////////////////////////////////////////
 

    public class StokCollection : ObservableCollection<CStok>

    {

        public static StokCollection Yukle()

        {

            StokCollection stoklar = new StokCollection();

            stoklar.Add(new CStok(1, “CD-ROM”, 200));

            stoklar.Add(new CStok(2, “Mouse”, 10));

            stoklar.Add(new CStok(3, “Pinter”, 23));

            return stoklar;

        }

    }

}

View Kısmı

StokEkrani.xaml
<Window x:Class=”WPF_MVC.StokEkrani”

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

    Title=”StokEkrani” Height=”300″ Width=”300″>

    <Grid>

        <ListBox Margin=”12,11,12,45″ Name=”lstStoklar” />

        <Button Height=”26″ Margin=”14,0,10,10″ Name=”btnListele”
                VerticalAlignment=”Bottom”
                Click=”btnListele_Click”>Listele</Button>

    </Grid>
</Window>

——————————————————

StokEkrani.xaml.cs

using WPF_MVC.Controller;

using WPF_MVC.Model;

namespace WPF_MVC

{

    public partial class StokEkrani : Window

    {

        private StokController controller;

        public StokEkrani()

        {

            InitializeComponent();

            controller = new StokController(this, StokCollection.Yukle ()); 

        }

        private void btnListele_Click(object sender, RoutedEventArgs e)

        {

            controller.Listele(); 

        }

    }

}

Controller Kısmı

Controller.cs

using System;

using System.Collections.Generic;

using System.Windows;

using System.Text;

using WPF_MVC.Model;

using System.Windows.Controls;

using System.Windows.Data;

namespace WPF_MVC.Controller

{

    public interface IController

    {

        void Listele();

        // …

    }

    public class StokController : IController

    {

        private StokCollection m_stoklar;  // Model

        private StokEkrani m_Wnd;          // View  

        public StokController(StokEkrani wnd, StokCollection stoklar)

        {

            m_Wnd = wnd;

            m_stoklar = stoklar;

        }

        #region IController Members

        public void Listele()

        {

            ListBox lst = (ListBox) m_Wnd.FindName(“lstStoklar”);

            lst.DisplayMemberPath = “Urun”;

            lst.ItemsSource = m_stoklar;

            lst.IsSynchronizedWithCurrentItem = true; 

        }

        #endregion

    }

}

Şüphesiz gerçek hayatta beklentiler uygulama yapısının daha karmaşık olmasını gerektirir. Ancak burada amaç; kılavuz olabilecek anlaşılırlığa sahip, basit bir örnek vermektir.