JavaScript'te OOP Yaklaşımı, nesne yönelimli programlama ilkelerini kullanarak kodlamayı kolaylaştırır Bu yaklaşım, kodunuzun daha okunaklı, bakımı kolay ve yeniden kullanılabilir hale gelmesini sağlar Bu yazı, JavaScript geliştiricilerine OOP yaklaşımı hakkında bilgi verir ve nasıl kullanılabileceği konusunda tavsiyeler sunar Okumaya başlayın ve JavaScript'te OOP ile kod yazmanın faydalarını öğrenin!

JavaScript programlama dilinde, nesne yönelimli programlama (OOP) yaklaşımı kullanımı hızla yaygınlaşmaktadır. Bu yaklaşım, programlama yapısında nesnelere ve sınıflara yer vererek, kodlama süreçlerini daha anlaşılır ve yönetilebilir hale getirmektedir. Nesne yönelimli programlama, büyük ölçekli projelerde daha sürdürülebilir bir yaklaşım sunmaktadır.
JavaScript'teki nesne yönelimli programlama yapısında, özellikle nesne ve sınıf yapısı ile daha verimli ve kolayca uygulanabilen bir yaklaşım ortaya çıkmaktadır. Bu yaklaşımda, nesneler birbirleriyle ilişkili bir şekilde gruplanır ve ayrı ayrı ele alınır. Nesne yönelimli programlama yapısında, miras ve çok biçimlilik kavramları da sıklıkla kullanılmaktadır. Ayrıca kapsülleme, korumalı özellikler, kesişimler ve sınıf fabrikası gibi özellikler de mevcuttur. Bu özellikler sayesinde, nesne yönelimli programlama yaklaşımı daha anlaşılır ve yönetilebilir hale gelmektedir.
Nesneler ve Sınıflar
JavaScript programlama dilinde nesne yönelimli programlama yapılarının en temelinde nesneler ve sınıflar yer almaktadır. Nesne, program içindeki bir varlık veya bir nesne olarak tanımlanmaktadır. Bu nesne, birçok farklı özelliğe ve metoda sahip olabilir. Sınıflar ise, benzer özelliklere ve metodlara sahip nesnelerin gruplanmasıdır. Sınıf yapısı kullanılarak, benzer özellikler gösteren nesneler bir sınıfa dahil edilerek, tekrarlanan kod parçalarının önüne geçilebilir.
Nesne yönelimli programlama ile birlikte, JavaScript programlama dilinde de nesne yapısı oldukça kullanışlı hale gelmiştir. Nesne yapısı sayesinde hem programın anlaşılırlığı artmakta, hem de kod tekrarları önlenmektedir. Özellikle büyük ölçekli projelerde, nesne yapısı kullanılması kolay bir anlaşılabilirlik sağlamaktadır.
- JavaScript programlama dilinde oluşturulan bir nesnenin özellikleri, direkt olarak nesne içerisinde tanımlanabilmektedir.
- Nesnenin özellikleri belirlendikten sonra, özelliklere doğrudan erişim sağlanabilir.
- JavaScript'te sınıf yapısı direkt olarak bulunmamaktadır.
- Nesne yapısı üzerinden, sınıfa benzer bir yapı oluşabilir ve bu sayede benzer özelliklere sahip nesneler gruplandırılabilir.
Miras ve Çok Biçimlilik
JavaScript programlama dili, nesne yönelimli programlama yaklaşımını destekler ve bu yaklaşımı kullanarak, varlıkları nesne olarak tanımlamamızı ve bu nesneleri manipüle ederek programlarımızı tasarlamamızı sağlar. Bu yaklaşımın temel yapı taşlarından biri de "miras" kavramıdır. Miras, bir nesnenin sahip olduğu özelliklerin diğer bir nesneye aktarılması işlemidir. Böylece, yeni bir nesne oluştururken önceden tanımlanmış olan bir nesnenin özelliklerini kullanarak kısa yoldan bir nesne oluşturmak mümkündür.
Polymorphism kavramı, farklı sınıfların aynı metodları kullanabilmesi anlamına gelir. Bu yapı sayesinde, programcılar farklı sınıfların birbirine benzer fakat farklı özelliklere sahip nesneleri yönetebilirler. Örneğin, bir "araba" sınıfı ve "kamyon" sınıfı aynı şekilde "sür" metodunu kullanabilir. Böylece, bu metod, farklı sınıfların nesnelerinde farklı davranabilir.
Örneğin, "hayvan" sınıfı ve "insan" sınıfı adında iki sınıfımız olsun. "insan" sınıfı, "hayvan" sınıfından türetilmiş olsun. "hayvan" sınıfının özellikleri olan örneğin "sürünme" özelliği "insan" sınıfına aktarıldığında, "insan" sınıfı artık hem insanların hem de hayvanların sahip olduğu özeliklere sahip bir nesneye dönüşür. Bu yapı, programcıların daha kolay ve hızlı çalışmasını sağlar.
Abstract Sınıflar
JavaScript'te abstract sınıflar, soyut bir sınıfın temel özelliklerini tanımlayan ancak kendisi doğrudan örneklendirilemeyen bir sınıf türüdür. Bu sınıflar, sistemde tutarlı bir genel yapı oluşturmak için kullanılır. JavaScript ile birlikte birden çok bir alanda öğrenim gören birinci sınıf nesne yapısına sahip olduğumuz için, abstract sınıfların kullanımı özellikle önemlidir.
Abstract sınıflar, bir sınıfın genel özelliklerinin tanımlanmasına yardımcı olur ve daha sonra bu özellikleri barındıran bir nesne oluşturmak için diğer sınıfların tarafından miras alınabilir. Bunun yanında, bir abstract sınıf kendisini doğrudan örneklendiremeyeceği için, soyut bir sınıfın özellikleri, alt sınıflar tarafından zorunlu hale getirilebilir.
Örneğin, elma, muz ve portakal, meyve adı altında birbirine benzer özelliklere sahip nesnelerdir. Ancak, her bir meyve türünün ayrı ayrı özellikleri ve yöntemleri vardır. Meyveler adı altında bir abstract sınıf oluşturulabilir. Bu abstract sınıf, meyve türlerinin doğal ortak özelliklerini içerecektir. Alt sınıflar olan elma, muz ve portakal sınıfları, soyut sınıfın özelliklerinin tamamını devralacak ve özellikleri, kendilerine özgü yöntemlerle tamamlayacaklardır.
Bu örnekte olduğu gibi, abstract sınıfların kullanımı, kod tekrarını azaltabilir ve kodun yeniden kullanılabilirliğini artırabilir. Ayrıca, soyut sınıftaki standart özelliklerin, alt sınıflar tarafından düzenlenmesi, sınıf yapısının daha da geliştirilmesine yardımcı olur.
JavaScript'te abstract sınıfların kullanımı, obje-oriented programlama yapısının temel prensiplerinden biridir. Bu prensibi anlamak ve kullanmak, kod yazımında ve güncellemede daha tutarlı bir yapı oluşturulmasına yardımcı olacaktır.
Interface'ler
Interface, nesne yönelimli programlama yapısında kullanılan önemli bir yapıdır. JavaScript'te interface yapısı, tam olarak bir interface şeklinde kullanılmaz ancak arayüz adı verilen bir yapı ile benzeri bir kullanım sağlanabilir. Arayüz, bir nesnenin özelliklerini ya da method'larını tanımlayan bir yapıdır.
Arayüzler, kodun anlaşılırlığını ve bakımını kolaylaştırır. Bu yapı, bir sınıfın belirli bir arayüzü uygulayabildiğini garanti eder. Bu da, uygulama geliştirirken daha tutarlı bir yaklaşımı sağlar. Arayüzler aynı zamanda kodun yeniden kullanılabilirliğini de arttırır. Bir arayüzü uygulayan farklı sınıflar oluşturabilir ve bu sayede aynı kod bloklarını tekrar tekrar kullanmak yerine bu sınıfları kullanabilirsiniz.
Arayüzler aynı zamanda bakımı da kolaylaştırır. Eğer bir sınıfın belirli bir arayüzdeki uyumluluğu değişirse, tüm sınıfları tekrar kontrol etmek yerine sadece ilgili arayüzü güncelleyebilirsiniz. Bu, kodun daha güvenilir olmasını ve hatasız çalışmasını sağlar. Ancak, JavaScript'te interface yapısının tam olarak desteklenmediğini unutmamak gerekiyor. Bunun yerine yukarıda bahsedildiği gibi arayüz adı verilen bir yapı benzer şekilde kullanılabilir.
Arayüz yapısının avantajları şöyle özetlenebilir:
- Anlaşılabilir kod yazımı
- Daha tutarlı ve yeniden kullanılabilir kod
- Kodun daha kolay bakımı ve güncellemesi
Mixin'ler
Mixins, JavaScript'te nesne-oriented programlama yaklaşımında oldukça kullanışlı yapılar olarak karşımıza çıkar. Mixin'ler, sınıfların birden fazla özelliklerini bir arada kullanmak için kullanılmaktadır. Kısacası, birden fazla sınıfın özelliğini bir sınıf içinde birleştirebiliriz. Bu sayede daha az kod yazarak, daha çok işlem yapabilme imkanına sahip olabiliriz.
Mixin'ler, prototip tabanlı bir dil olan JavaScript için oldukça faydalı bir yapıdır. İlerleyen zamanlarda kullanmak istediğimiz özellikleri mixin olarak tanımlayabilir ve çok daha az kod ile işlem yapabiliriz. Ayrıca, bir sınıfın için var olan bir özelliği başka bir sınıfta da kullanarak kod tekrarını da engelleyebiliriz.
Özellikle büyük projelerde mixin'lerin kullanımı oldukça faydalıdır. Farklı birimlerde çalışan farklı insanlar kodu anlamayabilirler. Bu durumda, karmaşık bir kod ortamında mixin yapısını kullanarak hem kodu anlaşılır hale getirebiliriz hem de daha az kod oluşturabiliriz.
JavaScript'te mixin yapıları oldukça basittir. Sadece birden fazla sınıfın özelliğini birleştirmeniz ve yeni bir objeye atamanız yeterlidir. Örneğin;
Kod: | // Biçim 1const Buyable = { buy() { console.log("Satın alındı."); }}const Sellable = { sell() { console.log("Satıldı."); }}const Item = { price: 100, weight: 10,}const NewObj = {...Buyable, ...Sellable, ...Item};console.log(NewObj.buy()); // Satın alındı.console.log(NewObj.sell()); // Satıldı.console.log(NewObj.price); // 100console.log(NewObj.weight); // 10 |
---|
Gördüğünüz gibi, mix alan bir obje üzerinden tüm özelliklere erişebildik. Mixin yapısının birden fazla kullanım örneği bulunmaktadır. Özellikle React ve Vue gibi framework'lerde mixin yapısı oldukça yaygın kullanılmaktadır.
Kapsülleme ve Korumalı Özellikler
JavaScript programlama dilinde nesne yönelimli programlama yapısı kullanılırken, kapsülleme ve korumalı özellikler oldukça önemlidir. Kapsülleme, nesnelere erişimi sınırlamak için kullanılır ve nesnelerin içindeki özelliklere dışarıdan erişimin önüne geçer. Bu sayede özelliklerin istenmeyen değişikliklerden korunması sağlanır ve programlama hatalarının önüne geçilir.
Encapsulation kullanımı ile birlikte, private ve protected property'ler de tanımlanabilir. Private property'ler sadece nesne içinde erişilebilirken, protected property'ler ise hem nesne içinde hem de miras alan nesneler içinde kullanılabilir.
JavaScript'te, private özelliğe sahip bir nesne oluşturmak için, fonksiyonlar kullanılabilir. Bu fonksiyonlar içinde, nesne özellikleri var olan farklı bir özellik adıyla tanımlanır ve bu özellik üzerinden nesne özelliklerine erişilir. Protected property'ler ise, nesne içinde tanımlandıkları gibi miras alan nesnelerde de kullanılabilir. Bu sayede, miras alan nesnelerde de aynı özellik ve özellik değerleri kullanılabilir.
Korumalı özelliklerin tanımlanması için, prototype yöntemi kullanılabilir. this anahtar kelimesi ile tanımlanan özellikler, fonksiyonlarda ve miras alan nesnelerde de kullanılabilir. Bu sayede, nesne yaratırken ve yaratıldıktan sonra da kapsülleme ve korumalı özelliklerin kullanımı, hataları önleyerek programların daha stabil olmasını sağlar.
The Factory Pattern
Factory Pattern, yazılım mühendisliğinde kullanılan popüler bir tasarım desenidir. Bu tasarım deseni, diğer kod bloklarını etkilemeden bir nesne grubu oluşturmayı, bu nesneleri oluşturmayı ve ayarlamayı kolaylaştırır. Bu kavram, bir nesnenin nasıl üretileceği ve hatta bir Interface aracılığıyla nasıl üretileceği konusunda bir şablon sağlar.
Bu yapı, Factory Method ve Abstract Factory tasarım desenlerine benzer, ancak tek farkı, sınıfların üretim yöntemlerini yönetmek yerine, belirli bir sınıfın Factory sınıfına sahip olmasıdır. Bu yapının amacı, uygulamalarda kullanımı kolay, genişletilebilir ve bakımı kolay nesneler oluşturmaktır.
Bir örnek vermek gerekirse, bir restoranın menüsünde çok sayıda yemeği olan bir sınıf düşünelim. Bu durumda, her yemeğin bir nesne olarak gösterilmesi ve üretilmesi daha uygun olacaktır. Factory Pattern, menüdeki yemeklerin nesnesini oluşturmak için bir yapı sağlar.
Aşağıdaki tabloda, Factory yordamlarının temel yapısını gösteren bir örnek yer almaktadır:
Factory Method | Abstract Factory | Factory Pattern |
---|---|---|
Üretim yöntemi tekil | Üretim yöntemleri genişletilebilir | Factory yöntem üzerinden üretim yönetimi |
Yeni bir alt sınıf eklemek için yeniden kodlama gerekir | Yeni bir alt sınıf eklemek için kodlamaya gerek yoktur | Yeni bir alt sınıf eklemek için factory metodu değiştirilir |
Factory Pattern, kesinlikle belirli durumlar için uygun olmayabilir veya fazladan karmaşıklık getirebilir. Ancak, büyük ve karmaşık uygulamalar için, bu tasarım deseni kullanımını kolaylaştırır ve daha düzenli bir kod üretim süreci sağlar.
Singleton Pattern
Singleton pattern, nesne yönelimli programlama yapısında kullanılan bir tasarım desenidir. Bu desen, herhangi bir sınıftan sadece bir örnek (instance) oluşturulmasını sağlar ve bu örneğe her yerden erişilebilir kılar. Bu sayede, bir örneğin birden fazla defa oluşturulmasının önüne geçilir ve tek bir örnek üzerinden işlemler gerçekleştirilir.
Singleton pattern özellikle ayar dosyaları, veritabanı bağlantıları gibi bir uygulamada sadece bir kere oluşturulması gereken nesneler için kullanılır. Böylece gereksiz bellek tüketimi önlenir ve uygulamanın performansı artar.
Bir örnekle singleton pattern'ın kullanımı açıklanacak olursa, örneğin bir uygulamada veritabanına bağlanmak için bir sınıf oluşturulması gerektiğini düşünelim. Bu sınıfın her defasında bağlantıyı oluşturması gereksiz işlem olacaktır. Ancak singleton pattern kullanılırsa, ilk bağlantı oluşturulduktan sonra sınıfın tekrar çağrılması durumunda aynı bağlantı kullanılacaktır.
Bir önceki örneği dikkate alarak, singleton pattern'ın uygulandığı bir JavaScript kodu örneklendirilmek istenirse aşağıdaki gibi bir kod bloğu oluşturulabilir:
// Singleton pattern uygulamasıvar DBConnection = function () { var instance; // önceki örnekte kullanılan private instance değişkeni function createInstance() { var object = new Object("Database Connection"); return object; } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; }, };};// Örnek kullanımvar connection1 = DBConnection.getInstance();var connection2 = DBConnection.getInstance();alert("Aynı Bağlantı: " + (connection1 === connection2)); // true
Bu örnek kodda, DBConnection sınıfımızı singleton pattern'a göre tanımlıyoruz. createInstance() fonksiyonu, sınıfın tek bir örneğini oluşturur. instance değişkeni ise örnekleme işlemi yapıldıktan sonra bu örneği bellekte tutar.
getInstance() fonksiyonu ise sınıfın örneklemesinde kullanılır. Bu fonksiyon, instance değişkeninden önce kontrol edilerek, daha önce bir örnekleme yapılmamışsa createInstance fonksiyonu aracılığıyla örnekleme yapılır ve bu örneğe getInstance() fonksiyonu ile erişilir.
Sonuç olarak, kodda iki defa DBConnection sınıfından instance oluşturumu yapılmak istense bile, aynı instance kullanılır ve "Aynı Bağlantı: true" mesajı ekranda görüntülenir.