Temiz Mimari: Görünüm Modeli Nedir?


13

Bob Amca, 'Temiz Mimari' kitabında, Sunucunun aldığı verileri 'Modeli Görüntüle' olarak adlandırdığı bir şeye koyması gerektiğini söylüyor.

resim açıklamasını buraya girin

Model-View-ViewModel (MVVM) tasarım modelinden 'ViewModel' ile aynı şey mi yoksa basit bir Veri Aktarım Nesnesi (DTO) mi?

Eğer öyleyse değil , basit bir DTO, nasıl Görünüm ile ilgisi nedir? Görünüm, bir Observer ilişkisi aracılığıyla ondan güncellemeler alıyor mu?

Benim tahminim daha çok MVVM'den ViewModel'e benziyor, çünkü kitabının 23. Bölümünde Robert Martin şöyle diyor:

[Sunum Yapan Kişinin] işi, uygulamadaki verileri kabul etmek ve bunları sunum için biçimlendirmektir, böylece Görünüm yalnızca ekrana taşıyabilir. Örneğin, uygulama bir alanda görüntülenen bir tarih istiyorsa, Sunum Yapan kişiye bir Tarih nesnesi verir. Presenter daha sonra bu verileri uygun bir dizeye biçimlendirir ve Görünüm modeli adlı basit bir veri yapısına yerleştirir; burada Görünüm bulabilir.

Bu, örneğin bir işlev bağımsız değişkeni olarak (DTO'da olduğu gibi) almanın aksine, Görünüm'ün bir şekilde ViewModel ile bağlantılı olduğu anlamına gelir.

Eğer resmin bakarsak, Sunucu Görünümü Modeli kullanır, ancak çünkü bu düşünmek başka nedeni ise değil Görünüm. Sunum Yapan, hem Çıktı Sınırını hem de Çıktı Verisi DTO'yu kullanır.

MVVM'den ne bir DTO ne de ViewModel değilse, lütfen ne olduğuna dikkat edin.


Bence cevap "duruma göre değişir". Bir web uygulamasıysa, görünüm modeli temelde bir DTO'dur, çünkü sonuçta bir HTML dizesi olarak serileştirilir. Aksi takdirde görünüm modeli, verileri görünümde görüntülemek için özel bir nesnedir.
Greg Burghardt

MVVM (WPF, Win uygulamalar) olarak ViewModeliçin sarıcı Controller, Presenterve ViewModelBob Amcanın Temiz mimaride.
Fabio

@Greg Burghardt - ViewModel özel bir veri yapısı olduğunda, Görünüm değişikliklere nasıl bildirilir?
Fearnbuster

@Fabio - MVVM modelinde, ViewModel'in diyagramın en solundaki tüm bileşenlere eşdeğer olduğunu söylediğiniz anlamına gelirse, doğru mu? Bob Amca'nın mimarisi için doğruysa, neden Denetleyiciyi ve Sunucuyu ayrı ayrı listeliyor?
Fearnbuster

Giriş ve çıkış işleyicilerini farklı nesnelere / sınıflara ayırdığını düşünüyorum. MVVM'de Controller-> ICommandve Presenter-> olabilir data-binding mechanism.
Fabio

Yanıtlar:


17

Model-View-ViewModel (MVVM) tasarım modelindeki 'ViewModel' ile aynı şey mi?

Hayır!

Yani olurdu bu :

resim açıklamasını buraya girin

Döngüler var. Bob Amca döngüden dikkatli bir şekilde kaçınır .

Bunun yerine:

resim açıklamasını buraya girin

Kesinlikle döngüleri yok. Ancak bu, görünümün bir güncelleme hakkında nasıl bildiğini merak etmenizi sağlar. Birazdan buna ulaşacağız.

ya da basit bir Veri Aktarım Nesnesi (DTO) mu?

Bob'u bir önceki sayfadan alıntılamak için:

İsterseniz temel yapıları veya basit veri aktarım nesnelerini kullanabilirsiniz. Veya bir hashmap içine paketleyebilir veya bir nesneye inşa edebilirsiniz.

Temiz Mimari p207

Yani, tabii, eğer istersen.

Ama şiddetle gerçekten sizi rahatsız eden şüpheli bu :

resim açıklamasını buraya girin

UML'nin bu sevimli küçük kötüye kullanımı, kaynak kod bağımlılığının yönünü kontrol akış yönüyle karşılaştırır. Sorunuzun cevabını burada bulabilirsiniz.

Kullanım ilişkisinde:

resim açıklamasını buraya girin resim açıklamasını buraya girin

kontrol akışı, kaynak kod bağımlılığının yaptığı yönde gider.

Uygulama ilişkisinde:

resim açıklamasını buraya girin resim açıklamasını buraya girin

kontrol akışı tipik olarak kaynak kod bağımlılığının tersi yönde ilerler.

Bu, gerçekten buna baktığınız anlamına gelir:

resim açıklamasını buraya girin

Kontrol akışının Sunum Yapandan Görünüme asla ulaşamayacağını görebilmelisiniz.

Nasıl olabilir? Bu ne demek?

Bu, görünümün kendi iş parçacığına sahip olduğu anlamına gelir (bu olağandışı değildir) veya (@Euphoric işaret ettiği gibi) kontrol akışı, burada tasvir edilmeyen başka bir şeyden görünüme geliyor.

Aynı iş parçacığıysa, Görünüm, Görünüm Modelinin ne zaman okunmaya hazır olduğunu bilecektir. Ancak durum buysa ve görünüm bir GUI ise, kullanıcı DB'yi beklerken ekranı hareket ettirdiğinde ekranı yeniden boyamakta zorlanır.

Görünüm kendi iş parçacığına sahipse, kendi kontrol akışına sahiptir. Bu, Uygulamayı uygulamak için, değişiklikleri fark etmek için Görünüm Modeli'ni sorgulamak zorunda kalacağı anlamına gelir.

Sunucu, Görünüm'ün varlığını ve Görünüm, Sunucu'nun var olduğunu bilmediğinden birbirlerini arayamazlar. Olayları birbirlerine fırlatamazlar. Olabilecek tek şey, Sunucunun View-Model'e yazacağı ve View View-Model'i okuyacağıdır. Ne zaman hissediyorsa.

Bu şemaya göre, View ve Presenter'ın paylaştığı tek şey View-Model hakkında bilgidir. Ve bu sadece bir veri yapısı. Yani herhangi bir davranışı olmasını beklemeyin.

Bu imkansız görünebilir, ancak View-Model karmaşık olsa bile çalışması sağlanabilir. Küçük bir güncellenmiş alan, tüm görünümü bir değişiklik tespit etmek için anket gerekir.

Şimdi elbette gözlemci desenini kullanmakta ısrar edebilir veya bu sorunu sizden gizlemek için bazı çerçeveli şeylere sahip olabilirsiniz, ancak lütfen bunu yapmak zorunda olmadığınızı anlayın.

İşte kontrol akışını gösteren biraz eğlenceli:

resim açıklamasını buraya girin

Daha önce tanımladığım yönlere göre akışı gördüğünüzde, gördüğünüz şeyin geri dönen bir çağrı olduğunu unutmayın. Bu hile Manzaraya ulaşmamıza yardımcı olmaz. İlk önce Kontrolör olarak adlandırılan şeye dönmezsek. Veya görünümü değiştirebilmeniz için tasarımı değiştirebilirsiniz . Bu aynı zamanda Veri Erişimi ve Arayüzü ile ilgili bir yo-yo sorununun başlangıcını giderir .

Burada öğrenilecek tek şey, Kullanım Senaryosu Kullanıcının sunum yapan kişiyi son çağırdığı sürece istediği sırayla işleri çağırabilmesidir.


Cevap verdiğiniz için çok teşekkürler, Temiz Mimari ile ilgili diğer çeşitli soruların cevaplarını gördüm. Görünümün, örneğin Modelde herhangi bir değişiklik olup olmadığını görmek için sürekli olarak bir bayrağı kontrol etmesini mi öneriyorsunuz? Ardından görünümün tüm Görünüm Modelini yeniden yeniden görüntülemesi gerekir mi, yoksa hangi verilerin değiştirildiğini belirtmek için bir dizi iç içe bayrak kullanmalı mıyım?
Fearnbuster

Manzara sürekli yoklamak zorunda değil. Örneğin, web 1.0 yalnızca kullanıcı yeniden yüklemeye geldiğinde yoklar. Yoklama, kullanıcıların gerçek ihtiyaçlarını dikkate almaları gereken bir tasarım kararıdır. Sadece mümkün olduğunu söylüyorum. Bir güncelleme alanının amacı, bir güncellemenin hızlı bir şekilde algılanmasını sağlamaktır. Yalnızca Görünüm Modeli karmaşıksa gereklidir. Ayrıca, sunum yapan kişi bir güncellemenin ortasındayken görünüm okursa ne olacağını düşünün.
candied_orange

Tamam, yardım için çok teşekkürler. Bu mimariyi takip ediyorsanız / izlediğinizde, bu genellikle kullandığınız teknik midir?
Fearnbuster

1
Bu cevabın tasarım bağımlılığı ve çalışma zamanı bağımlılığını birlikte gruplandırmasında büyük bir hata olduğunu düşünüyorum. İkisi farklı olabilir.
Euphoric

1
@ Euphoric Neden teşekkür ederim. Onları birbirine bağlıyorum çünkü bir şeye kaynak kodu bağımlılığınız yoksa, ne olduğunu anlamadığınız için herhangi bir şey için bir çalışma zamanı referansı kullanamazsınız. Yapabileceğiniz tek şey bir koleksiyonun yaptığı gibi referansı tutmaktır. Eğer bu bir hata ise anlamak isterim.
candied_orange

2

Bu sorunu çok kafa karıştırıcı buluyorum ve hem Martin Temiz Mimarisini hem de MVVM'yi yanlış anladığınıza inandığım için sorunu düzgün bir şekilde açıklamak çok fazla metin ve zaman alacaktı.

Dikkat edilmesi gereken ilk şey, gönderdiğiniz şemanın eksik olmasıdır. Yalnızca "iş mantığını" gösterir, ancak parçaları doğru sırada hareket ettiren bir tür "orkestratör" yoktur. resim açıklamasını buraya girin

Orkestratör kodu kadar basit olurdu

string Request(string request) // returns response
{
    Controller.Run(data);
    Presenter.Run();
    return View.Run();
}

Temiz Mimari konusundaki görüşmelerinden birinde Martin'in bunun hakkında konuştuğunu duyduğuma inanıyorum.

Dikkat çekilmesi gereken başka bir şey, candied_orange'ın döngü eksikliği hakkındaki yorumunun yanlış olduğudur. Evet, döngü kodun mimarisinde mevcut değildir (olmamalıdır). Ancak çalışma zamanı örnekleri arasındaki döngüler yaygındır ve genellikle daha basit bir tasarıma yol açar.

MVVM'de durum böyledir. MVVM View'da ViewModel'e bağlıdır ve ViewModel, View'u değişiklikler hakkında bilgilendirmek için olayları kullanır. Bu, sınıfların tasarımında yalnızca Görünümden Model sınıflarına bağımlılık olduğu, ancak çalışma zamanı sırasında View ve ViewModel örnekleri arasında döngüsel bağımlılık olduğu anlamına gelir. Bu nedenle, ViewModel kendisini ne zaman güncelleyeceğini anlamanın View yolunu sağlayacağı için orkestratöre gerek yoktur. Bu nedenle, bu diyagramdaki "bildirimler", doğrudan değil, "dalgalı" çizgi kullanır. Bu, ViewModel'in View'a bağlı olduğu değil ViewModel'deki değişiklikleri gözlemlediği anlamına gelir.

resim açıklamasını buraya girin

Martin Temiz Mimarisi'nden almanız gereken en önemli şey tasarımın kendisi değil, bağımlılıkları nasıl ele aldığınızdır. Görüşmelerinde yaptığı kritik noktalardan biri, bir sınır olduğunda, o sınırı geçen tüm kod bağımlılıklarının tek yönde geçmesidir. Diyagramda, bu sınır çift çizgi ile temsil edilir. Ve orada arayüzleri üzerinden bağımlılık ters bir sürü olduğunu ( InputBoundary, OutputBoundaryve DataAccessInterfacebu düzeltmeleri kod bağımlılık yönü).

Bunun aksine, ViewModelTemiz Mimari'de mantıksız, sade bir DTO vardır. Bu, <DS>etiket tarafından açıkça belirtilir . Ve mantık ne zaman çalıştırılacağını bilemeyeceğinden orchestrator, bu neden gereklidir View.

Diyagramı çalışma sırasında neye benzeyeceğine "düzleştirecek olsaydım" şöyle olacaktır:

resim açıklamasını buraya girin

Bu yüzden çalışma zamanı sırasında bağımlılıklar "yanlış" yöndedir, ancak bu iyidir.

Akıl yürütmesini daha iyi anlamak için Temiz Mimari hakkındaki konuşmasını izlemenizi tavsiye ederim .


"Orkestratör" niz Presenter'ı çağırmamalıdır. Kullanım Senaryosu Etkileşicisi bunu yapar.
candied_orange

@candied_orange Doğru, bu bir hatadır.
Euphoric

Cevabınız için teşekkürler, birkaç farklı görüş almak her zaman iyidir. İkinizin de cevaplarını iptal ettim. İkiniz de Robert Martin'in Mimarisinin bir formunu uyguladığı bir yerde kod tabanının olup olmadığını biliyor musunuz? FitNess projesine baktım, ama ağaçlar için ormanı göremedim. Ayrıca, yayınladığım görüntü Bob Amca'nın görüşmelerinde her zaman kullandığı diyagram olmasına rağmen, aslında mimarinizin neye benzeyebileceğinin bir örneği olduğunu düşünürken doğru muyum? Oysa bağımlılık akışı doğru olduğu sürece çok farklı görünebilir mi?
Fearnbuster

@ Sorgulayıcı Son sorunuza, evet. Bağımlılıkların yönü yapıdan daha önemlidir. "Temiz mimari", "Soğan mimarisi" ve "Altıgen mimari" nin gerçekten aynı "Bağımlılıkları kontrol altında tut" fikrinin uygulamaları olduğuna inanıyorum.
Euphoric

@Euthoric Dürüst olmak gerekirse, bunun muhtemelen böyle olduğunu söyleyebilirim, çünkü kitabının farklı bir görüntüsünde (Bölüm 8, Şekil 8.2), farklı görünen bir mimari gösteriyor. Bu şemada, Denetleyici aslında İnteraktif ve Sunum Yapan arasında bir orta düzey adamdır. Ayrıca, Etkileşimci için Çıktı Sınırı yoktur; Etkileşim bir arabirim aracılığıyla istekleri alır ve daha sonra aynı arabirim üzerinden yanıtları döndürür gibi görünüyor (Bu şekilde çalışacak başka bir mekanizma düşünemiyorum gibi, bu basit bir işlev dönüş değeri ile yapıldığını varsayalım).
Fearnbuster
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.