Görünüm modellerinde iş nesnelerini kullanma


11

Yeniden kullanılabilir iş nesneleri kullanırken, görünüm modelleri oluştururken en iyi uygulama nedir?

BuilderGörünüm modellerimizi oluşturmak için çağırdığımız bir nesne kullanıyoruz . Her bir mantıksal görünüm birimi (siparişler, kullanıcılar vb.) İçin bir oluşturucu; burada her birim bir dizi farklı görünüm modeli içerebilir (siparişler özet, sipariş satırları vb. İçerir).

Bir üretici, bir görünüm modeli oluşturmak için verileri bir veya daha fazla standart iş nesnesinden alabilir.

Görünüm modellerinde iş nesnelerini / modellerini kullanma konusunda daha iyi uygulama nedir?

Yaklaşım 1

Görünüm modelinde iş nesnelerinin kullanılmasına izin verilsin mi?

//Business object in some library
public class Order
{
    public int OrderNum;
    public int NumOrderLines;
    //...
}

//Order builder in website
public class OrderBuilder
{
    public OrderSummary BuildSummaryForOrder(int OrderNum)
    {
        Some.Business.Logic.Order obOrder = Some.Business.Logic.GetOrder(OrderNum);
        //Any exception handling, additional logic, or whatever

        OrderSummary obModel = new OrderSummary();
        obModel.Order = obOrder;

        return obModel;
    }
}

//View model
public class OrderSummary
{
    public Some.Business.Logic.Order Order;
    //Other methods for additional logic based on the order
    //and other properties
}

Yaklaşım 2

İşletme nesnelerinden yalnızca gerekli verileri alın

//Business object in some library
public class Order
{
    public int OrderNum;
    public int NumOrderLines;
    //...
}

//Order builder in website
public class OrderBuilder
{
    public OrderSummary BuildSummaryForOrder(int OrderNum)
    {
        Some.Business.Logic.Order obOrder = Some.Business.Logic.GetOrder(OrderNum);
        //Any exception handling, additional logic, or whatever

        OrderSummary obModel = new OrderSummary()
        {
            OrderNum = obOrder.OrderNum,
            NumOrderLnes = obOrder.NumOrderLines,
        }

        return obModel;
    }
}

//View model
public class OrderSummary
{
    public int OrderNum;
    public int NumOrderLines
    //Other methods for additional logic based on the order
    //and other properties
}

Her ikisinin de yararlarını ve dezavantajlarını görebiliyorum, ama kabul edilmiş bir yaklaşım olup olmadığını merak ediyorum. Yaklaşım 1'de, kodların modellerin çoğaltılması söz konusu değildir, ancak iş mantığına bağımlılık yaratır. 2. yaklaşımda, yalnızca görünüm için gereken verileri alırsınız, ancak kodlar modellerin çevresinde çoğaltılır.

Yanıtlar:


12

Seçenek 1, etki alanı modeli ile görünüm arasında sıkı bir bağlantı oluşturur. Bu, modellerin çözmek için tasarladıkları çok problemli görüşlere aykırıdır.

Bir görünüm modelleri "değiştirmenin nedeni" görünümün kendisinin değişmesidir. Görünüm modeline bir etki alanı modeli nesnesi koyarak, değiştirmek için başka bir neden sunuyorsunuz (ör. Etki alanı değişti). Bu, tek sorumluluk ilkesinin ihlal edildiğinin açık bir göstergesidir. Değiştirmek için iki veya daha fazla nedene sahip olmak, çok fazla bakım gerektiren modellere yol açar - muhtemelen alan / görünüm modellerinde yinelenen bakım maliyetinden daha fazladır.

Her zaman yaklaşım 2'yi savunurdum. Genellikle görünüm modellerinin etki alanı modeli nesnelerine bile çok benzer görünebileceği, ancak bahsettiğim ayrım, değişikliğin farklı nedenleridir.


"Değişim nedeni" ile bir bakım anlamında değişiklik demek olduğunu, güncelleme (örn. Ui olayı) anlamında değişiklik demek olmadığını düşünerek haklı mıyım?
Andy Hunt

@AndyBursh evet - bu makaleye bakın , özellikle "Robert C. Martin bir sorumluluğu değişim nedeni olarak tanımlar ve bir sınıfın veya modülün bir tane ve sadece bir tane de değişiklik nedeni olması gerektiğine karar verir."
MattDavey

Cevabınızı seviyorum ama bazı düşünceler ... Görünüm modeli sadece model değiştiği için değişmiyor. Yalnızca bağlandığınız veya değişen belirli bir özelliği kullanıyorsanız, başvurunuz tüm nesneye yönelik olduğundan bu sorun olur. Etki alanı nesnesine başvuru olması, değişiklik yapmayı ve yeniden kaydetmeyi kolaylaştırır. Kaydetme yöntemleriniz de etki alanı nesnesine bağlıdır, bu nedenle görünüm modelini geri dönüştürmeniz veya iş yönteminizin iyi olmayan görünüm modellerini kabul etmesi için ayarlamanız gerekir. Hala # 2'nin en mantıklı olduğunu düşünüyorum, ama sadece iki sent.
KingOfHococrites

Bir VM'de etki alanı nesneleriniz yoksa, bir Siparişler dizisi gibi daha karmaşık bir şeyi nasıl temsil edersiniz?
Jeff

Yani bu, örneğin, kullanıcı görüntüleme için bir zaman damgasının biçimlendirilmesi , alan katmanına değil görünüm katmanına ait olmalıdır ve alan düzeyi nesneleri, görünüm nesnelerine yalnızca ham, biçimlendirilmemiş bir zaman damgası döndürmelidir; biçimlendirici mantığı içerir mi?
The_Sympathizer

2

Seçenek 1 kod çoğaltılmasını önlediği için tercih edilir. Bu kadar.

Etki alanı modeli önemli ölçüde değişirse, görünümün yine de değişmesi gerektiği neredeyse kesindir. Seçenek 2 ile, görünüm modelini VE oluşturucuyu ve görünümün kendisini değiştirmeniz gerekir. Bu tür şeyler sakatlık için mutlak zehirdir. YAGNI.

Ayrı bir görünüm modeline sahip olmanın amacı, yalnızca görünüm için anlamlı olan durumu (örneğin, şu anda seçili olan sekme) iş modelinden ayrı tutmaktır. Ancak işletme verilerinin kendisi çoğaltılmak yerine yeniden kullanılmalıdır.


YAGNI - çoğu yazılım tasarım problemini çözmenin gizli suikastçısı.
Martin Blore

6
Üzgünüm ama bu en önemsiz uygulamalar hariç herkes için korkunç bir tavsiye. Görünüm modellerinde durum yok. Veri aktarım nesneleridir. Hangi sekme seçildiğinde, görünümün YAPISI'nın bir parçasıdır ve görünüm modelinde VERİ ile ne kadar ilgiliyse YAPILMAZ. Programınızı doğru bir şekilde yapılandırırsanız ve görünüm modellerinizi nemlendirmek için Automapper gibi bir şey kullanırsanız bakım bir kabus değildir.
Lucifer Sam

"Etki alanı modeli önemli ölçüde değişirse, görünümün yine de değişmesi neredeyse kesin." - Kabul. Peki etki alanında küçük bir değişiklik olduğunda ne olur? Birinci seçenekle, alan adındaki her küçük değişiklik (yalnızca bir mülkü yeniden adlandırmak bile) görünümde karşılık gelen bir değişiklik gerektirir. Bu aynı zamanda sürdürülebilirlik için mutlak bir zehirdir.
MattDavey

@MattDavey: Bir mülkü yeniden adlandırırsanız, ayrı bir görünüm modeliyle görünümü de değiştirmeniz gerekir (veya alan ve görünüm modeli arasında herhangi bir harita) ve şimdi aynı şey için karışıklığa neden olacağı kesin olan iki farklı adınız vardır.
Michael Borgwardt

@Lucifer Sam: Bir görünüm modelinin ne olduğu konusunda çok farklı kavramlarımız var. Senin gibi, bana çok ama çok garip geliyor, aptal terminaller için anabilgisayar uygulamalarını tarif ediyorsun, ama kesinlikle modern web veya yağ istemci uygulamaları değil.
Michael Borgwardt

2

İlkeler ve mantralar bazen tasarımı yönlendirmek için değerlidir ... ama işte pratik cevabım:

Görünüm modellerinizin JSON veya XML olarak serileştirildiğini hayal edin. Etki alanı modellerinizi denemeye ve serileştirmeye çalışırsanız, iğrenç bir metin karmaşasıyla sonuçlanacak ve büyük olasılıkla dairesel referanslar ve diğer sorunlarla karşılaşacaksınız.

Bir görünüm modelinin amacı, görünümün bunları tüketebilmesi için etki alanı modellerini birlikte gruplandırmak değildir. Bunun yerine görünüm modeli, görünümün tamamen düz bir modeli olmalıdır ... ekranda baktığınız gerçek şey. Görünüm mantığınız yalnızca görünüm modelinde mevcut olan verilerin yapılandırılmasıyla ilgilenmelidir.

İdeal olarak görünüm modeliniz neredeyse tamamen önceden biçimlendirilmiş dizelerden oluşmalıdır. Bir düşünün ... Görünüm modelinizde bir DateTime veya ondalık bile istemezsiniz çünkü o zaman C #, Javascript, Objective-C, vb.


2
Etki alanı modellerinin serileştirilmesinde hiç sorun yaşamadım. Ve her şeyi bir modeldeki dizelere dönüştürmek? Ciddi anlamda?
Michael Borgwardt

3
@MichaelBorgwardt Evet, bu bir görünüm modeli olmalı. Alan adı modellerinizi serileştirmek ve her yere göndermek istemezsiniz. Tüm iş mantığı evde tek bir yerde güvenle kalmalıdır. Ancak görünümler esnek olmalı ve herhangi bir cihazda oluşturulabilmelidir, bu nedenle YAPI, VERİ ve TARZınızı tamamen ayırmak istersiniz.
Lucifer Sam

Üzgünüz, ama bu herhangi bir uygulama için korkunç bir tavsiye, dönem. Esnekliğin tam tersi olan yinelenen kodlarla dolu aşırı mühendislik uygulamalarına yol açar.
Michael Borgwardt

1
@MichaelBorgwardt, varlıkların çok az davranışa sahip olan veya hiç davranmayan mülk torbalarından biraz daha fazla olduğu anemik alan modelleriyle çalışmaya alışkınsınız. Bu durumda evet, bir DTO / View modeli temel olarak bir kopya olacaktır. Ancak, karmaşık ilişkileri olan zengin bir etki alanı modeliniz varsa, bir DTOs / View-model katmanı gerekli hale gelir ve etki alanı varlıklarına çok benzemez.
MattDavey

@MattDavey: Kulağa alışkın olduğunuz alan modellerinin sadece zengin değil gerçek kleptokratlar olduğu anlaşılıyor. Anemik modelleri de sevmiyorum, ama yine de modeller ve davranışları etki alanını temsil etmekle sınırlı olmalı. Tek sorumluluk ilkesi ve tüm bunlar ...
Michael Borgwardt
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.