Yazılım Mimarisini Öğrenmek
(matklad.github.io)- Yazılım tasarımı, derslerden çok gerçek projelerde sorumluluk alındığında ve sorunlar kişinin kendi işi hâline geldiğinde daha derin öğrenilir
- Conway Yasası, yazılımın organizasyonun sosyal yapısını tekrar ettiği görüşüdür; bilimsel kod ile endüstriyel kod arasındaki fark da teşviklerden kaynaklanabilir
- rust-analyzer; hızlı derleme, stable desteği, C bağımlılığının olmaması ve birkaç saniyelik testleriyle yüksek verimli katkıcıların odaklanmasını kolaylaştırır
- rust-analyzer, bağımsız özellikleri
catch_unwindile korudu ve PR çıtasını düşürdü; ancak çekirdek spine için çok daha katı kalite standartları uyguladı - Deneysel yapı uzun vadeli gerçeğe dönüşebilir; rust-analyzer da LSP mimarisi için bir prototip olarak başlayıp bir derleyiciyi daha sürdürme sonucuna vardı
Yazılım tasarımı en iyi sahada öğrenilir
- Yazılım tasarımı, resmî derslerden ziyade gerçek projelerde sorumluluk alıp sorunları doğrudan çözerken daha iyi öğrenilir
- Üniversitedeki tasarım dersleri ve ders projelerinde “mimar” rolünü üstlenmekten çok, ikinci gerçek proje olan IntelliJ Rust üzerinde tasarım sorunları kişinin kendi meselesi hâline gelince öğrenme asıl o zaman başladı
- IntelliJ Rust’ta bazı hatalar yapıldı, ancak bunlar ölümcül değildi ve süreç içinde çok şey öğrenilebildi
- Yazılım mühendisliği, meraklı birinin ilkeler üzerinden düşünüp çeşitli yazılar okuyarak öğrenebileceği kadar basit yönler de taşır
Teşvik yapıları ve Conway Yasası
- Conway Yasası, yazılımın onu üreten organizasyonun sosyal yapısını tekrar ettiği görüşüdür
- Endüstriyel yazılım ile bilimsel kod arasındaki fark, yazılım inşa etme bilgisinin kendisinden çok, insanları yazılım üretmeye yönelten teşvik yapılarından kaynaklanıyor olabilir
- “3 ay içinde makale yayımlamak zorunda olan bir doktora öğrencisi” gibi durumlar, bilimsel kodun biçimini belirleyen önemli etkenlerden biri olabilir
- Teşvik yapılarına genel olarak iki şekilde karşılık verilebilir
-
Projenin teşviklerini tasarlamak veya yönlendirmek
- Bir projenin teşvik yapısını tasarlama ya da ayarlama fırsatı nadirdir, ama böyle bir fırsat doğduğunda etkisi büyüktür
- TIGER_STYLE içindeki asıl nokta, kural listesinin kendisinden çok bu kuralları iyi tercihlere dönüştüren sosyal bağlamdır
-
Değiştiremiyorsan kısıtlara uyum sağlamak
- Teşvik yapıları neredeyse hiçbir zaman istenildiği gibi verilmez; değiştirilemiyorsa o yapıya uyum sağlamak gerekir
- Endüstriyel yazılım projelerinde de “doğru yapmaya yetecek zaman” neredeyse hiç olmaz; eldeki kısıtlar içinde mümkün olanın en iyisini yapmak gerekir
rust-analyzer'da yapıyı katılımcılarla eşleştirme biçimi
- rust-analyzer, hem derinliği hem genişliği olan bir projedir
- Derin tarafta, bir derleyici olmasının da etkisiyle olağanüstü ve adanmış katkıcıları çekebilir
- Geniş tarafta ise klasik IDE’lerin amaca özel çok sayıda özelliği bulunduğundan, Rust öğrenenler ya da düzenli katkı sunması zor olan hafta sonu katkıcıları için kendi sıkıntılarını gidermek adına bir iki saat harcamaya uygundur
- rust-analyzer’ın
rustcderlemesi gerektirmemesi, stable üzerinde derlenmesi, C bağımlılığı taşımaması ve tüm test paketinin birkaç saniye içinde tamamlanması konusundaki ısrarının nedeni, yüksek verimli katkıcıları çekmekti - Derleme sistemi, insanların başka şeylerle uğraşmak zorunda kalmadan borrow checker üzerinde çalışmaya odaklanabilmesi için cilalandı
- Hafta sonu katkıcılarını çekmek için rust-analyzer’ın iç yapısı birçok bağımsız özelliğe bölündü ve her özellik çalışma anında
catch_unwindile korundu - Özellik PR’leri için çıta, “happy path çalışıyor ve testi var” seviyesine indirildi; ilgili kod çökse bile bunun kabul edilebilir olduğu düşünüldü
- Ancak iki koşul vardı
- Kalite sorunları tekil özelliğin içinde izole kalmalı ve diğer bölümlere yayılmamalıydı
- Çalışma anındaki çökmeler kullanıcıya görünmemeliydi; bunun için rust-analyzer özellikleri değişmez snapshot’lar üzerinde çalışmalı ve veriyi kirletememeliydi
- Buna karşılık, özellikleri taşıyan çekirdek spine için çok daha katı kalite standartları uygulandı
Deneysel yapının uzun vadeli gerçeğe dönüşme riski
- Teşvik yapısını düzeltmek yerine ona uyum sağlandığında, geleceğin belirsiz olduğu ve çoğu zaman en rahatsız edici biçimde gerçeğe dönüşebileceği akılda tutulmalıdır
- rust-analyzer’ın başlangıçtaki motivasyonu, IntelliJ Rust içinde ikinci bir paralel derleyici yazmaktan kaçınmak ve LSP için daha iyi bir mimariyi bir prototip üzerinden doğrulayarak elde edilen dersleri
rustcye geri taşımaktı - Bu yüzden çekirdek kısmı da dahil olmak üzere kod son derece deneyseldi
- Sonuçta bir derleyiciyi daha sürdürmek zorunda kalındı
- Benzer şekilde uutils projesi de Rust öğrenenler için başlıca hedeflerden biri olarak başlayıp Ubuntu’nun coreutils uygulaması hâline geldi
Faydalı kaynaklar ve kitaplar
- Tüm doğru cevapları içeren tek bir kitap yok; pratik deneyim vazgeçilmez görünüyor
- Boundaries by Gary Bernhardt
- Somut tavsiyeleri çok sağlam ve daha üst düzey araştırmaları tetikleyen bir kaynak
- How to Test
- Testin önemini hemen anlamıştım; ancak yaygın biçimde alıntılanan birçok test tavsiyesinin pratikte işe yaramadığını kabul etmek ve gerçekten çalışan yaklaşımı kavramsallaştırmak uzun zaman aldı
- ∅MQ guide ve Pieter Hintjens’in yazıları
- Conway Yasası tarzı düşünceyle tanışmamı sağlayan kaynaklardı
- rust-analyzer’ın özellik geliştirme mimarisi, optimistic merging yaklaşımının uygulanmış bir biçimidir
- Reflections on a decade of coding by Jamii
- Oldukça meta bir içeriğe sahip ve bağlantı derlemesinin ilk maddesi olacak kadar iyi
- Ted Kaminski blogu
- Var olmayan bir kitap için notlar biçiminde yazılmış; yazılım geliştirme üzerine tutarlı bir kurama en çok yaklaşan kaynaklardan biri
- Software Engineering at Google ve Ousterhout’un The Philosophy of Software Design kitabı
- Sık önerilen iyi kitaplar; özellikle Software Engineering at Google, unit test ve integration test için önemli adlandırmaları toparlamaya yardımcı oldu
- Ancak kişisel olarak çığır açıcı kitaplar değillerdi
1 yorum
Hacker News yorumları
Bunu bir kopya kağıdı olarak özetlersek, iyi tasarım tek bir fikrin bütüne nüfuz ettiği ve sürprizi en aza indirdiği bir yönde olmalı
Sistem izin veriyorsa insanlar eninde sonunda onu öyle kullanır ve “herkes sadece X yapsa” diye başlayan çözümler çözüm değildir
Veriyi dönüştüren kısımla kullanan kısmı ayırın; veri modeli koddan daha uzun ömürlüdür ve bağlılık birçok sorunun köküdür
Versiyonlama kaçınılmazdır, durum açıkça görünür olmalıdır ve her bilgi için tek bir doğruluk kaynağı bulunmalıdır
İsimlendirmeye daha fazla zaman ayırın; test etmesi zorsa tasarım yanlıştır ve belgelenmemiş kararlar sonradan pişmanlık yaratır
İletişim bir maliyettir, bu yüzden ödemeden önce gerekçelendirilmelidir; mühendisin işi ise eksik bilgi içinde sezgisel kurallarla problem çözmektir
Yazının kendisi de yazılım mimarisi bakış açısından pek tutarlı değildi
4+1 architecture view, UML kısmını çıkarırsak, büyük resmi düşünmek için iyi bir kavramsal çerçeve; Pattern-Oriented Software Architecture serisi de insanların vardığı çeşitli mimarileri iyi sınıflandırıyor
Grady Booch bir dönem software architecture handbook hazırlıyordu ama şimdi neredeyse durmuş gibi; o zamanlar mailing listede şirketlerin ya da büyük açık kaynak projelerinin büyük sistem mimarileri belgelenirdi
Bu tür kaynaklara inerseniz, mimarilerin ölçek, güvenlik, performans, birlikte çalışabilirlik, fail-safe gibi farklı odaklara göre şekillendiğini ve her hedefin gerçekçi trade-off'ları olduğunu görebilirsiniz
Bu ölçüte göre daha iyiyse, kötü tasarım gibi görünse bile aslında iyi tasarımdır
Arayüzler doğru kullanımı kolay, yanlış kullanımı zor hale getirmeli ve projeyi bilmeyen birinin nasıl kullanacağını düşünmelisiniz
Doğru kod yazması kolay olmalı, şüpheli kod göze çarpmalı ve bug'lar olabildiğince sola kaydırılmalıdır
Tek bir bug'ı düzeltmektense bir bug sınıfını ortadan kaldırmak daha iyidir; arayüzü değiştirmek implementasyondan daha zordur, bu yüzden arayüz doğruysa çirkin bir implementasyon da kabul edilebilir
Yorumlar ve dokümantasyon kodun neden o biçimde olduğunu açıklamalıdır; dışarıdan daha basit görünen bir yöntem varsa ama bazı kısıtlar yüzünden kullanılamıyorsa bu da yazılmalıdır
Veri açısından bakıldığında tekrar etmemek gerekir; aynı gerçeği birden fazla yerde saklarsanız sonunda tutarsızlık ve bug oluşur
İyi döşenmiş yoldan çıkmanın bir maliyeti vardır; gerçekten değerliyse yapılabilir ama bu maliyet küçümsenmemelidir
Daha kötü görünen sıkıcı teknoloji çoğu zaman daha iyi teknolojidir ve beklenen değeri “buna değer mi?” diye değil, “başka bir şey yapmakla kıyaslandığında buna değer mi?” diye hesaplamak gerekir
Kendinizi başkalarından daha zeki sansanız bile sadece zeka ile çözülemeyen problemler vardır; bazı problemler de gerçekten patlamadan fark edilemez, bu yüzden başkalarının hatalarından öğrenmek gerekir
Sürtünme sessiz bir katildir
Plan yapmak güzeldir ama bazen bizzat denemek gerekir ve her şeyin bir maliyeti vardır
Maliyeti hesaba katmadan tasarlarsanız sonra zor seçimlere mecbur kalırsınız
Tek başına yapılan bir projede bile engine'in kısıtları, “test sırasında ortaya çıkan garip yeni özelliği bu şekilde ekle” diyen bir rehber oluyor
Böylece “belirli bir durum geçişinde birkaç kez çalışan yeni bir ses efekti yapmak için şunu yap” gibi devasa bir belgeyi sürekli elde tutmak gerekmiyor
Sistem tasarımcısı sektörü anlamalıdır; onun terminolojisini ve modelleme alışkanlıklarını tamamen benimsemek zorunda değildir ama veri setlerine neden ve hangi açıdan baktıklarını anlamalıdır
Sağlık pazarının karmaşıklığını kasıtlı olarak basitleştirip gereksiz aşırı tanımlamaları kaldırarak daha birleşik bir model sunduğumuz yerler oldu ama bu tür değişiklikleri ancak problem alanını yeterince anladığımız için güvenle yapabildik
Özellikle isimler neredeyse hiç ölmez
Bazen ölürler ama bir adı değiştirmek aşırı çaba gerektirir; bu yüzden alan uzmanlarının isim önerilerini uzun süre gözden geçirip eksik bir şey olup olmadığını kontrol etmesine zaman ayırmak gerçekten çok değerlidir
Bazı kavramlar dayatılabilir ama satış/pazarlama gibi iş tarafı sürekli sektör terminolojisini talep eder ve modelin mevcut sektör bakışına uymasını ister
Bu akışı kırmaya karar verdiyseniz, o kopuşun niyeti ve amacı çok net olmalıdır
Yazılımda en çok vurgulanması gereken özellik bakım yapılabilirliktir
Yapmanın ne kadara mal olduğu önemlidir ama çalıştırmanın maliyeti; sadece altyapıyı değil biriken özellik isteklerini, kod refactoring'ini ve üçüncü taraf yazılım sürümlerini güncel tutmayı da kapsadığı için çok daha büyük etki yaratır
Öneri listesi, Ousterhout'un A Philosophy of Software Design kitabında olduğu gibi, çoğu zaman iyidir ama genel olarak yazılım mimarisinin kendisinden çok genel yazılım geliştirme ilkelerine yakındır
Mimariyi görmek istiyorsanız Shaw/Garlan'ın Software Architecture: Perspectives on an Emerging Discipline gibi klasiklerini ve Mary Shaw'ın yazılarını tavsiye ederim
Yazılım mimarisi alanının neden beklendiği gibi ilerlemediğini inceleyen Myths and Mythconceptions: What Does It Mean to Be a Programming Language, Anyhow? ya da Revisiting Abstractions for Software Architecture and Tools to Support Them gibi daha yeni makaleler de iyidir
Pratik tarafta Unix pipe and filter ile REST'in neden başarılı olduğunu ve nerede, neden çöktüğünü incelemek faydalı olur; hexagonal architecture da temeldir
Kişisel olarak, yazılım mimarisiyle metaobject protocol'ü ilişkilendirip bunu programlama dilleri ve programlama için yeni bir temel olarak görmeye çalışan Beyond Procedure Calls as Component Glue: Connectors Deserve Metaclass Status da var
Bu, Mary Shaw'ın Procedure Calls Are the Assembly Language of Software Interconnection: Connectors Deserve First-Class Status metnine bir yanıt; eğer prosedür çağrıları assembly diliyse, yüksek seviyeli dil nasıl görünürdü diye soruyor
Belki de yazılım mimarisinin daha parlak ve daha pratik bir geleceği vardır
Birkaç veri yapısı ve tip ile küçük bir temel fonksiyon kümeniz varsa, bunları birleştirirsiniz
Lisp'te sevdiğim şeylerden biri, daha karmaşık tiplerin, özellikle FFI'den gelenlerin, her zaman opak olmasıdır
C benzeri bir dilde struct tanımladığınızda standart bir fonksiyon kümesi veren bir CLOS implementasyonu görmek isterdim
Mimari öğrenmenin en iyi yolu yeterince büyük bir proje yapmak değil, onu bakımını yapmaktır
Üstelik bunu en az iki ya da üç projede yapmanız gerekir
Proje çok küçükse her mimari işe yarar ve “büyük” projeyi satır sayısından çok, üzerinde çalışmış insan sayısı, daha iyisi takım sayısı belirler
Karşılaştırma yapabilmek için en az iki farklı proje gerekir; ayrıca onlarca yıl tek bir projeye gömülüp modern problem çözme yollarını bilmeyen insanlar da gördüm
Ama pratikte projeyi yapan kişinin terfi edip mimar olması, bakımını yapan kişinin olması ise daha nadirdir
Google'da bu özellikle belirgindir; terfi için yeni bir şey çıkarmak gerekir, bakım yapmak terfi getirmez ve mümkünse lansmandan hemen sonra projeden çıkmak daha avantajlıdır
Paradoksal biçimde, mimar olmaya en uygun kişi, şirket içinde kimsenin almak istemediği mevcut projelerin bakımına verilen dış yüklenici olabilir
Bunlar mimariyi sürdürmek zorundadır ve birçok proje gördükleri için karşılaştırma yapabilirler
Tabii saatlik ücret alıyorlarsa daha fazla fatura kesmek için mimariyi gereksiz yere karmaşıklaştırma riski de vardır
Bu bağlamda Architecture of Open Source Applications'ı gerçekten tavsiye ederim
Her bölümün ilgili projenin bakımcısı tarafından yazıldığı bir kitap serisi, dolayısıyla mimariyi örnekler üzerinden öğrenebiliyorsunuz
Sadece mimarinin ne olduğunu değil, onu doğuran kısıtları, çoğu zaman tarihi ve değişen proje vizyonunu da görüyorsunuz
Çok yazarlı kitapların sınırlamaları yüzünden tüm bölümler aynı derecede iyi ya da ilginç değil ve hepsi eski, ama yine de okunmaya değer
http://aosabook.org/
Üzerinde çalıştığım projenin zihinsel modelini daha iyi kurmaya zaman ayırmak istiyorum ama programlama dili ya da belirli mimari seçimler yüzünden, hatta zaman ayırmaya değmeyecek kadar karmaşıklaşmış kısımlar nedeniyle nefret etmeye başlayınca motivasyonum çok düşüyor
Projeye göre değişir ama “full-stack developer” olarak çalışmak programlamanın keyfini kaçırıyor gibi geliyor
Zaten haftada 40 saatimi hayal edilebilecek en sıkıcı projeye bakarak geçiriyorum
Kusursuz proje diye bir şey yok
Ve eğer programlama dili bu kadar büyük bir sorunsa, gemiyi değiştirmek daha iyi olabilir
Herkesin birden fazla dille çalışabilmesi gerektiğini düşünüyorum ama nihayetinde seçim senin
En çok zaman harcadığınız kararın gerçekten en önemli karar olduğundan emin olmalısınız
İyi tasarlanmış veri yapıları; framework, dil ve platformdan çok performans ve bakım yapılabilirlik üzerinde daha büyük etkiye sahiptir
Kişisel olarak her gün ADHD ile çalıştığım için ilerlemeyi sürdürmek adına kendimi itmem gerekiyor; bu da önemsiz kararları seçip kapatarak dikkatli düşünme gerektiren kalan problem alanına odaklanmak anlamına geliyor
“Clean code” ya da “beautiful code” gibi ifadeler, junior'ların yazılım mimarisi iyi uygulamalarını öğrenmesine pek yardımcı olmuyor
Bir junior neden ORM kullandığımızı sorduğunda senior'ın “daha temiz olduğu için” diye cevap vermesi geride sadece bir soru işareti bırakır
Bunun yerine net bir hedef listesi tanımlamak daha iyidir
Bakım yapılabilirlik, performans ve ölçeklenebilirlik, verimlilik, dayanıklılık, gözlemlenebilirlik, test edilebilirlik ve test edilmiş olma, güvenlik, yeni bir geliştiricinin kolayca okuyabilmesi gibi ölçütler birbirini dengeler
Ölçüt sayısı arttıkça kararsız kalındığında daha iyi seçim yapmak kolaylaşır ve bunlar geliştirme ekibi dışındakiler için de anlamlıdır; böylece müşteriyle neye para ödendiği konusunda uzlaşılabilir
Projeler ömrünün çoğunu bakım modunda geçirir; bu da projenin başarılı olduğu anlamına gelen iyi bir şeydir, dolayısıyla bakım yapılabilirlik de tanımlanabilir
Yeni bir özelliği mimariyi bozmadan, hatta mümkünse tek bir method signature'ı bile bozmadan ekleyebilme yeteneği iyi bir başlangıç noktasıdır
Soyutlamalara karşı çok dikkatli olmak gerekir
“Soyutlamalar çoğu zaman istediğiniz şeyin ne kadar basit olduğunu gizler” sözü doğrudur ve ORM bunun tam örneğidir
Çoğu durumda veriye birinci sınıf vatandaş gibi davranılmalıdır; bu, DBA'lerle işbirliğini de iyileştirir
Erken optimizasyona düşmeden mutlu yolun dışını da düşünmek zordur ama bu, artı ve eksilere bakmadan iyi fikir gibi görünen bir implementasyona dalmayı önler
Kodumu ele alacak kişinin çok kötü bir gün geçirdiğini hayal etmek, onu okumayı keyifli hale getirmeme yardımcı oluyor
Oraya buraya bırakılmış yorumlar, çıkarılabilecek olsa bile bırakılan yerel değişkenler ve değişken adları buna dahildir
Framework'ler dikkatle seçilmelidir; iyi bir hizmetkâr ama kötü bir efendidir
“Frameworker değil, engineer olun” sözü burada yerini buluyor
Güçlü görüşlerin kendisine karşı değilim; hatta library ya da tool için mükemmel bir özellik olabilir
Böyle bir library ya da tool, kendi alanında muhtemelen ciddi bir alan uzmanlığı taşıyordur
Ama framework dünyasında güçlü görüşler kolayca “elinde çekiç varsa her şey çivi görünür” noktasına kayabilir
Her zaman böyle olmaz ve her zaman sorun da yaratmaz ama bir alanın ortodoksisini geniş ölçekte uyguladığınızda, onun gerekçesi alanın kendisine özgüyken daha geniş bağlamda kırılma riski doğar
Bu yüzden başka ORM'lerin ya da persistence integration katmanlarının takılabildiği, router, validator ve probleme uymayan başka bileşenlerin değiştirilebildiği modüler framework'leri tercih ederim
Framework ekosistemi içinde birden fazla paradigma için alternatifler varsa bu özellikle değerlidir
Çünkü o zaman neredeyse uyan hazır bir aracı bulup kusurları net olan ve gerektiğinde telafi edilebilen bir seçeneği alabilirsiniz
Bakım yapılabilirlik için NIH sendromuyla mücadele etmek çok önemlidir
Bu, kaynakları şaşırtıcı bir hızla tüketen sürekli bir risktir
Aynı zamanda bazı bileşenler doğrudan ayarlandığında ya da tamamen sahiplenildiğinde büyük fayda sağlayabilir; zor olan da hangisinin hangi tarafta kaldığını doğru değerlendirmektir
Bakım yapılabilirliği listenin başına koymana güçlü biçimde katılıyorum
Sistem mühendisliği açısından bakıldığında, yazılım mimarisi tesisat tasarımı gibidir
Çok önemlidir ama insanlar tesisatın içinde değil, tesisatı olan evde yaşar
Tesisat, evin geri kalanını hesaba katmazsa sonradan düzeltmesi çok pahalı olabilir
Güzel yazı
“Yazılım mimarisini öğrenmek”, tek bir doğru cevap olmadığını anlamaktır
Bu hem sanattır hem bilim
Okuma önerisi olarak Simplify IT - The art and science towards simpler IT solution'ı tavsiye ederim
https://nocomplexity.com/documents/reports/SimplifyIT.pdf
Gary Bernhardt konuşmaları gerçekten özeldir
İçlerinde başka ilginç yerlere götürebilecek çok sayıda fikir var