![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
Anlaşmalar yazılım geliştirmenin önemli bir parçasıdır. Geliştirme maliyetlerini düşürürler ve geliştiricilerin hayatlarını kolaylaştırırlar. Ancak bir sorun var; eski peri masalları gibi düzgün bir şekilde belgelenmediği ve ağızdan ağza aktarılmadığı için genellikle işleri karmaşık hale getiriyorlar. Yayılırken anlaşmalar değişir. Aniden yeni ayrıntılar ortaya çıkıyor ve eskileri kayboluyor. Sonunda her ekip üyesinin kafasında kendi anlaşma resmi vardır ve hatta bu resim bazen silinip gider.
Daha da kötüsü, ekipler bu anlaşmaları belgelemeye başladığında, bunu gelişigüzel yapıyorlar ve çoğunlukla yarısı güncel bile olmayan gevşek bir şekilde birleştirilmiş belgeler yığını oluşturuyorlar.
Bu yazıda size anlaşmaları belgelemenin doğru yolunu anlatacağım, böylece size yardımcı olacaklar.
Peki anlaşmaları nasıl faydalı hale getirebiliriz? Bunları yalnızca belgelemekle kalmıyoruz, aynı zamanda şunları da yapıyoruz:
kullanımı kolaydı;
bu anlaşmalara uymak minimum düzeyde çaba gerektiriyordu;
bu anlaşmaların hala geçerli olup olmadığını anlamak kolay olurdu;
bu anlaşmaların neden var olduğunu anlamak kolay olurdu;
ideal olarak - otomatikleştirildiler.
Anlaşmaları sınıflandırmanın birçok yolu bulunabilir. Bunları soyutlama düzeylerine göre ayıracağım:
Farklı düzeylerdeki anlaşmalar, bunları belgelemenin farklı yollarını gerektirir ve farklı faydalar sağlar. Her seviyeye bir göz atalım.
Bu anlaşmaların amacı kodu tek tip, kapsamlı ve okunabilir hale getirmektir. İşte bazı örnekler:
Tek tırnak yerine çift tırnak kullanıyoruz.
Bu çağrıları yöntemlere sardığımız Config
sınıfı dışında ENV'yi doğrudan koddan çağırmıyoruz.
Hizmet nesnelerinin son eki Service
ve bir genel yöntem call
vardır.
Bu tür anlaşmalar okuyucunun bilişsel yükünü azaltmak ve bilinmeyen kodlara daha hızlı alışmasına yardımcı olmak için oluşturulmuştur. Martin'in dediği gibi kod, yazılandan 10 kat daha fazla okunuyor.
Ruby on Rails çerçevesi hakkındaki düşüncenize rağmen, özünde, herhangi bir Rails geliştiricisinin bir başkasının projesini açmasına ve hemen oldukça iyi bir şekilde gezinmesine olanak tanıyan inanılmaz bir convention over configuration
vardır.
Peki bu sözleşmeler nasıl belgelenir? Linter aracı! Uygun bir linter kuralı yoksa, kendi lintinizi yazın. Hemen hemen her linter bunu yapmanıza izin verir: işte Go dilinde bir örnek ve işte Ruby için.
Bu tür sözleşmeler için linter kullanmak size üç fayda sağlar:
Geliştiricinin bunlar hakkında düşünmesine gerek yoktur; linter her hatayı vurgulayacak ve hatta çoğu zaman bunları sizin için düzeltecektir.
Ekibinizde kod incelemelerini kullanırsanız, incelemecilerinizi bu tür şeyler hakkında düşünmekten kurtarırsınız ve onlara daha önemli şeylere bakmaları için daha fazla zaman tanırsınız.
Geliştirici, geliştirme döngüsünün en başında bir sorun görecek ve daha sonra bağlama dönmeye zaman harcamadan sorunu hemen çözecektir. Anlaşmayı sürdürmek daha ucuz hale gelir.
Bir bonus daha: yeni bir linter kuralı yazmak, kıdemsiz bir geliştirici için mükemmel bir eğitimdir. Bu görevi tamamlarken kod ayrıştırma ve AST oluşturma hakkında çok şey öğrenecek ve dili daha derinlemesine anlayacak.
Bu, mimarinizi düşünceli, tutarlı ve tekdüze hale getirmeyi amaçlayan daha üst düzey bir anlaşma türüdür. Birkaç örnek:
Sistemin yüksek yüklü kısımlarına düzenli servisler ve Elixir yazmak için Python'u kullanıyoruz.
Arka uç, hataları açıklanan biçimde döndürür.
Her hizmetin prometheus'ta metrikler göndermesi gerekir; /metrics
uç noktasında metrikleri göndermeye yönelik bağlantı noktası PROMETHEUS_PORT
ortam değişkeni tarafından yapılandırılır.
Bu tür anlaşmalar yalnızca bilişsel yükü azaltmakla kalmaz, aynı zamanda üç sorunu daha çözer:
İşletme maliyetlerini azaltın. Hizmetler aynı şekilde, aynı günlük formatında, aynı metrikleri yayınlayarak başlatılırsa, hizmeti sürdürmek ve olaylarla başa çıkmak çok daha kolaydır.
Tasarım maliyetlerini azaltın. Geliştiricinin mimariyi her seferinde sıfırdan tasarlamasına gerek yoktur; siz önceden düşündünüz ve şimdi onun temel şeyler hakkında endişelenmeden yalnızca belirli bir özelliği veya hizmeti tasarlaması gerekiyor.
İletişim maliyetlerini azaltın. Sunucunun Kafka'daki yanıtı veya olay biçimi önceden belirlenmişse, geliştiricilerin her seferinde etkileşimlerini tartışmalarına gerek kalmaz, bunun yerine yalnızca kurallara başvurabilirler.
Bu tür anlaşmalar daha karmaşık ve ben bunları iki adımda çözmeyi tercih ediyorum.
Adım 1 – Tanımlayın
Mimari Karar Kaydı (ADR), bu tür anlaşmaların belgelenmesine yönelik bir araçtır. Onun çekiciliği, bir anlaşmayla birlikte meta bilgileri de yakalamasıdır: böyle bir anlaşmanın neden kabul edildiği; hangi alternatifler tartışıldı; en son ne zaman revize edildi; anlaşma hala geçerli mi?
Bu, yeni ekip üyesinin alınan kararların nedenlerini anlamasına ve etrafındaki insanlara bu konuda soru sormamasına olanak tanır.
ADR birkaç ana bloktan oluşur:
Anlaşma hangi sorunu çözüyor?
Sorunu çözmek için hangi seçenekler değerlendirildi ve bunların artıları ve eksileri nelerdi?
Sonunda hangi seçenek seçildi?
Ek bloklar olabilir - örneğin uygulama maliyetlerinin hesaplanması.
ADR'yi değişikliklerin ve tartışmaların geçmişinin görülebileceği bir sistemde tutmak daha uygundur. Benim tercihim Github ve Notion, her birinin artıları ve eksileri var. Github'un avantajı, bir inceleme aracına ve sürüm geçmişine sahip olmasıdır. Veritabanları ve etiketlerle çalışmanın kolaylığı nedeniyle Notion iyi bir çözüm olabilir. Ve ayrıca geliştirici olmayanlar bunu kolayca halledebilir.
ADR'ye başlamak istiyorsanız, farklı ADR şablonlarını ve bunların nasıl kullanılacağına dair örnekleri bulabileceğiniz depoya bakmanızı öneririm.
Adım 2 – Otomatikleştirin
ADR'lerin otomatikleştirilmesi, kod düzeyindeki kurallara göre daha zordur: tasarım linterleri henüz icat edilmemiştir (ne yazık!). Ancak ne tür bir anlaşma olduğuna bağlı olarak bunları kısmen otomatikleştirmek de mümkündür.
Diller, kitaplıklar ve hizmetlerin altyapıya yerleştirilmesine ilişkin anlaşmalar için hizmet şablonları oluşturun ve güncelleyin. Daha sonra geliştirici yeni hizmetleri sıfırdan yazmak yerine şablondan kopyalayıp yapılandırılmış Docker dosyasını, metrik yayınlamayı vb. hemen alır.
Benzer şekilde, tek bir uygulama içerisinde sınıf oluşturucular oluşturabilirsiniz. Birkaç uygulama katmanı üzerinde anlaştığınızı varsayalım (kontrolör => form => hizmet nesnesi). Bu durumda, yeni bir özellik için tüm katmanları aynı anda oluşturacak basit bir konsol komutu oluşturabilirsiniz.
Bu şekilde otomatikleştirilemeyecek bazı ilkeler üzerinde anlaşmaya vardıysanız, bir birleştirme isteğine veya izleyicideki bir göreve otomatik olarak eklenen kontrol listelerini düzenleyebilirsiniz; böylece geliştirici, görevi devretmeden önce bunları hızlı bir şekilde gözden geçirebilir.
Her şirkette süreçlere ilişkin birçok anlaşma vardır, örneğin:
Şirkette işe almanın nasıl çalıştığının açıklaması.
Sürüm kullanıma sunma işleminin açıklaması.
Büyük görevler için tasarım incelemeleri gereksinimi.
Haftada iki kez mevcut görevlerin ve engellerin tartışıldığı bir ekip toplantısı düzenlemek.
Yakın zamana kadar, şirketin başarısını önemli ölçüde etkilemesine rağmen bu anlaşmaları belgelemeyi düşünmüyordum. Bu anlaşmaların belgelenmesi yukarıda bahsedilen türde faydalar sağlamasının yanı sıra süreçleri rasyonelleştirmenize, görünür düzleme aktarmanıza ve bunların uygunluğu hakkında düşünmenize de olanak tanır.
Bu fikri aldım. ADR - Süreç Karar Kaydına (PDR) benzer bir araç önerdi. Tek farkı mimari kararlar yerine süreçlerle ilgili kararları anlatmasıdır. Ek olarak, her PDR'ye bir "yeniden düşünme tarihi" koymayı önerdi; bu tarih, belgenin benimsenmesinden n ay sonra sorunlarınızı hala en iyi şekilde çözüp çözmediğini görmek için belgeye geri döneceğiniz bir tarih (bu arada, aynı şey yapılabilir) ADR'ler ile).
Otomasyona gelince, yapabileceğiniz çok az şey var. Jira'da bir iş akışı kurarak, toplantılar için hatırlatıcılar ayarlayarak veya haftanın sonuçlarının sunumunu otomatik olarak hazırlayan bir bot oluşturarak bazı süreçleri otomatikleştirebilirsiniz (gerçi bunu yabancı bir şirkette yaptım).
Ancak çoğu zaman süreçleri gerçekten otomatikleştiremezsiniz ve asıl amacınız, takip edilmekten ziyade takip edilmesini kolaylaştırmaktır. Bununla birlikte, süreçlerinizi takip etmek zaten kolay olsa bile, anlaşmaların belgelenmesi yine de yararlı olacaktır; resmileştirme ve rasyonelleştirme, bunları geliştirmenize olanak sağlayacaktır.
Dokümantasyon ve ardından gelen otomasyon faydalıdır: Geliştirme için harcanan süre azalır, uygulamalar daha desteklenebilir hale gelir ve süreçler daha akıllı hale gelir.
Tüm bunların gereksiz bürokrasi olduğu düşünülebilir çünkü "biz iyi adamlarız; onsuz da kod geliştirebiliriz." Ancak aslında anlaşmalar size önemli miktarda zaman ve para tasarrufu sağlayacak ve çalışanların sinir hücrelerini koruyacaktır. Elbette, mutlak olarak anlaşmanıza ve anlaşmalara aykırı olan herhangi bir şeyi reddetmenize gerek yok; bu, anlaşmanın güncellenmesi gerektiğinin veya başlangıçta bazı yönlerini düşünmediğinizin bir işareti olabilir.
Ekibinizdeki anlaşmaları henüz belgelemeye başlamadıysanız, düşük soyutlama düzeylerinden daha yüksek düzeylere geçin: kod düzeyindeki anlaşmalardan başlayın, ardından mimari düzeydeki anlaşmalardan başlayın ve ancak bundan sonra süreç düzeyiyle başa çıkın. Sözleşme dokümantasyonu ekibinizde geliştirilecek bir alışkanlıktır ve daha az soyut kavramlarla başlamak çok daha kolaydır.
Ayrıca makalede her tür açıklanmamaktadır. Örneğin tasarım sözleşmesini kitaplık bileşenleri olarak belgeleyebilirsiniz.
Her yeni anlaşma türü aynı üç aşamadan geçer:
Bunu nasıl belgeleyeceğinizi öğrenin.
Bunu nasıl otomatikleştireceğinizi öğrenin.
Zaman geçtikçe, onu korumak için gerekenden daha fazla kaynak tasarrufu sağladığından emin olun.
Ve sonuncusu. Belgeleme sürecinde mevcut anlaşmalardan bazılarının görünürde hiçbir gerekçeye dayanmadığı, ekibinizin zamanını boşa harcadığı ve genel olarak zararlı olduğu görülebilir ancak siz bunlara zaten alışkınsınız. Bu durumda ekibinizin zihnindeki alışkanlık engelini aşmanız ve ekibinizi, anlaşmaların reddedilmesinin bazen onları kabul etmekten daha önemli olduğuna ikna etmeniz gerekir. Ama bu tamamen farklı bir hikaye.
Burada da yayınlandı.