Clean Architecture: Craftsman's Guide Kitap Özeti

Clean Architecture: Craftsman's Guide

1 kaynak

Bu pasajlar, yazılım geliştiricisi Robert C. Martin'in temiz yazılım mimarisi üzerine yazdığı bir kitaptan alıntılardır. Kitap, mimari ve tasarım arasındaki ayrımı netleştirmeyi, SOLID prensipleri gibi temel tasarım ilkelerini açıklamayı ve bağımlılıkların yönetilmesinin önemini vurgulamayı amaçlamaktadır. Yazar, tarihsel örnekler ve kişisel deneyimlerinden yola çıkarak, iyi bir mimarinin yazılımın yaşam döngüsünü nasıl desteklediğini ve seçenekleri mümkün olduğunca açık tutarak geliştirme, dağıtım ve bakım maliyetlerini nasıl azalttığını ele almaktadır. Metin, hizmetlerin kendi başlarına bir mimari tanımlamadığını, bunun yerine bileşenler arasındaki sınırların mimariyi oluşturduğunu ve eski sistemlerdeki donanım ve iş kurallarının ayrıştırılmasının önemini tartışmaktadır., kavramlar ve çıkarılan derslerin bir özetini sunmaktadır. 50 yılı aşkın kod yazma deneyimine sahip yazarın bakış açısıyla, yazılım sistemlerinin yapısını ve tasarımını ele alarak uzun ömürlü, test edilebilir ve sürdürülebilir mimariler oluşturmanın önemini vurgulamaktadır. Kitap, yazılım tasarımının temel ilkelerini (SOLID), bileşen ilkelerini ve çeşitli mimari sınırları ve detayları kapsayan geniş bir konu yelpazesini incelemektedir.



Ana Temalar ve Önemli Fikirler:


Tasarım ve Mimari Nedir?

Mimarlığın birincil hedefi, bir sistemin yaşam döngüsü maliyetini maksimize etmek ve dolayısıyla geliştirme çabasını minimize etmektir. Mimari kararlar, geliştirme kolaylığını ve bakım maliyetini doğrudan etkiler.

"İyi bir mimar, yapılmayan karar sayısını en üst düzeye çıkarır." Mümkün olduğu sürece ve mümkün olduğunca çok seçeneği açık bırakarak kararları ertelemek çok önemlidir. Bu, esnekliğin ve adaptasyonun anahtarıdır. (sf. 142)

Mimarlık, davranıştan daha değerlidir. "Mimarlık, bir sistemin şeklini oluşturan şeydir ve o şekil, sistemin yaşam döngüsü maliyetini belirleyen şeydir." (sf. 14-15) Mimarlık, yazılımın değişim maliyetini belirler.

İki Değerin Hikayesi:

Yazılım sistemleri iki ana değere hizmet eder: davranış (işlevsellik) ve mimari (yapı).

Davranış, kullanıcı ve paydaşların doğrudan deneyimlediği şeydir. Mimari ise geliştiriciler için daha değerlidir çünkü yazılımın yaşam döngüsünü sürdürmeyi, değiştirmeyi ve genişletmeyi mümkün kılar.

"Mimarlık, bir sistemin yaşam döngüsü maliyetini oluşturan şeydir." İyi bir mimari, başlangıçta ek çaba gerektirse bile uzun vadede maliyetleri düşürür.

Yapısal Programlama:

Dijkstra'nın katkısı, goto ifadesinin eliminasyonu ve bunun yerine if/then/else ve do/while/until gibi kısıtlı kontrol yapılarını kullanmanın önemiydi. Bu yapısal programlamanın temelini oluşturdu. (sf. 27)

Yapısal programlama, modüllerin kanıtlanabilir birimlere özyinelemeli olarak ayrıştırılmasını ve dolayısıyla fonksiyonel ayrıştırmayı mümkün kılar. (sf. 29)

Testler, bir programın doğru değil, hatalı olduğunu gösterir. Yeterli test çabasından sonra, bir programı amaçlarımız için yeterince doğru kabul edebiliriz. (sf. 31)

Nesne Yönelimli Programlama (OO):

OO'nun üç temel kavramı kapsülleme, kalıtım ve çok biçimliliktir.

C'de tam kapsülleme mümkündür; istemci, veri yapısının veya fonksiyonların uygulamasından tamamen habersizdir. (sf. 35) C++'ta ise istemci hala üye değişkenlerin varlığını bilir, bu da kapsüllemeyi kırar. (sf. 37)

Kalıtım, bir veri yapısının, üyelerin sırasını koruyarak başka bir veri yapısının saf bir üst kümesi gibi davranabilmesidir. C'de bu, alanların sırasını koruyarak taklit edilebilir. (sf. 39)

Çok biçimlilik, özellikle fonksiyon işaretçileri aracılığıyla eski dillerde mevcuttu. UNIX'teki IO aygıt sürücüleri örneği (FILE veri yapısı), OO'daki çok biçimliliğin temelini oluşturan basit numarayı gösterir. (sf. 41-42)

Fonksiyonel Programlama (FP):

FP, mutasyonel durumdan kaçınarak veya mutasyonel durumu çok disiplinli bir şekilde ele alarak çalışır. (sf. 49)

FP'de genellikle değişmezlik kullanılır. Bu, veri yapılarının oluşturulduktan sonra değiştirilememesi anlamına gelir. Bir veri yapısını "değiştirmek" istediğinizde, aslında yeni bir veri yapısı oluşturup orijinal verileri ve yeni verileri yeni yapıya eklersiniz. (sf. 52)

Mutasyonel durumun idare edilmesi, compare-and-swap gibi algoritmalarla disiplinli bir şekilde yapılabilir (Clojure'deki atomlar ve swap! fonksiyonu örneği). (sf. 53-54)

SOLID Prensipleri:

SRP (Tek Sorumluluk Prensibi): "Bir modül bir ve yalnızca bir aktöre karşı sorumlu olmalıdır." Bir modül, kaynak dosyası veya işlevler ve veri yapılarından oluşan tutarlı bir küme olabilir. Tutarlılık, tek bir aktöre karşı sorumlu olan kodu birbirine bağlayan güçtür. (sf. 62-63)

OCP (Açık/Kapalı Prensibi): "Bir yazılım varlığı (sınıflar, modüller, fonksiyonlar, vb.) genişletmeye açık olmalı, ancak değiştirmeye kapalı olmalıdır." Bu, yeni davranış eklemek için mevcut kodu değiştirmeden mümkün olması gerektiği anlamına gelir. (sf. 71)

LSP (Liskov İkame Prensibi): "S türünden bir nesne kullanılan her yerde, T türünden bir nesne ile değiştirilebilir olmalı, ancak programın doğruluğu bozulmamalıdır." Bu, türetilmiş sınıfların temel sınıflarının davranışını değiştirmemesi gerektiği anlamına gelir. (sf. 78) Örnek olarak, farklı API'lara sahip taksi şirketlerini işleyen bir sistemdeki LSP ihlali ele alınır. (sf. 80-82)

ISP (Arayüz Ayırma Prensibi): "İstemciler asla kullanmadıkları arayüzlere bağlı olmaya zorlanmamalıdır." Büyük, "şişman" arayüzler yerine küçük, özelleştirilmiş arayüzler kullanmak daha iyidir. (sf. 83-84)

DIP (Bağımlılık Ters Çevirme Prensibi): "Üst seviye modüller alt seviye modüllere bağlı olmamalıdır. Her ikisi de soyutlamalara bağlı olmalıdır. Soyutlamalar detaylara bağlı olmamalıdır. Detaylar soyutlamalara bağlı olmalıdır." (sf. 87) Bu, üst seviye iş kurallarının alt seviye uygulama detaylarına bağlı olmaması gerektiği anlamına gelir.

Bileşen Prensipleri:

Bileşenler, dağıtım birimleridir. Sistemlerin bir parçası olarak dağıtılabilen en küçük varlıklardır (jar, gem, DLL dosyaları, vb.). (sf. 96) İyi tasarlanmış bileşenler, bağımsız olarak dağıtılabilir ve dolayısıyla bağımsız olarak geliştirilebilir kalma yeteneğini korur.

REP (Yeniden Kullanım/Yayın Eşdeğerliği Prensibi): "Yeniden kullanımın tanecikliği, yayınlanmanın tanecikliğidir." Bir bileşen, bir bütün olarak yayınlanmayan ve izlenen sürüm numarasıyla kullanılamayan herhangi bir şey kadar yeniden kullanılabilir. (sf. 104)

CCP (Ortak Kapanım Prensibi): "Bir bileşendeki sınıflar, aynı türde değişikliklere karşı ortaklaşa kapalı olmalıdır. Bir bileşendeki sınıflar, bir tür değişikliğin tek bir bileşen içinde kalmasını sağlamak için bir araya toplanmalıdır." SRP'nin bileşenler için bir versiyonudur. (sf. 106)

CRP (Ortak Yeniden Kullanım Prensibi): "Bir bileşendeki sınıflar, birlikte yeniden kullanılmadıkları sürece birlikte paketlenmemelidir." Bu, bir bileşendeki sınıfların, o bileşenin tüm istemcilerinin tüm sınıflarına bağlı olması gerektiği anlamına gelir. (sf. 107)

ADP (Döngüsüz Bağımlılıklar Prensibi): Bileşenlerin bağımlılık grafiği döngüsüz olmalıdır. Bağımlılık döngüleri, bileşenlerin yayınlanmasını ve dağıtılmasını zorlaştırır. (sf. 112-117)

SDP (Kararlı Bağımlılıklar Prensibi): "Bir bileşenin bağımlılıkları, o bileşenin kararlılığı yönünde hareket etmelidir." Daha kararlı bileşenler, daha az kararlı bileşenlere bağlı olmalıdır. (sf. 118) Kararlılık, bir bileşene giren ve çıkan bağımlılıkların sayısıyla ölçülebilir. (sf. 122-123) I metriği (Kararsızlık), Fan-out / (Fan-in + Fan-out) olarak hesaplanır. I=0 tam kararlıdır, I=1 tam kararsızdır. (sf. 123)

SAP (Kararlı Soyutlamalar Prensibi): "Bir bileşenin soyutlanma derecesi, kararlılığı ile orantılı olmalıdır." Daha kararlı bileşenler daha soyut olmalıdır ve daha az kararlı bileşenler daha beton olmalıdır. (sf. 126) Ana Sekans (Anahtar), kararlı ve soyut bileşenler (A=1, I=0) ile kararsız ve somut bileşenler (A=0, I=1) arasındaki ideal ilişkiyi temsil eder. (sf. 127-130)

Sınırlar: Çizgi Çizme:

Mimari sınırlar, sistemi temel iş mantığı ve detaylar (veritabanı, kullanıcı arayüzü, harici servisler, vb.) arasında ayırır.

Hangi çizgileri çizeceğiniz ve ne zaman çizeceğiniz, birincil endişeniz hangi değişiklik türlerine uyum sağlamak istediğinize bağlıdır. (sf. 165)

Detayları (giriş/çıkış, veritabanı) iş kurallarından ayırmak için soyut arayüzler ve bağımlılık ters çevirme kullanılır. İş kuralları arayüzleri tanımlar ve detaylar bu arayüzleri uygular. (sf. 169-170)

Eklenti Mimari: Sistem, iş kurallarından ve onlara bağlı olan eylemcilerden (UI, veritabanı ağ geçitleri vb.) oluşur. İş kuralları, detayların yerine getirmesi gereken arayüzleri tanımlar. Bu, detayların iş kurallarına takılmasına olanak tanır. (sf. 170-171)

Dağıtım Modları:

Mimari sınırlar, farklı dağıtım modları (kaynak seviyesi, konuşlandırılabilir birimler, ayrı süreçler) ile ayrılabilir.

Kaynak Seviyesi Ayrışma: Tek bir işlemci ve tek bir adres alanı içinde fonksiyonların ve verilerin disiplinli bir şekilde ayrılmasıdır. Dağıtım noktasında, bu tek bir yürütülebilir dosya (monolit) anlamına gelir. (sf. 175)

Konuşlandırılabilir Birimler: Bileşenler, jar, DLL veya paylaşılan kitaplıklar gibi bağımsız olarak dağıtılabilir birimlere ayrılır. (sf. 176) Bağımlılık Ters Çevirme (DIP) bu katmanları ayırmak için kullanılır. (sf. 178)

Ayrı Süreçler: Bileşenler, aynı işlemci üzerinde farklı işlemler olarak çalışır ve süreçler arası iletişim (IPC), soketler veya paylaşılan bellek yoluyla iletişim kurar. (sf. 179)

Servisler: Farklı makinelerde farklı işlemlerde çalışan ve ağ üzerinden iletişim kuran bileşenlerdir. (sf. 179) Yazar, servislerin bağımsız olarak konuşlandırılabilir ve bağımsız olarak geliştirilebilir olduğu yanılgısının "Kara Kara Yanılgı" olduğunu iddia eder. (sf. 241) Bunun yerine, bu yeteneklerin iyi tasarlanmış bileşenlerden geldiğini ve servislerin bu bileşenlerin dağıtım modu olduğunu savunur. (sf. 242-243)

Detaylar:

Temiz Mimari'de birçok yaygın teknoloji detaylar olarak ele alınır ve mimari çekirdekten ayrı tutulmalıdır.

Veritabanı Bir Detaydır: Veri modeli önemlidir, ancak veritabanı sistemi (RDBMS, NoSQL, vb.) mimariden bağımsız bir detaydır. İş kuralları, veritabanı mekanizmasına bağlı olmamalıdır. (sf. 277-278) Eğer diskler olmasaydı, veriyi veritabanı veya dosya sistemi yerine bağlantılı listeler, ağaçlar, hash tabloları gibi veri yapıları olarak organize ederdik. (sf. 280-281)

Web Bir Detaydır: Web (HTTP, REST, vb.) bir UI mekanizmasıdır ve iş kurallarından ayrı tutulmalıdır. UI, iş kurallarına bağlı olmalı, iş kuralları UI'ya değil. (sf. 285-288)

Çerçeveler Bir Detaydır: Çerçeveler (Spring, Ruby on Rails, vb.) kullanışlı araçlardır ancak onlarla evlenmekten (yani iş kurallarını bir çerçeveye sıkıca bağlamaktan) kaçınmalıyız. (sf. 291-293) Çerçeveler, iş kurallarından bir mimari sınırın arkasında tutulmalıdır. (sf. 294-295)

Gömülü Mimari:

Temiz gömülü mimari test edilebilir bir gömülü mimaridir. Donanımdan bağımsız olarak test edilebilir olmalıdır. (sf. 262)

Katmanlar: Donanım, Firmware ve Yazılım arasında net bir ayrım olmalıdır. Yazılım katmanı donanım veya firmware detaylarından habersiz olmalıdır. (sf. 262)

Donanım Bir Detaydır: Donanım Arayüz Katmanı (HAL) veya İşlemci Soyutlama Katmanı (PAL) gibi soyutlamalar kullanılmalıdır. (sf. 263-264, 269) HAL kullanıcılarına donanım detaylarını açığa vurmayın. (sf. 265)

İşletim Sistemi Bir Detaydır: RTOS veya gömülü Linux gibi işletim sistemleri de soyutlanmalıdır. (sf. 269)

Kuru Koşullu Derleme Direktifleri: #ifdef gibi koşullu derleme direktiflerinin tekrarlanmasından kaçının. Donanım türü HAL altında gizlenmiş bir detay olmalıdır. (sf. 272)

Kod Organizasyonu:

Katmana Göre Paketleme: Mimari katmanlara (Web, Hizmetler, Depolar) göre organize etmektir. İş kurallarının bu katmanlara sızdığı ve katmanların iş kurallarından habersiz olduğu yaygın bir sorun vardır. (sf. 304-306)

Özelliğe Göre Paketleme: İlgili özelliklere, etki alanı kavramlarına veya toplama köklerine dayalı dikey dilimlemedir. Tüm türler, gruplanan kavramı yansıtan tek bir pakete yerleştirilir. (sf. 306)

Limanlar ve Adaptörler: İş kuralları çekirdektedir (Etki Alanı Katmanı) ve diğer tüm şeyler (UI, Veritabanı, Harici Hizmetler) adaptörler aracılığıyla etki alanına bağlanan limanlar olarak ele alınır. Bağımlılık Ters Çevirme kullanılır. (sf. 308-310) Bu, iş kurallarını diğer her şeyden izole etmek için harika bir yoldur. (sf. 310)

Mimari paketler ve erişim değiştiriciler (public vs published) kaynak kod bağımlılıklarını ayırmak için kullanılabilir. (sf. 316-319)

Test Edilebilirlik:

Temiz mimari test edilebilir mimaridir. Mimarlık, kodu harici detaylardan izole ederek test edilebilirliği desteklemelidir. (sf. 198, 211)

Humble Object Pattern: Test edilmesi zor olan davranışsal ve veri öğelerini (örn. GUI, veritabanı) test edilmesi kolay bir sınıfa ayırmayı içerir. (sf. 212-215)

Bir sistemin iş kurallarını, UI veya veritabanı gibi dış mekanizmalardan ayrı test etmek mümkün olmalıdır. (sf. 213-215)

Gömülü sistemlerde, hedef donanım kısıtlamaları olmadan kodu test etmek için HAL ve PAL gibi soyutlamalar hayati öneme sahiptir. (sf. 261-262)

İş Kuralları:

İş kuralları, işin para kazanmasını veya tasarruf etmesini sağlayan kurallar veya prosedürlerdir. Bilgisayar olmadan bile uygulanabilirler. (sf. 190)

İş kuralları, sistemin merkezinde olmalı ve diğer her şey (UI, veritabanı, servisler vb.) iş kurallarına bağımlı olmalıdır. (sf. 196-197, 202)

İş kurallarını, UI ve veritabanı gibi detaylardan ayıran sınırlar çizmek çok önemlidir. (sf. 165-169)

Mimari Arkeolojisi:

Kitap, yazarın kariyerindeki çeşitli yazılım projelerinden (Union Muhasebe, Lazer Trim, SAC, DLU/DRU, VRS, Craft Sevk Sistemi, ROSE) mimari dersleri göstermek için örnekler sunar. Bu projeler, yazılım geliştirmenin tarihsel evrimini ve iyi mimari ilkelerinin zamandan bağımsızlığını gösterir. (sf. 325-373)

Çeşitli projelerdeki bağımlılık yönetimi, modülerlik, test edilebilirlik ve mimari sınırların (ve eksikliklerinin) zorlukları ve çözümleri vurgulanır.

Çıkarılan Dersler:


Mimarlık bir detay meselesi değildir; bir sistemin uzun vadeli başarısı ve maliyeti üzerinde derin bir etkisi vardır.

Seçenekleri açık tutmak ve kararları mümkün olduğunca ertelemek, iyi bir mimari pratiğidir.

SOLID prensipleri ve Bileşen ilkeleri, esnek, test edilebilir ve sürdürülebilir yazılım sistemleri oluşturmak için temel oluşturur.

Sistemi temel iş kuralları ve dış detaylar (UI, veritabanı, çerçeveler, harici servisler) arasında ayıran net mimari sınırlar çizmek çok önemlidir.

Bağımlılıkları yönetmek, özellikle üst seviye bileşenlerin alt seviye detaylara bağlı olmadığından emin olmak, temiz mimarinin anahtarıdır.

Test edilebilirlik, iyi bir mimarinin doğal bir sonucudur. Mimari, kodun harici bağımlılıklar olmadan test edilmesine olanak sağlamalıdır.

Servisler, dağıtım modudur, mimari ilkesi değildir. Bağımsız geliştirilebilirlik ve konuşlandırılabilirlik iyi tasarlanmış bileşenlerden gelir.

Geçmişten öğrenmek önemlidir; birçok temel mimari prensip, modern programlama dillerinin ve araçlarının ortaya çıkmasından önce de geçerliydi.

Bu özet, sağlanan alıntılardan alınan ana noktaları ve önemli fikirleri kapsamaktadır. Daha derinlemesine bir anlayış için orijinal kaynağa başvurulması önerilir.

Please Select Embedded Mode To Show The Comment System.*

Daha yeni Daha eski

نموذج الاتصال