Uzlaşmak zorundayım: KURU veya Komut-Sorgu-Ayırma?


10

Son zamanlarda bir komut ve bir sorgu yöntemi olan bir yöntemi refactoring.

Bir komut yöntemi ve bir sorgu yöntemine ayırdıktan sonra, şimdi kodu çağırıyorum sonra DRY ilkesinin ihlali gibi görünüyor sorgudan değeri almak nerede kodda birden çok yer olduğunu buldum.

Ama bu ortak kodu bir yönteme sarmak olsaydı, bu yöntem hem komut hem de sorgu olurdu. Bu kabul edilebilir mi?


tamam, topluluğun fikir birliği içinde olup olmadığını bilmiyordum ve bu konuyla ilgili herhangi bir tartışma bulamadım.
Kris Welsh

Daha yaygın olarak CQRS olarak adlandırılır google.com.au/…
Daniel Little

@DanielLittle - hayır değil. CQS ve CQRS belirgin şekilde farklı konulardır. CQRS çok daha karmaşık bir mimari model iken, CQS daha fazla tasarım deseni ve kavraması ve uygulaması daha kolaydır. Bkz. Codebetter.com/gregyoung/2009/08/13/command-query-separation
Erik Funkenbusch

@Erik Funkenbusch Haklısın
Daniel Little

Yanıtlar:


11

Çelişen tasarım ilkeleri arasında daima göz önünde bulundurulması gereken değişimler vardır. Bunu çözmenin yolu, ilkelerin ardındaki temel nedenlere bakmaktır. Bu durumda, komutu çalıştırmadan bir sorguyu çalıştıramamak sorunludur, ancak sorguyu çalıştırmadan bir komutu çalıştıramamak genellikle zararsızdır. Sorguyu tek başına çalıştırmanın bir yolu olduğu sürece, özellikle de böyle bir şey yapılırsa, sorgu sonucunu komuta eklememek için hiçbir neden göremiyorum:

QueryResult command()
{
   // do command stuff
   return query();
}

4

Daha önce Komut-Sorgu-Ayırma (CQS) duymadım, ancak bir işlevin / sınıfın ideal olarak sadece bir şey ve bir şey yapmaktan sorumlu olması gerektiğini belirten Tek Sorumluluk İlkesi (SRP) ile ilgili olacağı anlaşılıyor. .

Komut kodunuz 20 satır kod ve sorgu kodu başka bir 30 satır ise ve hepsi bir işlev gövdesindeyse, SRP'yi ihlal ediyorsunuz ve CQS'yi de varsayıyorum ve bu iki mantık birbirinden ayrılmalıdır. .

Ancak, varsayımsal örneğinizle giderken, büyük olasılıkla DRY'nin kodun çeşitli yerlerinde ihlal edilmemesi için komutunuzu ve sorgunuzu birleştirecek bir sarmalayıcı yöntemi oluşturacağım. Ben de sarıcı hala tek bir sorumluluğu var: SRP (ve belki CQS) ihlali olarak düşünmek olmaz: komut bir sorgu ile birleştirmek ve tüketmek daha kolay bir üst düzey soyutlama oluşturmak.

Sarma yönteminin mükemmel kabul edilebilir bir çözüm olduğunu düşünüyorum ve bunu göstermek için örneğinizi bir adım daha ileri götürelim. 1 yerine 2 sorgu çalıştırıp ardından buna dayalı bir komut eylemi yapmanız gerekiyorsa ne yapmalısınız? Yani 2 kod satırınız 6 veya 8 olur. Ya biri ile diğeri arasında veri doğrulama / kontrol olsaydı, şimdi 15 kod satırınız var. Bu 15 satırı birden fazla dosyaya serpmek yerine, tüm bunları yapan bir sarıcı oluşturma hakkında iki kez düşünür müsünüz?


Ben bir sarıcı "tek ilke" komut ve sorgu birlikte DRY gerektiren diğer yöntemleri tutmak için olması gerektiğini düşünüyorum.
Droogans


Karl'ın bu soruna çözümü daha iyi olsa da, uzun sarmalayıcı işlevlerine ilişkin detaylandırmanızı çok iyi bir nokta olarak görüyorum.
Kris Welsh

-3

DRY daha önemlidir, çünkü çok daha temel bir ihtiyacı çözer - gereksiz, etkili boşa harcanan çabayı önler. Bu temel bir şeydir - bunu anlamak için programcı olmak gerekmez.

CQS, izleme sonuçları için desteği olmayan dillerde, hem sonuçları hem de etkileri için yürütülen kodu anlama zorluğuna bir yanıttır. Ancak:

  1. Sonuçları için kod yürütme zorunluluğundan kaçınılamaz, çünkü bu küçük birimlerden büyük programlar oluşturmanın temelidir.

  2. Etkileri için kod yürütme zorunluluğundan da kaçınılmaz, çünkü matematik ve teorik bilgisayar bilimi dışında, bir program yürütmenin değeri, gözle görülür şekilde bizim için yapabileceklerine dayanır.

  3. Etkilere neden olma ve aynı kodda sonuç üretme zorunluluğundan kaçınılamaz, çünkü pratikte, sadece birine veya diğerine değil, hem etkilere hem de kompozisyona ihtiyacımız vardır.

Etkileri izlemenin insanlar için çok zor olması sorununa asıl çözüm, elbette bilgisayarların bize insanlara yardım etmesini sağlamaktır ! Benzer bir şey, istisnaların ve çalışma zamanı tarafından zorlanan sözleşmelerin (olmayan) çözümler oluşturduğu çalışma zamanı değerleri (dizi indekslerinin geçerliliği gibi) arasındaki karmaşık ilişkilerin izlenmesi hakkında söylenebilir .

Sonuç olarak, CQS gibi "çözümler" sadece gerçekliğe dayalı sağlam ilkelere göre program tasarlama yolunda ilerlemektedir. KURU'ya git.


Bazen karmaşıklığı azaltmak için kuplajdan kaçınmanız gerekir. CQRS'ye bir göz atmalısınız.
Daniel Little

@Lavinski: Karmaşıklığı önlemek için en iyi araç (azaltmak değil, boşuna) soyutlamadır - çözdüğümüz sorunların genel özünü, söz konusu genel sorunların örneklerinin belirli detaylarından ayırmaktır. Büyülü tarifler (ya da "tasarım desenleri" olarak adlandırıldığını duydum) en iyi tasarımınızı yanlış yaptığınızda çok fazla hasara neden olabilir, ancak yanlış bir tasarımı doğru olana dönüştüremezler.
pyon

@Lavinski: CQRS ile ilgili olarak, kavramsal olarak doğru alternatif çözüm 1. veri modelini anlar (hiçbir nesne katmanı bunun gerekliliğini ortadan kaldıramaz), 2. veritabanı şemasında mümkün olduğunca çok doğruluk özelliği kodlar. (Ne yazık ki, en popüler RDBMS'ler, daha da yanlış olan NoSQL olanlardan bahsetmemek için, ikincisi için oldukça sınırlı destek sağlar. Mevcut araştırmam bunun için daha iyi bir çözüm sunuyor.)
pyon

CQRS, Etki Alanına Dayalı Tasarım ile tamamen uyumlu bir şekilde çalışır. Biraz araştırma yapmanızı öneririm. Uygulama içindeki Alan adı, veri deponuz için değil doğruluğu zorunlu kılmalıdır.
Daniel Little

1
@ EduardoLeón: Tasarımınızın doğru olduğunu kanıtlamak istiyorsanız, programınız için testler yazmaya çalışın. CQS atmanın sadece bu konudaki çabalarınızı engelleyeceğini garanti edebilirim.
Stefan Billiet
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.