• (ing. open close principle)

    "her turlu yazilim birimi geli$tirmeye/geni$lemeye acik ancak modifikasyona kapali olmalidir" $eklinde ozetlenebilecek nesneye dayali yazilim geli$tirme prensibi. yani yazilimimiza yeni yetenekler eklerken mevcut kod en az $ekilde degi$iklik gerektirmeli ve yeni geli$tirmelere olanak sagliyor olmalidir.

    mesela aşağıdaki gibi dört sınıf tanımlamış olalım :

    sınıf hayvan
    {
    karakter[] isim;
    sayı ayak_sayısı;
    }

    sınıf kedi : hayvan
    {
    fonksiyon kedi()
    {
    isim = "kedi";
    ayak_sayısı = 4;
    }
    }

    sınıf kuş : hayvan
    {

    fonksiyon kuş()
    {
    isim = "kuş";
    ayak_sayısı = 2;
    }

    }

    sınıf hayvanat_bahçesi
    {

    fonksiyon eğlendir(hayvan o)
    {
    eğer(o.isim=="kedi")
    {
    yaz("miyav");
    }
    veya
    eğer(o.isim=="kuş")
    {
    yaz("cik");
    }
    }

    }

    burada "hayvanat_bahçesi" sınıfındaki "eğlendir()" fonksiyonu açık kapalı prensibine uygun olmayan bir implementasyon içermektedir. zira hayvan sınıfından türetilen her yeni sınıf için hayvanat_bahçesi sınıfına yeni bir kontrol satırı eklenmesi gerekmekte, başka bir deyişle mevcut kodda değişiklik gerektirmektedir.

    halbuki şöyle yapılsa idi tam süper olurdu sanki :

    sınıf hayvan
    {
    karakter[] isim;
    sayı ayak_sayısı;

    özet fonksiyon ses_çıkar();
    }

    sınıf kedi : hayvan
    {

    fonksiyon kedi()
    {
    isim = "kedi";
    ayak_sayısı = 4;
    }

    fonksiyon ses_çıkar()
    {
    yaz("miyav");
    }

    }

    sınıf kuş : hayvan
    {

    fonksiyon kuş()
    {
    isim = "kuş";
    ayak_sayısı = 2;
    }

    fonksiyon ses_çıkar()
    {
    yaz("cik");
    }
    }

    sınıf hayvanat_bahçesi
    {

    fonksiyon eğlendir(hayvan o)
    {
    o.ses_çıkar();
    }

    }

    görüldüğü gibi burada istenildiği kadar hayvan tanımı yapılmakta ve temel sınıf ile türetilen sınıfları kullanan sınıflarda herhangi bir değişikliğe gerek olmamaktadır.

    ayrıca;

    (bkz: ters bagimlilik prensibi)
    (bkz: arayuz ayirma prensibi)
    (bkz: liskov degistirme prensibi)
    (bkz: tek sorumluluk prensibi)
  • açık yeşil, kapalı ise kırmızı şeklinde bağırır karşıyaka taraftarı.. böyle entresan bir prensipleri vardır..
  • evleneceği bayanın seçiminde başının kapalıaçık mı olduğunu değerlendirme kıstası .
  • geliştirmeye açık, değiştirmeye kapalı proje yaklaşımı.
  • mevcut koda eklenecek her yeni class için -ki bu class'lar aynı interface'i implemente eder ya da aynı class'tan türemiştir- tip kontrolü yapmak yerine, sorunu polymorphism den yararlanarak çözmektir. bu şekilde gereksiz yere if else bloğu kullanma sorunu ortadan kalkar.
  • yazılım dilinde 5 basit programlama prensiplerinin kısaltılmış hali olan solid in ikinci prensibidir. *

    bu prensibe göre kodumuz gelişime açık fakat değişime kapalı olmalıdır. yanisi yeni davranışlar eklemek için mevcut kodumuzu değiştirerek değilde, bu işlemi yeni kod ekleyerek yapmamız gerektiğini söylüyor.
  • programlamada yazililm kod kalitesini arttirmayi amaclayan "solıd" prensiplerinin "o" harfine denk gelen "open/closed principle" yani bir bir sinifin veya methodun degisiklige kapali, ama genisletilmeye acik olmasi gerektigini soyleyen prensiptir. ornegin bir diktortgenin alanini hesaplayan bir program yazmak durumunda kalsak java dili ile en basitinden nasil yazariz; cok basit bir alan hesaplayici sinifi icinde hesapla methodu, bu method genislik ve yuksekligi alip birbiri ile carpip alani bulup geri donuyor.

    class alanhesaplayici {
    public int hesapla(int genislik, int yukseklik){
    return genislik * yukseklik;
    }
    }

    daha sonra bizden bir de dairenin alanini hesaplamasi gereken bir kod yazmamizi istediiler. biz de bu hesapla methodunu daha genel hale getirip dairenin alanini hesaplyabilen sekle getirebiliriz. hesapla methodu bir sekil objesi alir ve bu sekil objesi dikdortgen ise dikdortgen alan hesabini yapar, daire ise daire alan hesabini yapar.

    class alanhesaplayici {
    public int hesapla(sekil sekil){
    if (sekil instanceof dikdortgen){
    return sekil.genislik * sekil.yukseklik;
    } else if (sekil instanceof daire){
    return sekil.cap * sekil.cap * math.pı;
    }
    }
    }

    bu alan hesabini yapan "hesapla" methodunu degistirdigimiz gibi bir de ayrica bu methodu cagiran tum kodlari, dokumantasyonunu, test kodlarini hepsini degistirmemiz lazim. peki bir sure sonra bizden bir de ucgen alan hesabi yapan bir kod isterlerse ne olacak. yine ayni sekilde method, daha sonra dokumantasyon, test kodlari hepsi degisecek. bu isin sonu yok, "hesapla" methodu uzadikca uzuyor, her degisiklik bircok yerde degisiklige neden oluyor. bu tam bir kalitesiz kod ornegi. bu kalitesizligi anlamak icin bir kod bloguna bakin, icinde buyuk if-else blogu var ise bu kodun "acik/kapali prensibi"ni ihlal etme ihtimali buyuk.

    peki bu prensibi ihlal etmemek icin ne yapmak gerekiyor? oncelikle her bir objeyi ilgilendiren hesaplamayi o objenin icine almak gerekir. bir onceki kod blogunda "sekil instanceof dikdortgen" ve "sekil instanceof daire" seklinde iki kod blogumuz vardi. bu kod bloguna gore bizin zaten bir "diktortgen" sinifimiz, bir de "daire" sinifimiz var demektir. arada "instanceof" olduguna gore de bu siniflar "sekil" sinifindan turetilmistir. yapmamiz gereken bu hesapla methodunu bu siniflarin icine tasimaktir.

    class dikdortgen {
    int genislik;
    int yukseklik;
    public int alanhesapla(){
    return this.genislik * this.yukseklik;
    }
    }

    class daire {
    int cap;
    public int alanhesapla(){
    return this.cap * this.cap * math.pı;
    }
    }

    boylece kendi oz ve oz hesaplama methodunu barindiran siniflarimiz olmus oldu. ama bu da yeterli degil, cunku ilerde bir gelistirici "ucgen" sinifi yartirsa bu kisiyi "hesapla" methodu yazmaya kim zorlayacak. bu durumda onumuze iki secenek cikiyor, ya "abstract sekil" sinifimiz olacak ya da bir "sekil interface" imiz olacak. dikdortgen, daire, ucgen de bu sekil sinifindan tureyecek. burada kendimize sormamiz gereken "sekil" gercek hayatta bir nesneyi mi yoksa bir nesnenin ozelligimidir. sekil gercek hayatta somut olara var olmayan ama ucgen, kare, dikdortgen, daire gibi kavramlari genel tanimlayan "soyut" (abstract) bir kavramdir. o nedenle bir abstract sinif olusturacagiz ve icinde de abstract "alanhesapla" methodu olacak. boylece sekilden tureyen tum objeler bu abstract methodu gerceklestirmek zorunda olacak.

    public abstract class sekil{
    public abstract double alanhesapla();
    }

    class dikdortgen extends sekil{
    int genislik;
    int yukseklik;
    public int alanhesapla(){
    return this.genislik * this.yukseklik;
    }
    }

    class daire extends sekil{
    int cap;
    public int alanhesapla(){
    return this.cap * this.cap * math.pı;
    }
    }

    bu sayede ilerde ucgen ihtiyacimiz oldugunda yapmamiz gereken ucgeni sekilden turetmek, ve zorunlu olarak alanhesapla methodunu gerceklestirmek.

    class ucgen extends sekil{
    int taban;
    int yukseklik;
    public int alanhesapla(){
    return (this.taban * this.yukseklik) / 2;
    }
    }

    bu yapi sayesinde her bir obje kendine yeten, sirf kendine ait alan hesaplama ozelligine sahip olacaktir. bu nedenle de ilerde yeni bir sekil ihtiyaci dogdugunda sekil sinifinda ya da herhangi bir alt sekil sinifinda (daire, dikdortgen, ucgen) degisiklik yapmamiz gerekmeyecek. hatta ilerde bu sekil siniflarindan birine hityacimiz olmadiginda ve silmek istedigimizde ust siniflarin hicbirinde degisiklige gerek duymadan rahatlikla silebilecegiz.
  • nesne yönelimli programlamada kodun bir adım daha ideale yaklaşmasına yardımcı prensiplerden bir tanesidir. teknolojiyle beraber gündelik yaşamımıza giren güncelleme kavramını düşünürsek, yazılımların sürekli orasıyla burasıyla oynandığını, uygun tabirle geliştirilme sürecinin devam ettiğini görebiliriz.
    bu geliştirme sürecini lego parçalarından tasarladığımız, afilli ve öfkeli gözüksün diye kanat formunda parçalar eklemek istediğimiz araba şeklindeki bir oyuncağa benzetirsek; eğer kanat takacağımız alanda yer var ve biz lego parçalarını sorunsuzca takabiliyorsak ne kadar hoş, ne kadar güzel.(genişlemeye açık, modifikasyona kapalı) test sürecinde yalnızca arabamızın eklenen kanat kısımlarında sorunlar çıkabilir belki, ana tasarıma herhangi etkisi olmaz. kanatlar üzerinde düzeltmelere gidilir en fazla tekrardan.
    ama kanat takılacak alan bulamayıp önceki tasarımda bazı parçaları söküyorsak, yer değiştiriyorsak işte o zaman sıkıntı var. (modifiye şahin açık)
    çünkü oyuncağımız geliştirme sürecinden önce gayet sorunsuzdu, hatalarından arındırılmıştı. şimdi ise kanatların hata ihtimaliyle beraber önceki sağlam tasarımda da hata çıkabilir artık.
    işte açık kapalı prensibimiz, kodunu tasarlarken bu durumu göz önüne al,genişlemeye açık ol ama modifiye şahinden uzak dur diyor.
  • "değişime kapalı ama geliştirmeye açık" diyince kafa karıştırıyor ve neden iyi bir şey olduğu anlaşılmıyor.

    closed:
    bir sınıfın sunduğu bir işlevin her zaman aynı işi yapacağından emin olalım. önüne gelen üzerinde değişiklik yapamasın.

    kodun akışı sırasında a sınıfından çağrılacak b fonksiyonu hep aynı işi yapmalı. arada gidip birileri kafasına göre bu fonksiyonu değiştirmiş olmamalı. deterministik olmalı.

    open:
    bir sınıfın sunduğu işlevler üzerine yenileri ilave edilebilmeli.

    yazılım geliştirme sürecinde a sınıfına c isimli yeni bir fonksiyon ekleyebilmeliyiz. esneklik olmalı.
  • (bkz: #94280510)

    uygulama gelişime açık, değişime kapalı olmalıdır.
    yazılım doğası gereği sürekli güncellenmektedir. sürekli yeni ihtiyaçlar, yeni durumlar ortaya çıkmaktadır. yani yazılım bir süreçtir. bu süreçte uygulama geliştirilebilmeli fakat değiştirilmemelidir.
    bu prensipte genel olarak gelişim anlaşılıyor fakat değişim anlaşılamıyor.
    değişimden kastımız nedir? uygulamaya yeni bir özellik, yeni bir durum eklendiğinde önceden yazdığımız kodu değiştirmeden, sadece ihtiyacımız olan yeni yere kod yazarak yapabiliyor olmalıyız.
    yukarıda bahsettiğim öğretmen, mühendis ve bakkal örneğine bir de doktor eklenmesi gerektiğinde, sadece doktor u ekleyip uygulamamın hazır olmasını bekleriz. örneğin maaş hesaplaması yapılan bir yere bir else if daha eklenmesi gereken bir durum oluşuyorsa bu open-closed principle'e aykırı olacaktır.
hesabın var mı? giriş yap