Alan varlıklarımı neden sunum katmanımdan ayırmalıyım?


85

Etki alanı odaklı tasarımın çok fazla ayrıntı içermeyen bir parçası, etki alanı modelinizi arayüzünüzden nasıl ve neden ayırmanız gerektiğidir. Meslektaşlarımı bunun iyi bir uygulama olduğuna ikna etmeye çalışıyorum, ancak pek ilerleme kaydetmiyorum ...

Sunum ve arayüz katmanlarında istedikleri yerde etki alanı varlıklarını kullanırlar. Onlara Etki Alanı katmanını arayüz katmanından izole etmek için görüntüleme modellerini veya DTO'ları kullanmaları gerektiğini iddia ettiğimde, böyle bir şey yaparken iş değerini görmediklerini söylüyorlar, çünkü artık bakmanız gereken bir UI nesneniz var orijinal etki alanı nesnesinin yanı sıra.

Bu yüzden bunu desteklemek için kullanabileceğim bazı somut nedenler arıyorum. Özellikle:

  1. Neden sunum katmanımızda etki alanı nesneleri kullanmamalıyız?
    (Cevap bariz olan 'ayrıştırma' ise, lütfen bunun bu bağlamda neden önemli olduğunu açıklayın)
  2. Etki alanı nesnelerimizi arayüzden izole etmek için ek nesneler veya yapılar kullanmalı mıyız?

bu soru wiki'de olmalıdır.
Syed Tayyab Ali

@ m4bwav - Bir wiki olmalı çünkü tek bir doğru cevap yerine tartışmaya davet edecek şekilde ifade edilmiştir.
Rob Allen

1
@ m4bwav: Sorunuzun, gerçek bir sorudan çok bir fikir parçası olarak ortaya çıktığını düşünüyorum ... Bunu düzeltmeye çalıştım (daha fazla düzenlemek isteyebilirsiniz), ancak uygun bir bakım olmadan bunun görünebileceğini unutmayın trol olmak.
Shog9

5
Tamam, yedek, meşru bir soru soruyorum, bu birini nasıl rencide eder? Kimi hedef alıyorum?
Mark Rogers

@ m4bwav: saman adamınızı hedefliyorsunuz. Sorunuzda bunu tartıştığınız "çok sayıda insan".
Shog9

Yanıtlar:


48

Basitçe söylemek gerekirse, bunun nedeni uygulama ve sapmadır. Evet, sunum katmanınızın bunları doğru şekilde temsil edebilmesi için iş nesnelerinizi bilmesi gerekir. Evet, başlangıçta iki tür nesnenin uygulanması arasında çok fazla örtüşme var gibi görünüyor. Sorun şu ki, zaman geçtikçe her iki tarafa da işler ekleniyor. Sunum değişiklikleri ve sunum katmanının ihtiyaçları, iş katmanınızdan tamamen bağımsız olan şeyleri (örneğin renk) içerecek şekilde gelişir. Bu arada, etki alanı nesneleriniz zamanla değişir ve arabiriminizden uygun bir şekilde ayrılamazsanız, iş nesnelerinizde görünüşte zararsız değişiklikler yaparak arabirim katmanınızı bozma riskiyle karşı karşıya kalırsınız.

Kişisel olarak, olaylara yaklaşmanın en iyi yolunun sıkı bir şekilde uygulanan arayüz paradigması olduğuna inanıyorum; yani, iş nesnesi katmanınız, iletişim kurabilmesinin tek yolu olan bir arabirimi ortaya çıkarır; arayüzle ilgili hiçbir uygulama ayrıntısı (yani etki alanı nesneleri) gösterilmez. Evet, bu, etki alanı nesnelerinizi iki konumda uygulamanız gerektiği anlamına gelir; arayüz katmanınız ve BO katmanınız. Ancak bu yeniden uygulama, başlangıçta fazladan iş gibi görünse de, gelecekte bir noktada TONS iş tasarrufu sağlayacak ayrıştırmanın uygulanmasına yardımcı olur.


2
"Etki alanı nesnelerinizi iki konumda uygulayın" derken neyi kastediyorsunuz?
jlembke

10
Bu bana aptalca geliyor. Gelecekte iş tasarrufu YAPABİLECEĞİNE göre şimdi fazladan iş neden yapılıyor? 10 üzerinden 9 kez işten "TONS" tasarruf ettirecek değişikliği yapmanız gerekmeyecek.
bip bip sesi

13
@LuckyLindy: 100 üzerinden 99 kez (aslında daha fazla), emniyet kemerimi takmam sakatlanmam için gerekli değil. Ancak, gerçekten ihtiyacım olduğu bir durumda, beni (muhtemelen) ölmekten veya ağır şekilde yaralanmaktan alıkoyacaktır. Bir gram önleme, bir kilo tedaviye değer. Daha fazla deneyim kazandıktan sonra bu konudaki fikrinizin değişeceğinden şüpheleniyorum.
Paul Sonier

19

Bununla kendim mücadele ettim. Bir DTO'nun sunumda kullanılmasının mantıklı olduğu durumlar vardır. Diyelim ki, sistemimdeki Şirketlerin bir düşüşünü göstermek istediğimi ve değeri bağlamak için onların kimliğine ihtiyacım olduğunu varsayalım.

Aboneliklere atıfta bulunabilecek veya başka ne bilen bir CompanyObject yüklemek yerine, adı ve kimliği ile bir DTO gönderebilirim. Bu iyi bir kullanım IMHO'dur.

Şimdi başka bir örnek alalım. Bir Tahmini temsil eden bir nesnem var, bu tahmin işçilik, ekipman vb. Olabilir, tüm bu öğeleri alan ve bunları toplayan kullanıcı tarafından tanımlanan birçok hesaplamaya sahip olabilir (Her tahmin farklı türlerle farklı olabilir hesaplamalar). Neden bu nesneyi iki kez modellemeliyim? Neden kullanıcı arayüzümün hesaplamaları listelemesini ve görüntülemesini sağlayamıyorum?

Etki alanı katmanımı kullanıcı arabirimimden izole etmek için genellikle DTO kullanmıyorum. Etki alanı katmanımı kontrolümün dışındaki bir sınırdan izole etmek için kullanıyorum. Birisinin iş nesnesine navigasyon bilgilerini koyacağı fikri saçmadır, iş nesnenizi kirletmeyin.

Birinin iş nesnesine doğrulama koyacağı fikri? Bunun iyi bir şey olduğunu söylüyorum. Kullanıcı arayüzünüz, iş nesnelerinizi doğrulamaktan tek başına sorumlu olmamalıdır. İşiniz tabakası GEREKİR kendi doğrulama yapmak.

UI oluşturma kodunu neden bir busienss nesnesine koyarsınız? Benim durumumda, UI kodunu UI'den ayrı olarak oluşturan ayrı nesnelerim var. İş nesnelerimi Xml'ye dönüştüren ayrı nesnelerim var, bu tür kirlenmeyi önlemek için katmanlarınızı ayırmanız gerektiği fikri bana çok yabancı çünkü neden HTML oluşturma kodunu bir iş nesnesine bile koyasınız ...

Düzenle Biraz daha düşündüğüm gibi, UI bilgisinin etki alanı katmanına ait olabileceği durumlar var. Ve bu, etki alanı katmanı dediğiniz şeyi bulutlandırabilir, ancak hem kullanıcı arayüzü görünümü ve hissi hem de işlevsel iş akışı çok farklı davranışa sahip olan çok kiracılı bir uygulama üzerinde çalıştım. Çeşitli faktörlere bağlı olarak. Bu durumda, kiracıları ve yapılandırmalarını temsil eden bir etki alanı modelimiz vardı. Yapılandırmaları UI bilgilerini içeriyordu (örneğin, genel alanlar için etiketler).

Nesnelerimi kalıcı hale getirmek için tasarlamam gerekirse, nesneleri de kopyalamam gerekir mi? Yeni bir alan eklemek istiyorsanız, şimdi ekleyebileceğiniz iki yeriniz olduğunu unutmayın. Belki de DDD kullanıyorsanız, tüm kalıcı varlıklar etki alanı nesneleri mi? Örneğimde olduklarını biliyorum.


Etiketlerin farklı kiracılar için farklı olması, her kiracı için her yerde bulunan farklı bir dili göstermez mi? Bence, meta-modelin yorumlanmasında, bir etki alanının kiracılar arasında bir çeviri katmanıyla paylaşıldığı bir meta-model kavramı olması gerekiyor.
Kell

16

SQL'i ASP / JSP sayfalarınızdan uzak tutmanızla aynı nedenle yaparsınız.

Sunum VE etki alanı katmanında kullanmak için yalnızca bir etki alanı nesnesini saklarsanız, o nesne kısa sürede monolitik hale gelir. UI doğrulama kodunu, UI navigasyon kodunu ve UI oluşturma kodunu içermeye başlar. Ardından, kısa süre sonra tüm iş katmanı yöntemlerini bunun üzerine eklersiniz. Artık iş katmanınız ve kullanıcı arayüzünüz birbirine karıştı ve hepsi etki alanı varlık katmanında karışıklık yaratıyor.

Bu şık UI widget'ını başka bir uygulamada yeniden kullanmak ister misiniz? Peki, bu isimde, bu iki şema ve bu 18 tablo ile bir veritabanı oluşturmanız gerekiyor. İşletme doğrulamasını yapmak için ayrıca Hazırda Bekletme ve İlkbahar'ı (veya tercih ettiğiniz çerçeveleri) yapılandırmanız gerekir. Oh, bu 85 diğer alakasız sınıfı da dahil etmelisiniz, çünkü bunlar aynı dosyada bulunan iş katmanında referans verilmişlerdir.


13

Katılmıyorum.

Bence en iyi yol, sunum katmanınızdaki etki alanı nesneleriyle, AKSİNİ YAPMAYI HİSSEDİNE KADAR başlamaktır.

Popüler inanışın aksine, "Etki Alanı Nesneleri" ve "Değer Nesneleri" sunum katmanında mutlu bir şekilde bir arada var olabilir. Ve bunu yapmanın en iyi yolu budur - etki alanı nesneleriyle her iki dünyanın avantajlarından, daha az çoğaltma (ve standart kod) elde edersiniz; ve istekler arasında değer nesnelerini kullanmanın uyarlanması ve kavramsal basitleştirilmesi.


Girişiniz için teşekkürler, nereden geldiğini anlıyorum. Bunun başarılı bir proje yaratmanın sonsuz yollarından biri olmadığını söylemiyor olsam da, bakımı daha zor olan daha büyük ve daha karmaşık projeler için olan "Etki Alanına Dayalı Tasarım" stiline ters düşüyor gibi görünüyor. uzun vadede.
Mark Rogers

Hayır, bu yanlış ve tam olarak neden bu kadar çok site sql enjeksiyonuna karşı savunmasız kalıyor.
Remi

7

Cevap, uygulamanızın ölçeğine bağlıdır.


Basit CRUD (Oluşturma, Okuma, Güncelleme, Silme) uygulaması

Temel kaba uygulamalar için herhangi bir işlevselliğe sahip değilsiniz. Varlıkların üzerine DTO eklemek zaman kaybı olacaktır. Ölçeklenebilirliği artırmadan karmaşıklığı artıracaktır.

görüntü açıklamasını buraya girin


Orta derecede karmaşık CRUD dışı uygulama

Bu uygulama boyutunda, gerçek yaşam döngüsüne ve bunlarla ilişkili bazı iş mantığına sahip birkaç varlığa sahip olacaksınız.

Bu vakaya DTO eklemek birkaç nedenden dolayı iyi bir fikirdir:

  • Sunum katmanı, yalnızca varlığın sahip olduğu alanların alt kümesini görebilir. Varlıkları kapsüllediniz
  • Arka uç ve ön uç arasında bağlantı yok
  • Varlıkların içinde iş yöntemleriniz varsa, ancak DTO'da yoksa DTO'ların eklenmesi, dış kodun varlığınızın durumunu bozamayacağı anlamına gelir.

görüntü açıklamasını buraya girin


Karmaşık Kurumsal Uygulama

Tek bir varlığın birden fazla sunum yöntemine ihtiyacı olabilir. Her birinin farklı alanlara ihtiyacı olacaktır. Bu durumda, önceki örnekte olduğu gibi aynı sorunlarla karşılaşırsınız ve her müşteri için görünen alanların miktarını kontrol etmeniz gerekir. Her müşteri için ayrı bir DTO'ya sahip olmak, neyin görünmesi gerektiğini seçmenize yardımcı olacaktır.

görüntü açıklamasını buraya girin


4

Sunucuda ve kullanıcı arayüzünde aynı modeli kullanıyoruz. Ve bu bir acı. Bir gün onu yeniden düzenlemeliyiz.

Sorunlar temel olarak, etki alanı modelinin tüm veritabanına başvurulmadan onu serileştirebilmek için daha küçük parçalara kesilmesi gerektiğinden kaynaklanmaktadır. Bu, sunucuda kullanımını zorlaştırır. Önemli bağlantılar eksik. Bazı türler de serileştirilemez ve istemciye gönderilemez. Örneğin 'Tür' veya herhangi bir genel sınıf. Jenerik olmamaları ve Type olarak dizgi olarak aktarılması gerekir. Bu, serileştirme için fazladan özellikler üretir, gereksizdir ve kafa karıştırıcıdır.

Diğer bir sorun, kullanıcı arayüzündeki varlıkların gerçekten uymamasıdır. Veri bağlama kullanıyoruz ve birçok varlığın yalnızca kullanıcı arabirimi amaçları için çok sayıda yedek özelliği var. Ek olarak, varlık modelinde birçok 'BrowsableAttribute' ve diğerleri vardır. Bu gerçekten kötü.

Sonunda, bunun hangi yolun daha kolay olduğu meselesi olduğunu düşünüyorum. İyi çalıştığı ve başka bir DTO modeli yazmaya gerek olmayan projeler olabilir.


2
Veri bağlamayı kullanacaksanız, bir linq sorgusu çalıştırın ve anonim bir türe bağlanın. Bu, hiyerarşiyi düzleştirmenizi ve değiştirmenizi sağlar. Bununla birlikte, filtreleme ve sıralamayı çok güzel bir şekilde uygulayabilirsiniz.
JoshBerke

@ Josh: Tavsiyen için teşekkürler. Bu kısmen işe yarayabilir. Ben kendim bir GUI programcısı değilim ve GUI kavramlarına pek dahil değilim. Sorun, verilerin işlendiği ve sunucuya geri gönderildiği durumlarda olacaktır.
Stefan Steinegger

3

Çoğunlukla bağımlılıklar ile ilgili. Kuruluşun temel işlevsel yapısının kendi işlevsel gereksinimleri vardır ve kullanıcı arabirimi, insanların çekirdeği değiştirmesine ve görüntülemesine olanak sağlamalıdır; ancak çekirdeğin kendisinin kullanıcı arayüzünü barındırması gerekli olmamalıdır. (Olması gerekiyorsa, bu genellikle çekirdeğin mülk tasarlanmadığının bir göstergesidir.)

Muhasebe sistemim, şirketimin işleyişini modellemesi gereken bir yapıya ve içeriğe (ve verilere) sahiptir. Bu yapı gerçektir ve hangi muhasebe yazılımını kullandığımdan bağımsız olarak mevcuttur. (Kaçınılmaz olarak, belirli bir yazılım paketi kendi iyiliği için yapı ve içerik içerir, ancak zorluğun bir kısmı bu ek yükü en aza indirmektir.)

Temelde bir kişinin yapması gereken bir işi vardır. DDD, işin akışına ve içeriğine uygun olmalıdır. DDD, yapılması gereken tüm işleri olabildiğince tamamen ve bağımsız bir şekilde açıklamakla ilgilidir. Daha sonra kullanıcı arayüzü, işi olabildiğince şeffaf ve olabildiğince verimli bir şekilde yapmayı umuyoruz.

Arayüzler, uygun şekilde modellenmiş ve değişmez işlevsel çekirdek için sağlanan girdiler ve görünümlerle ilgilidir.


3

Kahretsin, yemin ederim bu ısrar dedi.

Her neyse, aynı şeyin bir örneği daha: Parnas yasası, bir modülün sır tutması gerektiğini ve sırın değişebilen bir gereklilik olduğunu söylüyor. (Bob Martin'in bunun başka bir versiyonu olan bir kuralı vardır.) Böyle bir sistemde, sunum alandan bağımsız olarak değişebilir . Örneğin, fiyatları Euro cinsinden tutan ve şirket ofislerinde Fransızca kullanan, ancak fiyatları Mandarin dilinde metinle dolar cinsinden sunmak isteyen bir şirket gibi. Etki alanı aynıdır; sunum değişebilir. Dolayısıyla, sistemin kırılganlığını en aza indirmek için - yani, gereksinimlerde bir değişiklik uygulamak için değiştirilmesi gereken şeylerin sayısı - endişeleri ayırırsınız.


2

Sununuz olabilir referans alan adı katmanı, ancak hiçbir alan adı nesneler için ui doğrudan bağlayıcı olmalıdır. Etki alanı nesneleri, uygun şekilde tasarlanırlarsa, veri temsillerine değil davranışlara dayalı olduklarından, kullanıcı arabirimi kullanımına yönelik değildir. Kullanıcı Arabirimi ile Etki Alanı arasında bir eşleme katmanı olmalıdır. MVVM veya MVP, bunun için iyi bir modeldir. Kullanıcı arayüzünüzü doğrudan Etki Alanına bağlamayı denerseniz, muhtemelen kendiniz için çok fazla baş ağrısı yaratırsınız. İki farklı amacı vardır.


1

Belki de UI katmanını yeterince geniş terimlerle kavramsallaştırmıyorsunuz. Birden çok yanıt biçimi (web sayfaları, sesli yanıt, basılı mektuplar vb.) Ve birden çok dil (İngilizce, Fransızca vb.) Açısından düşünün.

Şimdi, telefonla arama sistemi için konuşma motorunun, web sitesini çalıştıran bilgisayardan (belki de Windows) tamamen farklı bir bilgisayarda (örneğin Mac) çalıştığını varsayalım.

Tabii ki tuzağa düşmek kolaydır "Şirketimde sadece İngilizce'yi önemsiyoruz, web sitemizi LAMP (Linux, Apache, MySQL ve PHP) üzerinde çalıştırıyoruz ve herkes Firefox'un aynı sürümünü kullanıyor". Peki ya 5 veya 10 yıl sonra?



1

' Value Injecter ' gibi bir araç yardımıylaGörünümlerle çalışırken sunum katmanındaki ' ve 'Mappers' kavramı sayesinde, her kod parçasını anlamak çok daha kolay. Biraz kodunuz varsa, avantajları hemen görmezsiniz ancak projeniz gittikçe büyüyecekse, hizmetlerin mantığına girmek zorunda kalmamak için görüşlerle çalışırken çok mutlu olacaksınız, görüntüleme modelini anlamak için havuzlar. View Model, engin yolsuzlukla mücadele katmanı dünyasında başka bir koruyucudur ve uzun vadeli bir projede ağırlığı altın olarak değerindedir.

Görünüm modelini kullanmanın hiçbir avantajı görmememin tek nedeni, projenizin küçük ve basit olması ve görünümlerin doğrudan modelinizin her bir özelliğine bağlanmasıdır. Ancak gelecekte, gereksinim değişikliği ve görünümlerdeki bazı kontroller modele bağlanmayacaksa ve bir görünüm modeli konseptiniz yoksa, birçok yerde yamalar eklemeye başlayacak ve eski bir koda sahip olmaya başlayacaksınız. takdir etmeyeceksin. Elbette, görünüm modelinizi görünüm-görünüm modelinde dönüştürmek için biraz yeniden düzenleme yapabilir ve YAGNI ilkesini takip edebilir, buna ihtiyacınız yoksa kod eklemeyebilir, ancak kendim için, bu çok daha fazla bir yalnızca görünüm modeli nesnelerini açığa çıkaran sunum katmanı.


1

Alan varlıklarını görünümden ayırmanın neden iyi bir uygulama bulduğuna dair gerçek bir örnek.

Birkaç ay önce bir toprak örneğindeki Azot, Fosfor ve Potasyum değerlerini 3 göstergeli bir dizi ile göstermek için basit bir kullanıcı arayüzü oluşturdum. Her göstergenin kırmızı, yeşil ve kırmızı bir bölümü vardı, yani her bileşenden çok az veya çok fazla olabilirdiniz, ancak ortada güvenli bir yeşil seviye vardı.

Çok fazla düşünmeden, bu 3 kimyasal bileşen için veri sağlamak üzere iş mantığımı modelledim ve 3 vakanın her birinde kabul edilen seviyeler hakkında veriler içeren (hangi ölçüm biriminin kullanıldığı, yani moller veya yüzde dahil). Daha sonra kullanıcı arayüzümü çok farklı bir model kullanacak şekilde modelledim, bu model gösterge etiketleri, değerler, sınır değerleri ve renklerle ilgileniyordu.

Bu, daha sonra 12 bileşeni göstermem gerektiğinde, fazladan verileri 12 yeni gösterge görünümü modeliyle eşleştirdim ve ekranda belirdi. Ayrıca, gösterge kontrolünü kolayca yeniden kullanabileceğim ve diğer veri kümelerini görüntüleyebileceğim anlamına geliyordu.

Bu göstergeleri doğrudan etki alanı varlıklarıma bağlamış olsaydım, yukarıdaki esnekliklerin hiçbirine sahip olmazdım ve gelecekteki herhangi bir değişiklik baş ağrısına neden olurdu. Kullanıcı arayüzünde takvimleri modellerken çok benzer sorunlarla karşılaştım. 10'dan fazla katılımcı olduğunda bir takvim randevusunun kırmızıya dönmesi için bir gereklilik varsa, bunu ele alacak iş mantığı iş katmanında kalmalı ve kullanıcı arayüzündeki tüm takvimin bilmesi gereken, kırmızıya dönün, nedenini bilmesine gerek yok.


-1

Genelleştirilmiş ve alana özgü anlambilim arasına ek eşleme eklemenin tek mantıklı nedeni, etki alanınızın anlambiliminden farklı, genelleştirilmiş (ancak eşlenebilir) bir semantiğe dayanan mevcut bir kod gövdesine (ve araçlara) sahip olmanızdır (erişiminiz).

Etki alanı güdümlü tasarımlar, ortogonal bir dizi işlevsel etki alanı çerçeveleri (ORM, GUI, İş Akışı, vb.) İle birlikte kullanıldığında en iyi şekilde çalışır. Etki alanı anlambiliminin yalnızca dış katman bitişiklerinde açığa çıkarılması gerektiğini her zaman unutmayın. Tipik olarak bu, ön uç (GUI) ve kalıcı arka uçtur (RDBM, ORM). Etkili bir şekilde tasarlanmış ara katmanlar, etki alanında değişmez olabilir ve olmalıdır.


para 1: gerçekten farklı uygulamalar arasında paylaşmadığınız sürece gereksiz soyutlamalar (örneğin yeniden kullanılabilir bileşenler) oluşturmayın. para 2: Genel GUI'lerin bu kadar çok farklı alanda nasıl çalıştığını merak ediyorum. Not: Bu sektör o kadar bozuk ki artık komik bile değil ...
alphazero
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.