Business Objects - Konteynerler veya fonksiyonel?


19

Bu bir süre önce SO'ya sorduğum bir soru, ama burada daha iyi tartışılabilir ...

Çalıştığım yerde, bu konuda birkaç kez ileri geri gittik ve akıl sağlığı kontrolü arıyoruz. İşte soru: İş Nesneleri veri kapsayıcıları mı (daha çok DTO'lar gibi ) mi yoksa bu nesne üzerinde bazı işlevler gerçekleştirebilecek mantık da içermelidir.

Örnek - Bir müşteri nesnesini al, muhtemelen bazı ortak özellikler (Ad, Kimlik vb.) İçeriyor, bu müşteri nesnesi de işlevler içermeli mi (Kaydet, Kireç, vb.)?

Bir akıl yürütme çizgisi, nesneyi işlevsellikten ayırır (tek sorumluluk sorumlusu) ve işlevselliği Business Logic katmanına veya nesnesine yerleştirir.

Diğer akıl yürütme der ki, hayır, eğer bir müşteri nesnem varsa, sadece Müşteri'yi aramak istiyorum. Nesneyi tüketiyorsam bir müşteriyi kurtarmak için neden başka bir sınıf bilmem gerekiyor?

Son iki projemiz nesneleri işlevsellikten ayırdı, ancak yeni bir projeyle ilgili tartışmalar yeniden gündeme geldi.

Hangi daha mantıklı ve neden ??


1
Bize projeniz hakkında daha fazla bilgi verebilir misiniz? Projenizin doğası hangi çözümün daha iyi olduğunu belirleyecektir.

Yanıtlar:


5

Bir Müşterinin etki alanı modelinin bir parçası olduğunu düşünüyorsanız, o nesne için hem özelliklere hem de işlemlere sahip olmak mantıklıdır (özellikle DDD bağlamında ancak bununla sınırlı değildir).

Bununla birlikte, bununla birlikte, kullandığınız örneğin zayıf olduğunu ve tartışmanın bir nedeni olduğunu düşünüyorum. Kalıcılıktan bahsediyorsanız, Müşteriler genellikle kendilerini 'kurtarmaz'; kalıcılık için ne kullanırsanız kullanın. Her türlü kalıcılığın, kalıcılık katmanına / bölümüne ait olması mantıklıdır. Bu genellikle depo modelinin arkasındaki düşüncedir. ** Customer.UpgradeWarranty () veya Customer.PromoteToPreferred () gibi bir yöntem, argümanı daha açık hale getirir.

Bu ayrıca DTO'lara sahip olma olasılığını ortadan kaldırmaz . Örneğin, müşteri bilgilerini uzak bir hizmete aktaracağınız durumu düşünün. Bir müşterinin nakliye için kendi DTO'sunu yaratması mantıklı olmayabilir, bu mimari bir endişe kaynağıdır, ancak bunun için kalıcılık veya ağ katmanı / bölüm / kod / ne var. Bu durumda, böyle bir nesnenin şöyle görünen yöntemleri olabilir

public static CustomerDTO GetDTO(Customer c) { /* ... */ }

public static Customer GetCustomer(CustomerDTO cdto) { /* ... */ }

Bu nedenle, özet olarak, bir etki alanı nesnesinde, etki alanındaki mantıksal işlemlerle uyumlu işlemlerin olması mükemmel bir anlam ifade eder.

Konuyla ilgili bir dizi iyi tartışma için Google 'Kalıcılık Cehaleti' ( bu SO sorusu ve kabul edilen cevabı başlamak için iyi bir yer).

** Bu, 'Kaydet' yöntemi olan kalıcı bir tabandan miras almak zorunda kaldığınız belirli OR / M yazılımlarıyla biraz karışır.


3

Aslında son zamanlarda nesneleri verilerden ayırmak için bazı kodları yeniden çalıştı. Bunun nedeni, verilerin ayrı bir hizmet aracılığıyla elde edilmesidir ve tüm verileri ileri geri iletmek ve sunucudaki doğrulama hatalarıyla uğraşmak yerine ham verileri sunucuya / sunucudan geçirmek çok daha kolaydır.

Küçük projeler için, nesnelerin iş mantığını içerdiği ve verilerinin iyi olacağı, ancak büyük projeler veya zamanla genişleyebilecek projeler için, katmanları kesinlikle ayırırım.


3

Bunu yapmanın her iki yolunun da faydaları olabileceğini düşünüyorum, ancak ona nesne yönelimli veya alan güdümlü bir bakış açısıyla bakardım: farklı sınıfların ve nesnelerin sorumlulukları nelerdir.

Bu yüzden, somut davanızda kendime şunu sorardım: bir müşteri kendini nasıl kurtaracağını bilmeli mi?

Benim için cevap hayır olurdu: mantıklı olarak bana mantıklı değil ve bir müşterinin herhangi bir kalıcılık çerçevesi hakkında hiçbir şey bilmek zorunda kalmaması gerekir (sorumlulukların ayrılması).

SnOrfus'un Customer.UpgradeWarranty () veya Customer.PromoteToPreferred () ile ilgili örneklerine gelince, bunlar kesinlikle Customer.Save () 'den daha fazla iş mantığına yöneliktir. Bu konuda farklı yaklaşımlar vardır, ancak yine de bir müşterinin garantisini yükseltebilecek olup olmadığını kendinize sorarsanız, ona nasıl baktığınıza bağlı olarak cevap hem evet hem de hayır olabilir:

  • evet: bir müşteri elbette garantisini yükseltebilir
  • hayır: bir müşteri yeni sürüme geçirilmesini isteyebilir , ancak yükseltme başka biri tarafından yapılır

Orijinal sorunuza geri dönün; hangi yol daha mantıklı olabilir muhtemelen kime sorduğunuza ve tercih ettikleri yönteme bağlıdır, ancak en önemli şey muhtemelen bunu yapmanın bir yoluna bağlı kalmaktır.

Deneyimlerime göre, veri ve (iş) mantığını ayırmak, heyecan verici olmasa da, daha basit bir mimari sağlıyor.


2

Özellikle ActiveRecorddesen ile desen arasındaki farktan bahsettiğinizi düşünüyorum Repository. İlkinde, varlıklar kendilerini nasıl devam ettireceklerini bilirler ve ikincisinde depo kalıcılığı bilir. Bence ikincisi endişelerin daha iyi ayrılmasını sağlıyor.

Daha geniş anlamda, eğer varlıklar daha çok bir veri yapısı gibi davranıyorsa, davranışları olmamalı, ancak davranışları varsa, veri yapısı gibi kullanılmamalıdırlar. Misal:

Veri yapısı:

class CustomerController
{
    public int MostRecentOrderLines(Customer customer)
    {
        var o = (from order in customer.Orders
                orderby order.OrderDate desc
                select order).First();
        return o.OrderLines.ToList().Count;
    }
}

Veri Dışı Yapı:

class Customer
{
    public int MostRecentOrderLines()
    {
        // ... same ...
    }
}

İlk durumda, modelinizin veri yapısı ağacında, çalışma kodunuzun herhangi bir yerinden sorunsuz bir şekilde gezinebilirsiniz ve sorun değil, çünkü ona veri yapısı gibi davranıyorsunuz. İkinci durumda, Müşteri belirli bir müşteri için daha çok bir hizmet gibidir, bu nedenle sonuçta yöntemleri çağırmamalısınız. Müşteri hakkında bilmek istediğiniz her şey, Müşteri nesnesindeki bir yöntemi çağırarak erişilebilir olmalıdır.

Varlıklarınızın veri yapıları veya hizmetleri olmasını ister misiniz? Tutarlılık için, biriyle yapışmak daha iyi görünüyor. Önceki durumda, "hizmet" tipi mantığınızı varlıkta değil, başka bir yere koyun.


1

Sorunuza gerçekten cevap veremiyorum ama komik buluyorum, bu tartışmayı okuldaki projelerimizden birinde de yapıyoruz. Kendimi mantığı verilerden ayırmak istiyorum. Ancak sınıf arkadaşlarımın çoğu, nesnenin tüm mantık VE verilerini tutması gerektiğini söylüyor.

Ortaya koydukları gerçekleri yazmaya çalışacağım:

  • Business class nesnesi bir şeyi temsil eder, bu nedenle tüm veriler VE mantığı içerilmelidir. (örneğin bir kapı açmak istiyorsanız, kendiniz yaparsınız, başka birine sormazsınız. kötü örnek biliyorum)

  • Bir bu nesnenin kodunu ve işlevselliğini anlamak daha kolaydır.

  • Tasarımda daha az karmaşıklık

Onlara tembel olduklarını söylüyorum ve bunu şöyle yaparım:

  • Evet, işletme sınıfları bir şeyleri temsil eder, bu nedenle verileri tutar. Ama kendinizi kurtarmak, hatta kopyalamak yanlış geliyor. Bunu rl'de yapamazsın.

  • Nesneyi her şeyden sorumlu hale getirmek, gelecekte dayanıklılık ve sakinlik için iyi değildir. Tasarruftan sorumlu ayrı bir sınıfınız varsa, tasarıma yeni bir nesne eklerseniz, tasarruf işlevini kolayca uygulayabilirsiniz. hepsini o sınıfta tekrar kodlamak yerine.

  • Bir nesnenin veriyi sürdürebilmesi sayesinde, o nesne bir veritabanı bağlantısı tutabilir ve tüm veritabanı trafiği bu nesneye yönlendirilir. (temel olarak veri erişim katmanıdır) aksi takdirde tüm Business nesnesinin bir bağlantıya sahip olması gerekir. (karmaşıklık katar)

Öyle ya da böyle, bir öğretmene soracağım. Bunu yaptığımda, cevabını burada da göndereceğim. ;)

Düzenle:

Bu projenin bir kitapçı ile ilgili olduğunu söylemeyi unuttum.


Sınıf arkadaşlarınız haklıdır, ancak iş mantığını diğer mantık biçimleriyle karıştırırlar (bu durumda mimari veya kalıcılık mantığı).
Steven Evers

1

Yanıt gerçekten mimarinizin / tasarımınızın ne olduğuna bağlı olacaktır - bir etki alanı modeline sahip bir DDD mimarisi, nesne tasarımı söz konusu olduğunda CRUD veri merkezli bir modelden çok farklı olacaktır.

Bununla birlikte, genel olarak, nesne yönelimli tasarımda durumu kapsüllemeye ve davranışı ortaya çıkarmaya çalıştığınızı unutmayın. Bu, genellikle bir davranışla ilişkili durumu bu davranışa olabildiğince yakın tutmaya çalışacağınız anlamına gelir - bunu yapamadığınızda durumu bir şekilde veya başka bir şekilde göstermeye zorlanırsınız.

Bir etki alanı modelinde, iş modelini altyapı kaygılarından ayırmak istersiniz - bu nedenle '.Kaydet' gibi yöntemlerden kesinlikle kaçınmak istersiniz. Bir müşteriyi en son "gerçek hayatta" kurtardığımı hatırlamıyorum!

Bir CRUD uygulamasında veriler birinci sınıf vatandaştır, bu nedenle ".Save" tamamen uygundur.

Çoğu gerçek dünyadaki uygulamalar, bu paradigmaların bir karışımına sahip olacak - hızla değişen veya karmaşık iş kurallarının bulunduğu etki alanı modeli, sınırları aşan veri aktarımı için DTO'lar, CRUD (veya CRUD ile activerecord gibi bir etki alanı modeli arasında bir şey). Her kurala uyan tek beden yoktur.


0

Bir süredir aynı soru üzerinde duruyorum - Bence veri bileşeni ve mantık bileşeni ayrı olmalıdır. Buna inanıyorum çünkü anlam sağlayan verilere bir arayüz olarak iş mantığına ilişkin olarak sizi aklın doğru çerçevesine sokar.

Ben de Scott Whitlock'un bakış açısını yukarıdan modifiye ederdim (yeni bir üye olmak için hiçbir puanım hariç), veri veya iş mantığı sınıfları gerçekten nesnenin kalıcı olarak nasıl saklandığı konusunda endişelenmemelidir.

Bununla birlikte, mevcut bir ürünle uğraşıyorsanız, temiz, sözleşmeli arayüzleriniz olduğu sürece - bu da tamam ve bakımı kolaydır ...

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.