“Measuring programming progress by lines of code is like measuring aircraft building progress by weight.”
by Bill Gates

Nexus 5 vs. LG G2

Tarih: Şubat 12th, 2014 | Yazar: | Kategoriler: Dışlananlar | Etiketler: , , | Yorum Yok »

LG G2′yi 20 gün, Nexus 5′i de 2 hafta boyunca kullanma şansım oldu. Öncelikle iki telefonun teknik detaylarını öğrenmek istiyorsanız buraya bakabilirsiniz. Ben bu yazıda daha çok iki telefonu kullanırken elde ettiğim deneyimlerden bahsedeceğim.

LG G2′nin Artıları:

lg-g2-white-big

  • Pil: Hiç şüphesiz 3000mAh‘lik pil rakiplerine fark atıyor.  Ben zorlayarak 4 gün kullandım hiç şarj etmeden. Normal kullanımda 2 gün, yoğun kullanımda bir günü rahatlıkla çıkarttı.
  • Dahili FM Radyo: Radyonun olması data paketinizi tüketmeden çok pil harcamadan radyo kullanmanızı sağlıyor. Nexus 5′de böyle bir seçenek yok. (Türkiye’de satılan bazı modellerde kutudan çıktığında radyo aktif geliyor. Aktif olmayanlar ise root ile açılabiliyor)
  • Pencere içerisinde açılan uygulamalar: Benim kullanımım sırasında çok işime yaramadı ancak bazı durumlarda çok işlevsel olacağını düşünüyorum. Örneğin; bir excel tablosundaki sayıları pencere içinde açılmış hesap makinesi ile excel tablosundan çıkmadan toplayabilmek.
  • Ekran: Nexus 5′e göre bir tık daha iyi olduğunu düşünüyorum.
  • Kutudan kulaklık çıkması. (Nexus 5′de çıkmıyor)
  • Bildirim Işığı: Nexus 5′e göre bildirim ışığı daha net ve belirgin.
  • Knock-on: Çoğunlukla birden fazla iki kez dokunmak gerekse bile alıştıktan sonra kullanması iyi oluyor.
  • Hoparlör: Nexus 5′e göre hoparlörü daha iyi.

LG G2′nin Eksileri:

  • Malzeme Kalitesi: Gıcırdayan ve parlak arka kısmı elinizde aldığınızda çok iyi bir his bırakmıyor.
  • *Kamera: Hem fotoğrafta hem de videoda kameranın geç odaklanması zaman zaman can sıkıyor. Optik görüntü sabitleme(OIS) özelliğinden de pek beklediğimi bulamadım.
  • *Takılmalar: Birçok kişi bu diyeceğimi fark etmeyecektir ancak ben G2′den hemen sonra Nexus 5 kullandığım için net olarak fark ettim. Arayüzde aşağı yukarı kaydırırken, resimli listelerde gezinirken ara ara takılmalar oluyor. Ben en fazla Twitter uygulamasında ve ayarlar bölümünde yaşadım bu sorunu. Akıcılık anlamında Nexus 5′e göre kesinlikle G2 zayıf.
  • *Dokunmatik Performansı: Bir önceki madde gibi bu da dikkat edilmez ise fark edilmeyecek bir konu ama yine de belirtmek istiyorum. Ekranda dokunarak yaptığınız hareketlerin ekrandaki yansımasında bir gecikme var. Belki birkaç milisaniye ama Nexus 5′e göre geç tepki veriyor.
  • LG’nin Uygulamaları: Telefonu ilk aldığınızda LG tarafından yapılmış birçok uygulama yüklü geliyor ve bunları kaldıramıyorsunuz. Özelikle hiç kullanmayacağınız uygulamalar hem hafızayı tüketiyor hem de gereksiz kalabalık yapıyor.
  • *Otomatik Ekran Parlaklığı: Otomatik seçeneği aktif olduğunda ekran parlaklığı yumuşak bir şekilde azalıp artmıyor. Kademeli olarak ayarlıyor kendisini.
  • RAM Kullanımı: Telefonu yeniden başlattığınızda ve hiç bir uygulama açık değilken bile yaklaşık 1GB RAM kullanıyor. Bu Nexus 5′ın neredeyse 2 katına denk geliyor.
  • Yazılım Desteği: Android 4.4 KitKat’ın yayınlanmasının üzerinden aylar geçmesine rağmen G2′nin ne zaman güncellemeyi alacağına dair tarih bile yok. Kişisel olarak; G2 KitKat’ı alsa bile ondan sonra gelecek güncellemeyi almasını zor görüyorum.
  • USB Kablosu: (Önemsiz bir konu ama yine de belirteyim.) Kutudan çıkan USB kablosu oldukça sert. Şarja taktığınızda telefonunun şarj girişini havaya kaldıracak kadar sert.
  • Tuş Yerleşimi: Bildiğiniz üzere G2′nin tüm tuşları arkasında. Bu biri ile konuşurken telefonu yüzünüze dayadığınızda işe yararken, normal kullanımda benim için zorluk yarattı. Arkadaki tuşlara basmak için uyguladığınız baskı, telefonun elinizden düşüreceğiniz hissi uyandırıyor.
  • Ses Kalitesi: Telefon görüşmelerinde bazen ses boğuk geliyor. Bu karşı taraftan da kaynaklanıyor olabilir ama G2′de daha fazla hissediliyor boğukluk.

Nexus 5′in Artıları

nexus-5-weiss_628

  • İlk sıraya yazacağım şey kesinlikle arayüzün akıcılığı. Bunu girdiğiniz her uygulamada, her menüde hissediyorsunuz.
  • Malzeme Kalitesi: G2′ye göre kesinlikle daha iyi. Kauçuğa benzer mat arka kısım G2′nin parlak arka kısımına göre kesinlikle daha iyi bir his bırakıyor.
  • Tasarım: Göze Nexus 5 tasarım olarak daha hoş geliyor. (Özellikle beyaz versiyon)
  • Kamera: Kağıt üstünde G2′nin kamerası üstün gözükse de daha hızlı odaklaması ve görüntü kalitesi olarak Nexus 5′in kamerası G2′ye göre daha iyi. Ayrıca, Nexus 5′in kamera uygulaması da daha sade ve kullanışlı buldum.
  • Yazılım Desteği: Android dünyasında en hızlı ve en fazla güncellemeyi Nexus serisi alıyor. Burada sadece G2′ye değil diğer tüm telefonlara Nexus’lar fark atıyor. (Nexus 5′i tercih sebebim.)
  • Arayüz: Stok Android arayüzü kesinlikle daha iyi.

Nexus 5′in Eksileri

  • Pil: G2 ile arasındaki 700mAh farkı hissediyorsunuz. Nexus 5′i de zorlayarak 3 gün hiç şarj etmeden kullandım. Nexus 5 de normal kullanımda 2 günü çıkarttı. Yoğun kullanımda ise G2′ye göre gün sonunu zor görebilirsiniz.
  • Bildirim Işığı: Verdiği ışık, miktar olarak yetersiz. Ayarlama yapmak için ise mutlaka bir yazılım kurmanız gerekiyor.
  • Google’un Uygulamaları: Telefon kutudan çıktığında birçok Google uygulaması ile yüklü geliyor. G2′de olduğu gibi yine bunları silemiyorsunuz. Benim için çok önemli bir sorun değil zira birçok Google hizmetini kullandığım için uygulamaları da kullanıyorum.

Ben kararımı Nexus 5′den yana kıldım.

*Bu sorunlar ilerde gelecek yazılım güncellemeleri ile çözülebilir. 


Notlarım: Komut Satırı En İyi Arkadaşınız

Tarih: Mart 10th, 2013 | Yazar: | Kategoriler: Komut Satırı | Etiketler: , , , | 1 Yorum »

Bu yazımda, buradaki yazıyı The Command Line is Your Best Friend okurken çıkardığım notları paylaşmak istiyorum. (Özet severlerin hoşuna gideceğini düşünerek :) )

Kendim için not aldığım için, çok fazla detayları katmadım. Ama birilerine faydası dokunur diyerek paylaşıyorum.

Not 1: Yazıda geçen komut satırı *nix(Unix/Linux) ortamındaki komut satırıdır. Bu yüzden Windows ortamında bu komutları denemeniz için Cygwin uygulamasını indirebilirsiniz. Bu uygulama ile birçok BASH komutunu Windows işletim sistemi üzerinde çalıştırmanız mümkün.

Not 2: Bu yazıdakilere ek olarak, sizin de ekleyebileceğiniz kullanışlı komutlar veya püf noktalar varsa, yorum olarak paylaşırsanız sevinirim. Şimdiden teşekkürler.

Unix sistemlerde her şey bir dosyadır(file). Klavye, fare, ekran ve diğer her şey birer dosyadır.

Dosya türü ayraçları:

  • 0 standart girdi(stdin)
  • 1 standart çıktı(stdout)
  • 2 standart hata(stderr)

Genel:

  • Komut girilen satırın başında $ varsa kullanıcı root değil, # varsa ise kullanıcı root.
  • ~ işareti o anki kullanıcıya ait home dizinini gösterir. Örnek; dizine gitmek için cd ~ kullanılır veya o dizindeki bir dosyayı açmak için: cd ~/dosyaismi
  • kullaniciadi@computerhostname @’den önce kullanıcı adı sonrası ise bilgisayarın host ismi
  • Herhangi bir değişkeni ulaşmak için $degiskenadı şeklinde kullanıyoruz.
  • Bir değişkenin içerdiği değeri ekrana yazmak için echo $değişkenadi kullanıyoruz. Örnek: echo $PS1
  • Dosya oluşturmak için touch dosyasına veya touch dizin/dosyaisimi de olabilir.
  • mcedit dosyaadi şeklinde dosyaları düzenleyebilirsin. Programlama dili desteği olduğu için code renklendirmesi var. Editörden çıkmak için iki kez üst üste ESC basılarak çıkılıyor veya F10 ile. Aşağıda gözüken numaraların fonksiyon tuşlarındaki karşılıkları ile kullanabilirsin.
  • nokta(.) işareti şu anki konumu ifade eder. iki nokta(..) işareti bir üst dizinin konumunu ifade eder. Örnek; şu anki konumdan alt bir dizine geçmek istiyorsak: cd ./altdizi
  • cat dosyaismi komutu ile girilen dosya isminin içeriği okunabilir.
  • grep “aranacak kelime” dizin/dosyaismi ile belirtilen dosyanın içeriği içinde arama yapılabilir. Ek olarak –color eklenerek gelen sonuçta eşleşen bölge renklendirilebilir. Örnek; grep “kelime” deneme.txt –color
  • pipe: bu komut “|” işareti ile kullanılır. | işaretinden önceki komutun ürettiği çıktıyı | işaretinden sonraki komuta aktarır. Örnek; cat ./SecondDir/ThirdFile | grep “Another” veya ls | grep “deneme” –color Bu örnekte cat ile içeriğini okuduğumuz dosyanın çıkıtısı üzerinden, grep ile “deneme” kelimesini arıyoruz.
  • sed: bu komut ile çıktı veya dosya içinde regular expression kullanarak arama yapılıyor. Örnek; cat ./SecondDir/ThirdFile | grep “Another” | sed -e “s/AnotherFile/MyFile/”
  • [geçici]kendi komutunu tanımlama: alias komutismi=”çalıştırmak istediğim komutlar” Örnek: alias listele=”ls” Ancak bu yolla oluşturulan komutlar oturum süresince korunur. Oturumdan çıkıldığında(logout) bu komutlar silinir. Yani geçicidir.
  • [kalıcı]kendi komutunu tanımlama: .bashrc veya .bashprofile dosyaların içerisine alias ile kendi komutumuzu kalıcı olarak tanımlayabiliyoruz. Bu iki dosya genelde kullanıcıya ait home klasöründe(~) bulunuyormuş.
  • .dosyaismi gibi başında nokta(.) ile başlayan isimlendirmeler gizli dosyaları belirtmek için kullanılır.
  • traceroute: bu komut ile yazacağımız hedefe giden yolda uğradığımız noktaları görebiliyoruz. Örnek; traceroute 8.8.8.8 veya traceroute www.google.com
  • ifconfig: komutu ile ağ yapılandırmasını(network configuration) görebiliyoruz.
  • netstat: komutu ile açık olan bağlantıları listeliyoruz. Örnek: netstat veya netstat -an

Yönlendirme(Redirection)

  • İçeri yönlendirme <: bir komuta bir dosya yönlendirmek istiyorsak eğer, komut < dizin/dosyaismi şeklinde gönderebiliriz
  • Dışarı yönlendirme >: bir komutun çıktısını bir dosyaya yazdırmak istiyorsak eğer, komut > dizin/dosyaismi şeklinde yazdırabiliriz. Örnek: bir klasörün içerisindeki dosya ve klasörleri bir dosyaya yazdırmak istiyorsak; ls > dosyaismi
Sadece hataları yönlendirmek istiyorsak eğer; ls 2> dosyaismi şeklinde veya hataları dışarıda bırakıp standard çıktıyı yönlendirmek istiyorsak eğer ls 2> dosyaismi olarak kullabiliriz. 2 yönlendirildiyse 1 ekranda yazar, 2 dosyaya gider. Yani kalan türler ekrana basılır. Bknz: Dosya türü ayraçları.
Türler arası da yönlendirme yapmak mümkün. Örneğin: stderr’i stdout’a doğru yönlendirebiliriz. Bu şekilde bir kullanımda 1(stdout) aynı zamand 2(stderr)’i de temsil eder. Örnek; find . -name *File 1>./SecondDir/ThirdFile 2>&1
Görmek istemediğimiz çıktıları /dev/null ‘a yönlendirebiliriz. /dev/null ‘a yönlendirilen herhangi bir şey yok olur, kayıt altına alınmaz. Örnek: wget -r -P /dev/null http://www.domain.com

Arama(Find)

  • find aranacak klasörün yolu( nokta(.) ile şu anki klasörü iki nokta (..) ile bir üst klasörü belirtebiliriz) -name aranacak dosyanın tam adi deneme.txt gibi Örnek; find . -name deneme.txt veya find klasor -name deneme.txt
  • find ile arama yaparken bilmediğimiz karakterler için ? ve * işaretlerini kullanabiliriz. ? bilinmeyen bir karakteri temsil ederken * karakteri birden fazla karakteri temsil eder. Örneğin; find . -name deneme.* veya find -name deneme.??? Üç kez soru işareti kullandık nedeni txt’nin 3 karakterli olması. Bu özel karakterler sadece dosya uzantısında değil dosya isminin kendisinde de kullanılabilir.

İzinler(Permissions)

  • Nesnenin sahibi nesnenin izinlerini her durumda değiştirebilir, ancak nesnenin izinleri yoksa chown ile sahibini değiştiremez. Bu durumda izinleri ayarlayıp daha sonra sahip değiştirilebilir.
  • Her bir kullanıcı en az bir gruba dahil olur.
  • Uygulamalar kendi kullanımları için özel kullanıcı oluştururlar. Erişimi sınırlı dosya ve klasörlere bu kullanıcı ile erişirler.
  • Tüm kullanıcılar /etc/passwd konumundaki dosyada yer alır.
  • Tüm gruplar /etc/group konumundaki dosyada yer alır.
  • drwxr-xr-x 5 csaba csaba 4096 Feb 24 00:44 Kırmızı: kullanıcı, Mavi: grubu temsil eder. Bunlar dosyanın sahipleridir(Owner)
  • Dosya/klasör sahibini değiştirmek için: chown user:group hedef Örnek: chown Can:root deneme.txt Sadece iznimiz olan dosya/klasör’lerde değişiklik yapabiliriz. Grup veya kullanıcı bazında. root gibi yönetici konumundaki kullanıcılar tüm dosya ve klasörlerde değişiklik yapabilir.
  • drwxr-xr-x 5 csaba csaba 4096 Feb 24 00:44 Kullanıcı izinleri 3 kategoride yer alır. Bunlar;
    • Kullanıcı(User): Nesnenin sahibi olan kullanıcının izinleri
    • Grup(Group): Nesnenin sahibi olan grubun izinleri.
    • Diğerleri(Others): Diğer kullanıcıların izinleri.
  • drwxr-xr-x 5 csaba csaba 4096 Feb 24 00:44 Burada yer alan r, w, x’in anlamları
  • okuma izni
  • yazma izni
  • çalıştırma(execute) izni
  • ise directory’i temsil ediyor olabilir.(Benim fikrim)
  • ise herhangi bir izin olmadığını temsil ediyor.         
  • chmod +rwx ./ThirdDir/ buradaki +‘nın anlamı izin ekledir. Bunun yerine - kullanılırsa izin çıkarılır.
  • İzinlerin nümerik karşılıkları:
    • rwx: Each bit is set to 1: 111. Which in decimal is 7.
    • rw-: Is represented as 110. Which in decimal is 6.
    • r-x: Is represented as 101. Which in decimal is 5.
    • r--: Is represented as 100. Which in decimal is 4.
    • -wx: Is represented as 011. Which in decimal is 3.
    • -w-: Is represented as 010. Which in decimal is 2.
    • --x: Is represented as 001. Which in decimal is 1.
    • ---: Is represented as 000. Which in decimal is 0.

Google Chrome’da Kullandığım Uzantılar

Tarih: Aralık 16th, 2012 | Yazar: | Kategoriler: Dışlananlar | Etiketler: , | Yorum Yok »

Tarayıcıların yeteneklerini geliştirmek için uzantılara(eklentilere) başvururuz. Kimi zaman bazı uzantılar tarayıcı deneyimimiz oldukça verimli kılar. Ben de, bu yazımda kullandığım ve memnun kaldığım Google Chrome uzantılarını sizinle paylaşacağım.

  • Instant Translate: Fare ile seçeceğimiz cümle veya kelimelerin bizim seçtiğimiz dile çeviriyor. Google Translate tabanlı çalışan bu uzantı özellikle kelime çevirisi bakımından oldukça başarılı. Seçilen kelimenin anlamlarını türüne göre(sıfat, zarf, isim…) gruplayarak anlamamızı kolaylaştırıyor.
  • Evernote Web ClipperEvernote‘un resmi Chrome uzantısı.(Evernote kullanmıyorsanız mutlaka denemenizi öneririm) Bu uzantının iki özelliği var. İlk olarak gezdiğiniz sayfalar hakkında not almanızı sağlıyor. İkinci ve benim en çok sevdiğim özelliği ise yaptığınız Google aramalarını aynı zamanda aldığınız notlar içerisinde de yapıyor. Örneğin: Google’da “elma” diye aradığınızda, uzantı  “elma” kelimesini notlarınız arasında da arıyor ve bir eşleşme çıkarsa Google’ın arama sonrası gelen sonuç sayfasında bu notları gösteriyor. Bu şekilde.
  • StylebotBazı web sayfalarının tasarımları hoşunuza gitmeyebilir veya gereksiz gördüğünüz parçaların(reklam, ilginizi çekmeyen ama oldukça yer kaplayan bileşenler…) sürekli önünüze çıkmasını istemeyebilirsiniz. Bu noktada Stylebot uzantısı yardımımıza koşuyor. Stylebot ile bir web sayfasını tasarımını kalıcı olarak değiştirebiliyoruz. Bu değişiklikleri yapmak için az da olsa CSS bilgisi gerekiyor. (Yaptığımız düzenlemeler sadece bizim tarayıcımızda çıkıyor ;))
  • Google Reader Open entry in background tabİsmi oldukça uzun, ama yaptığı bir tane iş var. Google Reader’da okuduğumuz o anki yazıyı “v” tuşuna basarak arka planda yeni bir tab olarak açıyor. Arkaplan’da açtığı için Google Reader’daki diğer yazılara geri dönmeden devam edebiliyoruz.
  • RSS Abonelik Uzantısı (Google’dan)Gezdiğimiz sayfaların varsa RSS’lerine tek tıkla abone olmamızı sağlıyor.
  • Screen Capture (by Google): Adından da anlaşılacağı üzere ekran görüntüsünü kayıt edebiliyoruz bu uzantı ile. Hem tüm sayfayı, hem istediğimiz bir bölgenin görüntüsünü kolaylıkla kayıt edebiliyoruz.  Ayrıca Picasa, Facebook, Imgur gibi servislere direkt olarak yakaladığımız görüntüyü göndermemizi sağlıyor.
  • ClearlyBir sayfadaki yazıyı, sayfada bulunan gereksiz şeylerden arındırıp, daha temiz bir okuma ekranı sağlıyor.
  • XML TreeJSONView: Bu iki eklenti ile XML veya JSON formatlarındaki verileri daha okunabilir yapabiliyoruz. Bu formatlar ile haşır neşir olan geliştiricilerin mutlaka işlerine yarayacaktır.

Sizin de kullanmaktan hoşlandığınız uzantılar varsa, yorum olarak paylaşırsanız sevinirim.


Coğrafi Konuma Göre Zaman Dilimini Tespit Etme

Tarih: Kasım 4th, 2012 | Yazar: | Kategoriler: Dışlananlar | Etiketler: , , , , | Yorum Yok »

Dünyanın tüm bölgelerine hitap eden bir web siteniz veya bir uygulamanız varsa, kullanıcıların içinde bulundukları saat dilimleri önemlidir. Bu duruma örnek vermek gerekirse; İngiltere’de bulunan bir üyeniz Türkiye’de bulunan bir üyeye sizin Amerika’da bulunan sunucunuz üzerinden mesaj attığını düşünürseniz, 3 farklı zaman dilimi ile uğraşmanız gerekmektedir. Yani İngiltere’den mesaj atan üyeye mesaj tarihini, İngiltere’nin zaman dilimine göre göstermeniz gerekir. Aynısı Türkiye’deki üye için de geçerlidir.

Kullanıcılara doğru tarihi göstermek için genelde zaman dilimini kullanıcıya sorarak öğreniriz. Bu yöntemi her zaman uygulayamayabiliriz veya daha pratik şekilde çözmek isteyebiliriz. Bu noktada bu yazının konusu olan, konuma göre zaman dilimi öğrenme çözümü derdimize derman olacaktır.

Google Maps API Web Servislerine yeni dahil olan The Google Time Zone API (Deneysel) ile konuma göre zaman dilimini öğrenebiliyoruz artık. Hem de oldukça kolay bir şekilde. Gelin bir bakalım…

İstekleri Yapacağımız URL:

https://maps.googleapis.com/maps/api/timezone/çıktı formatı(xml|json)?parametreler

İstekte Kullanacağımız Parametreler

  • location: Zaman dilimini öğreneceğimiz konumun bilgisi. Enlem(latitude) ve boylam(longitude) bilgilerini araya bir virgül(,) koyarak kullanıyoruz. Örnek: 39.926562,32.817512
  • timestampZaman dilimini öğreneceğimiz konumun timestamp olarak zaman bilgisi. Yani, Ankara’nın şu anki zaman dilimini öğrenmek istiyorsak güncel timestamp bilgisini, bir ay önceki zaman dilimini öğrenmek istiyorsak bir ay önceki timestamp bilgisini girmeliyiz. Örnek: 1352052772
  • sensor: Konum bilgisini GPS kullanarak öğrendiyseniz true değilse false

Yukarıdaki parametrelerin kullanılması zorunlu bunun dışında language parametresini kullanarak gelen cevabın hangi dilde üretilmesi gerektiğini belirleyebilirsiniz. Örnek: Türkçe için tr

Cevap Elementleri

  • dstOffset: Bu bilgi bize, konumun ne kadar gün ışığından(yaz saati uygulaması) yararlandığını verir. Örnek: Türkiye’de yaz saati uygulandığı bir zamanı timestamp olarak gönderirsek sunucuya bu değer 3600(saniye cinsinden) olacaktır yani bir saat gün ışığından faydalandığımızı gösterir.
  • rawOffset: Bu bilgi bize, konumun Eşgüdümlü Evrensel Zaman (UTC) ile olan farkını verir. Bu farkın içine gün ışığından yararlanma farkı dahil değildir. O yüzden konum için gün ışığından yararlanma söz konusu ise bu iki bilgiyi aynı anda değerlendirmekte fayda var.
  • timeZoneId: Bu bilgi ile zaman dilimi ID’sini öğrenebiliriz. Örnek: Türkiye için Europe/Istanbul değeri gelecektir. Küçük bir not: Bu element üzerinden gelecek bilgi PHP’deki zaman dilimi ID’leri ile aynı. Dönüştürme işlemi olmadan direkt kullanbilirsiniz.
  • timeZoneName: timeZoneId bilgisi teknik tarafta işe yarayacaksa bu bilgi de kullanıcı tarafında işe yarayabilir. Zaman dilimi bilgisini kullanıcının anlayacağı şekilde bu alan üzerinden öğrenebiliriz. Örnek: Türkiye için gelen değer bu şekilde olacaktır; Doğu Avrupa Standart Saati

Örnekler

Konum Ankara, Tarih: 4 Kasım 2012, Saat: 21:18:32 için Örnek Bir İstek ve Cevap

İstek:

https://maps.googleapis.com/maps/api/timezone/json?location=39.92077,32.85411&sensor=true&timestamp=1352056712&language=tr

Cevap:

{
   "dstOffset" : 0.0,
   "rawOffset" : 7200.0,
   "status" : "OK",
   "timeZoneId" : "Europe/Istanbul",
   "timeZoneName" : "Doğu Avrupa Standart Saati"
}

Konum Ankara, Tarih: 12 Temmuz 2012, Saat: 03:31:52(yaz saati uygulanan bir zaman) için Örnek Bir İstek ve Cevap

İstek:

https://maps.googleapis.com/maps/api/timezone/json?location=39.92077,32.85411&sensor=true&timestamp=1342056712&language=tr

Cevap:

{
   "dstOffset" : 3600.0,
   "rawOffset" : 7200.0,
   "status" : "OK",
   "timeZoneId" : "Europe/Istanbul",
   "timeZoneName" : "Doğu Avrupa Yaz Saati"
}

Bonus

  • Konumu(enlem ve boylam) adres bilgisi üzerinden öğrenmek için bu yazımı okuyabilirsiniz.
  • Konumu Geolocation üzerinden öğrenmek için bu yazımı okuyabilirsiniz.
  • Konuyla ilgili Google Maps’in dökümanına buradan ulaşabilirsiniz.

Strategy Design Pattern(Strateji Tasarım Şablonu)

Tarih: Ekim 29th, 2012 | Yazar: | Kategoriler: Tasarım Şablonları (Design Patterns) | Etiketler: , | Yorum Yok »

Eminim bu yazıyı okuyanlar en az bir tane Shooter(Silah kullanılan oyunlar. FPS’ler TPS’ler…) oyunu oynamıştır. Shooter oyunlarının temeli düşmanlar, silah ve bu silahı kullanan karakter üzerine kurulmuştur. Bu üç öge olmadan bir shooter oyunu düşünülemez. Gelin bizde bir shooter oyununu PHP tarafında modelleyelim.

Character sınıfımız

namespace Strategy;
require_once 'Weapon.php';
class Character
{
    public $name;

    public function attack($weapon, Character $target)
    {
        switch ($weapon) {
            case 'machineGun':
                printf("'%s' makinalı silah ile vuruldu", $character->name);
                break;
            case 'revolver':
                printf("'%s' tabanca ile vuruldu", $character->name);
                break;
        }
    }
}

Bir kişiye makinalı silah ve tabanca kullanarak ateş edelim.

require_once 'Character.php';

$hedef = new \Strategy\Character();
$hedef->name = 'Emma Richardson';

$katil = new \Strategy\Character();
$katil->name = 'Albert Fish';

$katil->attack('machineGun', $hedef);
$katil->attack('revolver', $hedef);

Ekranımızda aşağıdakiler yazı.

'Emma Richardson' makineli silah ile vuruldu
'Emma Richardson' tabanca ile vuruldu

Yukarıdaki örnekte iki tane Character sınıfından örnekleme yaptık bunlardan biri $hedef isimli değişkene, diğerini $katil isimli değişkene atadık. $katil içinde bulunan karakterimiz $hedef içinde bulunan karaktere attack metodu ile saldırıyor ve verdiğimiz silah bilgisi ile hedefe ateş ediyor.

Yukarıdaki örneği prensipler bakımından inceleyelim.

  • attack metoduna bakarsak, switch yapısını fark edebiliriz. Her bir silah için ayrı ayrı case tanımlaması yaptık ki silah türlerini ayırt edebilelim. Bu yüzden her yeni silah için, yeni bir case eklememiz gerekiyor. Bu da open-closed(geliştirmeye açık-değiştirmeye kapalı) prensibine uymayan bir durum. Sisteme ekleyeceğimiz her bir silah için kullanıcı sınıfı olan Character sınıfında değişiklikler yapmamızı gerektirir. Bu yapı da zaman içerisinde uygulamamızı kırılgan bir duruma sokacaktır. (Gerçek hayattaki örnekler çoğunlukla daha karmaşık olur. Bunu aklımızda tutmamızda fayda var.)
  • Character sınıfımız olması gerekenden daha fazla sorumluluğa sahip. Yine attack metoduna bakarsak, sınıfın silah türlerini ve silahlar hakkında bilgiler içerdiğini görebiliriz. Oysa single responsibility(tek sorumluluk) prensibi bize her sınıfım bir tane sorumluğu olması gerektiğini söyler. Ancak biz Character sınıfına silahlar hakkında bilgi ekleyerek sınıfın sorumluluklarına birden ikiye çıkardık. Bu hali ile Character sınıfı hem bir karakteri, hem de silahları temsil ediyor.

Peki, single responsibility ve open-closed prensiplerini bozmadan uygulamamızı nasıl geliştirebiliriz? Bunu cevabı yazımızın konusu olan Strateji tasarım şablonunda.

Strateji tasarım şablonunu uyguladıktan sonra sınıflarımızın son hali aşağıdaki şekilde olacaktır.

Weapon arayüzü

namespace Strategy;
interface Weapon
{
    public function fire(\Strategy\Character $character);
}

MachineGun sınıfı

namespace Strategy;
require_once 'Weapon.php';
use Strategy\Weapon;
class MachineGun implements Weapon
{
    public function fire(\Strategy\Character $character)
    {
        printf("'%s' makineli silah ile vuruldu", $character->name);
    }
}

Revolver sınıfı

namespace Strategy;
require_once 'Weapon.php';
use Strategy\Weapon;
class Revolver implements Weapon
{
    public function fire(\Strategy\Character $character)
    {
        printf("'%s' tabanca ile vuruldu", $character->name);
    }
}

Character sınıfı

namespace Strategy;
require_once 'Weapon.php';
class Character
{
    public $name;

    public function attack(\Strategy\Weapon $weapon, Character $target)
    {
        $weapon->fire($target);
    }
}

Character sınıfındaki değişikliklere gelmeden önce isterseniz yeni eklenen sınıflara ve arayüzlere bakalım. Öncelikle Weapon adında yeni bir arayüz(interface) ekledik. Bu arayüzün koşullarını yerine getiren(implement) her bir sınıf Weapon özelliği kazanacaktır. Örneğimizde is Weapon arayüzü kullanan sınıflardan fire metodunu mutlaka barındırmalarını istedik. MachineGun ve Revolver sınıfına bakarsanız bu isteğin karşılık bulduğunu görebilirsiniz.

Character sınıfına gelirsek, oradaki attack metodunda bazı değişikler yaptık. Öncelikle metodun $weapon argümanın başına \Strategy\Weapon eklendiğini fark etmişsinizdir. Bunu ekleyerek $weapon argümanı için gönderilen içeriğin mutlaka Weapon arayüzüne sahip olmasını istedik. (Gönderilen içerik Weapon arayüzüne sahip değilse PHP fatal error verecektir.) Diğer yandan yaptığımız tanımlama ile $weapon için gönderilen sınıfın hangi metotları ile iletişim kuracağımızı kabul etmiş sayıldık. Biz, bundan sonra sadece Weapon arayüzünde tanımlı olan metotları attack metodunda kullanacağız. Yani bu örnekte sadece fire metodunu kullanacağız. Çünkü Weapon arayüzünde sadece o tanımlı. Burada şunu belirtmekte fayda var. Arayüz dışındaki metotlara da erişebiliriz ama bu önerilen bir yöntem değildir. Çünkü arayüzde bulunmayan metotların olup olmadığı veya nasıl çalıştığının bir garantisi yok. Oysa arayüz içinde bulunan metotlarda, bu garanti arayüz tarafından sağlanıyor.

Ayrıcı attack metodun içinde bulunan switch yapısını tamamen kaldırdık. Bunun yerine Weapon arayüzünün fire metodunu kullanarak hedefe ateş ediyoruz.

Character sınıfında yaptığımız son değişiklikler sayesinde single responsibility prensibini artık ihlal etmiyoruz. Çünkü Character sınıfının silah sorumluğunu ondan alıp Weapon arayüzü üzerinden MachineGun ve Revolver sınıfına devrettik. Character sınıfın şu anda tek bir sorumluluğu var o da; karaktere ait bilgileri ihtiva etmek.

Son yaptığımız değişiklikler ile beraber kodumuzu çalıştıralım.

require_once 'Character.php';
require_once 'MachineGun.php';
require_once 'Revolver.php';

$hedef = new \Strategy\Character();
$hedef->name = 'Emma Richardson';

$katil = new \Strategy\Character();
$katil->name = 'Albert Fish';

$machineGun = new \Strategy\MachineGun();
$revolver = new \Strategy\Revolver();

$katil->attack($machineGun, $hedef);
$katil->attack($revolver, $hedef);

Çıktımız

'Emma Richardson' makineli silah ile vuruldu
'Emma Richardson' tabanca ile vuruldu

Her şey yolunda gözüküyor. Yukarıda bahsettiğim open-closed prensibine kodumuz uyuyor mu peki? Bunu yeni bir silah ekleyerek test edebiliriz. Bu silah da sniper olsun.

Sniper sınıfı

namespace Strategy;
require_once 'Weapon.php';
use Strategy\Weapon;
class Sniper implements Weapon
{
    public function fire(\Strategy\Character $character)
    {
        printf("'%s' sniper ile vuruldu", $character->name);
    }
}

Yeni eklediğimiz Sniper sınıfı ile beraber tüm silahları kullanarak hedefimize saldıralım.

require_once 'Character.php'; 
require_once 'MachineGun.php'; 
require_once 'Revolver.php'; 
require_once 'Sniper.php'; 
$hedef = new \Strategy\Character(); 
$hedef->name = 'Emma Richardson';

$katil = new \Strategy\Character();
$katil->name = 'Albert Fish';

$machineGun = new \Strategy\MachineGun();
$revolver = new \Strategy\Revolver();
$sniper = new \Strategy\Sniper();

$katil->attack($machineGun, $hedef);
$katil->attack($revolver, $hedef);
$katil->attack($sniper, $hedef);

Çıktı

'Emma Richardson' makineli silah ile vuruldu
'Emma Richardson' tabanca ile vuruldu
'Emma Richardson' sniper ile vuruldu

Evet! Strateji tasarım şablonu sayesinde kullanıcı(Character) sınıfımızda herhangi bir değişiklik yapmadan uygulamamıza kolayca yeni bir silah ekledik. (Değiştirme yapmadan geliştirme yaptık.) Open-closed prensip ihlalini de bu sayede ortadan kaldırdık.

Örneğimizi Strateji tasarım şablonu çerçevesinde incelersek;

  • Weapon arayüzüne sahip olan her bir sınıf birer stratejidir.
  • Her bir strateji kendine has algoritmalara sahiptir. Bu örnek için Revolver tek tek atış ederken, MachineGun arka arkaya ateş ettiğini düşünebiliriz.
  • Stratejimiz değiştiğinde, uygulamamızın davranışları da değişecektir. Bu da strateji tasarım şablonunu davranışsal tasarım şablonu(behavioral design pattern) yapmaktadır. Kullandığımız örnekte her bir silahın kendine has atışı olduğuna göre uygulamamız aynı amaç için birden fazla ve birbirinden farklı davranışlara sahip olmuş demektir.

Sonuç

Geliştirdiğimiz uygulamada bir amacı(yukarıdaki örnekte attack) birden fazla yöntem(MachineGun, Revolver…) kullanarak uygulamamıza farklı davranışlar kazandırmak istiyorsak veya sınıfların birbiri hakkında daha az bilgiye sahip olmasını istiyorsak Strateji Tasarım Şablonunu kullanabiliriz.

Bu yazımda kullandığım örneğe buradan ulaşabilirsiniz.