Mimari ilkeleri

İpucu

Bu içerik, .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak sağlanan ASP.NET Core ve Azure ile Modern Web Uygulamaları Mimarisi adlı e-Kitap'tan bir alıntıdır.

Architect Modern Web Applications with ASP.NET Core and Azure eBook cover thumbnail.

"Eğer inşaatçılar binaları programcıların yazdığı gibi inşa etse, o zaman ortaya çıkan ilk ağaçkakan medeniyeti yok eder."
- Gerald Weinberg

Yazılım çözümlerini sürdürülebilirliği göz önünde bulundurarak tasarlamanız ve tasarlamanız gerekir. Bu bölümde özetlenen ilkeler, temiz ve sürdürülebilir uygulamalarla sonuçlanacak mimari kararlar konusunda size yol gösterebilir. Genel olarak, bu ilkeler uygulamanızın diğer bölümleriyle sıkı bir şekilde bağlı olmayan, açık arabirimler veya mesajlaşma sistemleri aracılığıyla iletişim kuran ayrık bileşenlerden uygulama oluşturma konusunda size yol gösterir.

Ortak tasarım ilkeleri

Endişelerin ayrılması

Geliştirme sırasında yol gösteren bir ilke, Endişelerin Ayrımı'dır. Bu ilke, yazılımın yaptığı iş türlerine göre ayrılması gerektiğini iddia eder. Örneğin, kullanıcıya görüntülenecek önemli öğeleri tanımlama mantığı içeren ve bu öğeleri daha belirgin hale getirmek için belirli bir şekilde biçimlendiren bir uygulama düşünün. Biçimlendirilecek öğeleri seçmekten sorumlu davranış, öğeleri biçimlendirmekten sorumlu davranıştan ayrı tutulmalıdır, çünkü bu davranışlar yalnızca birbiriyle tesadüfen ilişkili ayrı endişelerdir.

Mimari olarak, uygulamalar temel iş davranışını altyapı ve kullanıcı arabirimi mantığından ayırarak bu ilkeyi izleyecek şekilde mantıksal olarak oluşturulabilir. İdeal olan, iş kuralları ve mantığının uygulamadaki diğer projelere bağımlı olmaması gereken ayrı bir projede bulunmasıdır. Bu ayrım, iş modelinin test edilmesinin kolay olmasını ve alt düzey uygulama ayrıntılarıyla sıkı bir şekilde birleştirilmeden gelişebilmesini sağlamaya yardımcı olur (altyapıyla ilgili endişelerin iş katmanında tanımlanan soyutlamalara bağlı olup olmadığı da yardımcı olur). Uygulama mimarilerinde katmanların kullanılmasının ardındaki önemli noktalardan biri de endişelerin ayrılmasıdır.

Kapsülleme

Uygulamanın farklı bölümleri, bunları uygulamanın diğer bölümlerinden yalıtmak için kapsülleme kullanmalıdır. Uygulama bileşenleri ve katmanları, dış sözleşmeler ihlal edilmediği sürece ortak çalışanlarını bozmadan iç uygulamalarını ayarlayabilmelidir. Kapsüllemenin düzgün kullanımı, uygulama tasarımlarında gevşek bağlama ve modülerlik elde edilmesine yardımcı olur, çünkü nesneler ve paketler, aynı arabirim korunduktan sonra alternatif uygulamalarla değiştirilebilir.

Sınıflarda kapsülleme, sınıfın iç durumuna dışarıdan erişimi sınırlayarak elde edilir. Dış aktör nesnenin durumunu işlemek istiyorsa, bunu nesnenin özel durumuna doğrudan erişime sahip olmak yerine iyi tanımlanmış bir işlev (veya özellik ayarlayıcısı) aracılığıyla yapmalıdır. Benzer şekilde, uygulama bileşenleri ve uygulamalar da durumlarının doğrudan değiştirilmesine izin vermek yerine, ortak çalışanlarının kullanması için iyi tanımlanmış arabirimleri kullanıma sunmalıdır. Bu yaklaşım, genel sözleşmeler korunduktan sonra uygulamanın iç tasarımının zaman içinde gelişmesine ve bunu yapmanın ortak çalışanları bozacağı konusunda endişelenmeden serbest bırakmasını sağlar.

Mutable global state, kapsülleme için antitetiktir. Bir işlevde değiştirilebilir genel durumdan getirilen bir değer, başka bir işlevde (hatta aynı işlevde daha da fazla) aynı değere sahip olması için kullanılamaz. C# gibi programlama dillerinin deyimlerden yöntemlere ve sınıflara kadar her yerde kullanılan farklı kapsam kuralları için destek olmasının nedenlerinden biri, değiştirilebilir genel durumla ilgili endişeleri anlamaktır. Uygulamalar içinde ve uygulamalar arasında tümleştirme için merkezi bir veritabanına dayanan veri odaklı mimarilerin, veritabanı tarafından temsil edilen değiştirilebilir genel duruma bağlı olarak tercih edilen mimariler olduğunu belirtmek gerekir. Etki alanı odaklı tasarım ve temiz mimaride dikkat edilmesi gereken önemli noktalardan biri, verilere erişimi kapsülleme ve kalıcılık biçimine doğrudan erişimle uygulama durumunun geçersiz hale getirilmemesini sağlamadır.

Bağımlılık ters çevirme

Uygulama içindeki bağımlılığın yönü, uygulama ayrıntıları değil soyutlama yönünde olmalıdır. Çoğu uygulama, derleme zamanı bağımlılığının çalışma zamanı yürütme yönünde akması ve doğrudan bağımlılık grafı oluşturması için yazılır. Yani, A sınıfı B sınıfının bir yöntemini çağırırsa ve B sınıfı C sınıfının bir yöntemini çağırırsa, derleme zamanında A sınıfı B sınıfına, B sınıfı ise Şekil 4-1'de gösterildiği gibi C sınıfına bağlıdır.

Direct dependency graph

Şekil 4-1. Doğrudan bağımlılık grafiği.

Bağımlılık ters çevirme ilkesinin uygulanması, A'nın B'nin uyguladığı bir soyutlamada yöntemleri çağırmasına olanak tanır ve A'nın çalışma zamanında B'yi çağırmasını, ancak B'nin derleme zamanında A tarafından denetlenen bir arabirime bağımlı olmasını sağlar (bu nedenle tipik derleme zamanı bağımlılığını tersine çevirir ). Çalışma zamanında, program yürütme akışı değişmeden kalır, ancak arabirimlerin tanıtılması, bu arabirimlerin farklı uygulamalarının kolayca takılabilmesi anlamına gelir.

Inverted dependency graph

Şekil 4-2. Ters bağımlılık grafiği.

Bağımlılık ters çevirme , gevşek bir şekilde bağlanmış uygulamalar oluşturmanın önemli bir parçasıdır, çünkü uygulama ayrıntıları tam tersi yerine daha üst düzey soyutlamalara bağımlı olacak ve uygulayacak şekilde yazılabilir. Sonuçta elde edilen uygulamalar daha test edilebilir, modüler ve sonuç olarak sürdürülebilir. Bağımlılık ekleme uygulaması, bağımlılık ters çevirme ilkesine uyularak mümkün hale getirilir.

Açık bağımlılıklar

Yöntemlerin ve sınıfların düzgün çalışması için ihtiyaç duydukları tüm işbirliği nesnelerini açıkça gerektirmesi gerekir. Buna Açık Bağımlılıklar İlkesi adı verilir. Sınıf oluşturucuları, sınıfların geçerli bir durumda olması ve düzgün çalışması için ihtiyaç duydukları şeyleri tanımlamalarına olanak sağlar. Oluşturulabilen ve çağrılabilen ancak yalnızca belirli genel veya altyapı bileşenleri varsa düzgün çalışacak sınıfları tanımlarsanız, bu sınıflar istemcileriyle dürüst değildir. Oluşturucu sözleşmesi istemciye yalnızca belirtilen şeylere ihtiyacı olduğunu (sınıf yalnızca parametresiz bir oluşturucu kullanıyorsa büyük olasılıkla hiçbir şey) gerektiğini söylüyor, ancak çalışma zamanında nesnenin gerçekten başka bir şeye ihtiyacı olduğu ortaya çıkıyor.

Açık bağımlılıklar ilkesine uyarak, sınıflarınız ve yöntemleriniz istemcileri ile birlikte çalışması için neye ihtiyaçları olduğu konusunda dürüst olur. Bu ilkeye uyularak kodunuz daha kendi kendine belgelenir ve kodlama sözleşmeleriniz daha kullanıcı dostu hale gelir, çünkü kullanıcılar yöntem veya oluşturucu parametreleri biçiminde gerekenleri sağladıkları sürece, üzerinde çalıştıkları nesnelerin çalışma zamanında doğru şekilde davranacaklarına güvenecektir.

Tek sorumluluk

Tek sorumluluk ilkesi nesne odaklı tasarım için geçerlidir, ancak endişelerin ayrılmasına benzer bir mimari ilke olarak da düşünülebilir. Nesnelerin tek bir sorumluluğu olması gerektiğini ve yalnızca bir değişiklik nedeni olması gerektiğini belirtir. Özellikle, nesnenin değişmesi gereken tek durum, tek sorumluluğunu yerine getirme şeklinin güncelleştirilmesi gerektiğidir. Bu ilkenin uygulanması daha gevşek bir şekilde bağlanmış ve modüler sistemler üretmeye yardımcı olur, çünkü birçok yeni davranış türü mevcut sınıflara ek sorumluluk eklemek yerine yeni sınıflar olarak uygulanabilir. Henüz hiçbir kod yeni sınıflara bağlı olmadığından, yeni sınıflar eklemek her zaman mevcut sınıfları değiştirmekten daha güvenlidir.

Monolitik bir uygulamada tek sorumluluk ilkesini uygulamadaki katmanlara üst düzeyde uygulayabiliriz. Sunum sorumluluğu kullanıcı arabirimi projesinde kalırken, veri erişim sorumluluğu bir altyapı projesinde tutulmalıdır. İş mantığı, kolayca test edilebileceği ve diğer sorumluluklardan bağımsız olarak gelişebileceği uygulama çekirdeği projesinde tutulmalıdır.

Bu ilke uygulama mimarisine uygulandığında ve mantıksal uç noktasına alındığında mikro hizmetler elde edersiniz. Belirli bir mikro hizmetin tek bir sorumluluğu olmalıdır. Bir sistemin davranışını genişletmeniz gerekiyorsa, genellikle mevcut bir sisteme sorumluluk eklemek yerine ek mikro hizmetler ekleyerek bunu yapmak daha iyidir.

Mikro hizmetler mimarisi hakkında daha fazla bilgi edinin

Kendinizi tekrar etmeyin (KURU)

Bu uygulama sık karşılaşılan bir hata kaynağı olduğundan, uygulama belirli bir kavramla ilgili davranışı birden çok yerde belirtmekten kaçınmalıdır. Bir noktada, gereksinimlerde bir değişiklik bu davranışın değiştirilmesini gerektirir. Davranışın en az bir örneğinin güncelleştirilememesi ve sistemin tutarsız davranması olasıdır.

Mantığı yinelemek yerine bir programlama yapısında kapsüller. Bu yapıyı bu davranış üzerinde tek yetkili yapın ve uygulamanın bu davranışı gerektiren başka bir parçasının yeni yapısını kullanmasını sağlayın.

Not

Yalnızca tesadüfen tekrarlanan bir şekilde birbirine bağlanma davranışından kaçının. Örneğin, iki farklı sabitin de aynı değere sahip olması, kavramsal olarak farklı şeylere başvuruda bulunan tek bir sabite sahip olmanız gerektiği anlamına gelmez. Yineleme her zaman yanlış soyutlama ile bağlantı için tercih edilir.

Kalıcılık yoksayma

Kalıcılık yoksayma (PI), kalıcı olması gereken ancak kodu kalıcılık teknolojisi seçiminden etkilenmeyen türleri ifade eder. .NET'teki bu tür türlerin belirli bir temel sınıftan devralması veya belirli bir arabirim uygulaması gerekmediğinden bazen Düz Eski CLR Nesneleri (POCO' lar) olarak adlandırılır. Kalıcılık yoksayma, aynı iş modelinin birden çok şekilde kalıcı olmasını sağladığından ve uygulamaya ek esneklik sağladığından değerlidir. Kalıcılık seçenekleri zaman içinde, bir veritabanı teknolojisinden diğerine değişebilir veya uygulamanın başlattığı her şeye ek olarak ek kalıcılık biçimleri gerekebilir (örneğin, ilişkisel veritabanına ek olarak Redis önbelleği veya Azure Cosmos DB kullanma).

Bu ilkenin ihlallerine bazı örnekler şunlardır:

  • Gerekli bir temel sınıf.

  • Gerekli bir arabirim uygulaması.

  • Kendilerini kaydetmekten sorumlu sınıflar (Etkin Kayıt düzeni gibi).

  • Gerekli parametresiz oluşturucu.

  • Sanal anahtar sözcük gerektiren özellikler.

  • Kalıcılığa özgü gerekli öznitelikler.

Sınıfların yukarıdaki özelliklerden veya davranışlardan herhangi birine sahip olması gereksinimi, kalıcı hale getirilecek türler ile kalıcılık teknolojisi seçimi arasında bağlantı sağlayarak gelecekte yeni veri erişim stratejilerini benimsemeyi daha zor hale getirir.

Sınırlanmış bağlamlar

Sınırlanmış bağlamlar , Etki Alanı Odaklı Tasarım'da merkezi bir desendir. Bunlar, büyük uygulamalarda veya kuruluşlarda karmaşıklığı ayrı kavramsal modüllere ayırarak bu karmaşıklıklarla başa çıkılma yöntemi sağlar. Ardından her kavramsal modül, diğer bağlamlardan (dolayısıyla sınırlanmış) ayrılmış bir bağlamı temsil eder ve bağımsız olarak gelişebilir. Sınırlanmış her bağlam, içindeki kavramlar için kendi adlarını seçmekte özgür olmalıdır ve kendi kalıcılık deposuna özel erişime sahip olmalıdır.

En azından, tek tek web uygulamaları bir veritabanını diğer uygulamalarla paylaşmak yerine kendi iş modellerine yönelik kalıcılık depoları ile kendi sınırlanmış bağlamları olmaya çalışmalıdır. Sınırlanmış bağlamlar arasındaki iletişim, gerçekleşen değişikliklere yanıt olarak iş mantığının ve olayların gerçekleşmesini sağlayan paylaşılan bir veritabanı yerine programlı arabirimler aracılığıyla gerçekleşir. Sınırlanmış bağlamlar mikro hizmetlerle yakından eşlenir ve bu da ideal olarak kendi sınırlanmış bağlamları olarak uygulanır.

Ek kaynaklar