Veri sınıfları neden bir kod kokusu olarak kabul edilir?


18

Bu makalede, bir veri sınıfı bir "kod kokusu" olduğunu iddia ediyor. Sebep:

Yeni oluşturulmuş bir sınıfta yalnızca birkaç ortak alan (ve hatta bir avuç alıcı / ayarlayıcı) varsa bu normal bir şeydir. Ancak nesnelerin gerçek gücü, verileri üzerinde davranış türleri veya işlemler içerebilmeleridir.

Bir nesnenin yalnızca veri içermesi neden yanlıştır? Sınıfın temel sorumluluğu verileri temsil etmekse, veri üzerinde çalışan yöntemler Tek Sorumluluk İlkesini bozmaz mı?


1
Bu büyük ölçüde dil özelliklerine bağlı olacaktır. Örneğin Python'da, Python'da Java yazma yolunuzdan çıkmadıkça "alan" ve erişimcileri arasında bir ayrım yoktur .
jscs

1
Ben sadece bazı sınıflara sahip olması kendi başına bir kod kokusu olduğunu düşünüyorum, ama çoğu sınıf böyle ise o zaman biz "anemik etki alanı"
antipattern

1
Bu sorunun nasıl bir kopyası olduğunu anlamıyorum. Diğer sorular OO'da veri sınıflarının kullanımı ile ilgili iken, bu soru veri sınıflarının olumsuz yönleriyle ilgilidir - tamamen farklı konular.
Milos Mrdovic

Zengin alan adı modelinin kalitesizliğini ön plana çıkaran ve kanıtlanmış bir gerçek olarak sunan üst oylama cevabından çok daha farklı olan stackoverflow'daki bu cevabı okumak isteyebilirsiniz. stackoverflow.com/questions/23314330/…
McLovin

Yanıtlar:


31

Saf veri nesnelerine sahip olmanın kesinlikle yanlış bir yanı yoktur. Eserin yazarı açıkçası ne hakkında konuştuğunu bilmiyor.

Böyle bir düşünce, "gerçek OO" nun programlamanın en iyi yolu olduğu ve "gerçek OO" nun tamamen veri ve işlevselliği karıştırdığı "zengin veri modelleri" ile ilgili eski, başarısız bir fikirden kaynaklanmaktadır.

Gerçeklik bize, özellikle de çok iş parçacıklı çözüm dünyasında bunun tam tersinin doğru olduğunu gösterdi. Değişmez veri nesneleriyle birleştirilmiş saf işlevler, kodlamanın açıkça daha iyi bir yoludur.


1
Sadece saf veri nesnelerinin ilişkileri modelleme, doğrulama, erişimi / değişiklikleri kontrol etmek için çok değerli olabileceğini eklemek istedim.
Adrian

2
Her ne kadar argüman olarak sadece değişmez veri nesnesinin bir örneğini alan bu saf işlevlerin veri nesnesi üzerinde yöntem olarak uygulanması güzel olsa da.
RemcoGerlich

7
İşlev bu veri türünde bir argüman alırsa, zaten verilere bağlanmıştır.
RemcoGerlich

4
Bu yanlış veya en azından bir görüş meselesi olduğu için aşağı oylama. Bir OO dilinde, bir nesnenin hem verileri (hala değişmez olabilir!) Hem de ona etki eden yöntemleri içermesi mantıklıdır. Saf işlevler ve ayrı veriler diğer dil paradigmalarında mükemmeldir, ancak OO yapıyorsanız, OO'yu tamamen yapın.
Marnen Laibow-Koser

3
Gerçeklik bize birçok şey gösterdi. Dogmatik know-it-all için -1 "diğerleri başarısız oldu" düşüncesi. Ayrıca, yazar saf veri nesnelerinin "yanlış" olduğunu, sadece "kod kokusu" olduğunu ve sorgulamaya değer olduğunu söylemez. Sadece ülkem için bir vekalet verdiğim için üzgünüm. :-)
user949300

7

Saf veri nesnelerine sahip olmanın kesinlikle yanlış bir yanı yoktur. Yazarın tanıdığım yazılım geliştiricileri tarafından paylaşılmadığı bir görüşü var.

Özellikle veritabanı eşlemesi için, genel olarak yalnızca veri tabanında depolanan alanları ve alıcıları ve ayarlayıcıları içeren varlık sınıfları vardır. Wikipedia Hazırda Bekletme (çerçeve)

Java araçlarının birçok araç / çerçeve tarafından kullanılan delik fikri, yalnızca alanları ve ilgili alıcıları ve ayarlayıcıları içeren fasulye adı verilen veri sınıflarına dayanır. Vikipedi JavaBeans

Fazit:
Birisi bir şeyin 'kötü' veya 'kod kokusu' olduğunu iddia ederse, daima verilen nedenleri aramalısınız . Sebepler başka birine daha iyi nedenler veya farklı bir görüş sormanızı ikna etmiyorsa. (Bu forumda yaptığınız gibi)


Yazar, saf veri nesnelerinin "yanlış" olduğunu söylemez. Saf veri nesnelerinin bir "kod kokusu" olduğunu söylerler, bu da onları kullanma hakkında iki kez düşünmeniz gerektiği anlamına gelir.
user949300

1
@ user949300, şaşkın görünüyorsun. Yazar bunlara kod kokusu olarak atıfta bulunursa, onlarda yanlış bir şey olabileceğini belirtir. Bu günlerde çok iyi bir uygulama olarak yaygın olarak tanındıklarından, açıkça bir kod kokusu değildirler. Dolayısıyla MrSmith42 doğrudur: Onlarda kesinlikle yanlış bir şey yoktur.
David Arno

4

Martin Fowler'ın neden iyi bir argüman:

"Söyle-Sor-Ask, insanların nesne yöneliminin, verileri bu veriler üzerinde çalışan işlevlerle birleştirmek olduğunu hatırlamalarına yardımcı olan bir ilkedir. Bize bir nesneyi veri istemekten ve bu veriler üzerinde hareket etmekten ziyade, bunun yerine bir nesneye ne yapacağını söylemelidir. Bu, davranışı verilerle gitmek için bir nesneye taşımayı teşvik eder. "

https://martinfowler.com/bliki/TellDontAsk.html


1
Buradaki problem, Fowler'in işlevleri daha geniş bir kapsam istemekten sadece nesne kapsamını sormaya değiştirerek "söyleme sorma" işlevini yapay olarak kısıtlamasıdır. Hala soruyorlar. "Söyle sorma" aslında bu işlevleri argüman listeleri aracılığıyla gerçekten söyleyerek bir adım daha ileri götürülebilir. Ve böylece veri nesnelerine ulaşıyoruz ve “söylemek istemeyin” in gerçek uygulaması olan ayrı (veri bakımından) fonksiyonlar var. Dolayısıyla, veri sınıflarının bir kod kokusu olduğu iddiası için iyi bir argüman olmaktan ziyade, bunun tam tersini kanıtlar.
David Arno

2
@DavidArno Kapsülleme ve saklamayı unutuyorsun. Bir nesneye üye yöntemini çalıştırmasını söylersiniz ve üye yöntemi nesnenin kara kutusuna gider ve cevabı almak için ne gerekiyorsa yapar. Dışarıdan bir nesne sorarsanız, özel durumuna erişiminiz olmaz ve bu nedenle ya akıllıca olduğundan daha fazla durum ortaya çıkarır ya da asker gerektiğinden daha fazla kasnağa atlamak zorundadır. Neden bir OO ortamında bir nesneyi “sormuş” olduğunuzu anlamıyorum. (Diğer programlama paradigmaları elbette farklı yaklaşımlar gerektirebilir.)
Marnen Laibow-Koser

2
@DavidArno Tabii ki sen yapabilirsiniz geçmesi baziçin öncelikle ihtiyaç statik yönteme parametre olarak, ama bu yapmak sormak bunun için nesneyi. Belki de yöntemlerin birincil olduğu bir programlama paradigmasında (örneğin, fonksiyonel programlama) bu mantıklıdır, ancak bir OO ortamında kesinlikle yoktur, çünkü nesneler birincildir ve üzerinde hareket edecek verileri ve işlevleri içermelidir. Yöntemin nesneden kaldırılmasının kapsülleme oranının arttığı iddianız, tam olarak geriye doğru , söyleyebildiğim kadarıyla, çünkü artık baznesnenin dışında görünüyorsunuz demektir .
Marnen Laibow-Koser

1
@ MarnenLaibow-Koser, "OO yapıyor" olduğunu iddia etmiyorum. Kod yazıyorum ve bunu yapmak için iyi teknikler kullanıyorum. Bu tekniklerin işlevsel paradigmadan mı, yoksa OO paradigmasından mı, yoksa lanet veren paradigmadan mı ilgimi çekmediği. Bir paradigma seçmek ve ona mümkün olduğunca eksiksiz yapışmak saf dogmadır. O kötü. Saçma. Sizi boğar ve düşük kodla sonuçlanır. Yapma.
David Arno

1
@DavidArno Aksine, bir paradigmaya tamamen bağlı kalırsanız (sadece OO değil, herhangi bir iyi paradigma), güçlü üst düzey soyutlamalar ve mantıksal olarak tutarlı, sürdürülebilir kod elde edersiniz. Bunu dogmatik değil, pragmatik olarak söylüyorum. Görünüşe göre sizin gibi bir tavırla üretilen çok fazla kod gördüm ve korudum, burada yazar kullanılan sistemin mantıksal tutarlılığını gerçekten taahhüt etmedi. Anlaması zor, bakımı zor ve değiştirilmesi zor. Hiçbir paradigma mükemmel değildir, ancak genellikle (dikkatlice düşünülmedikçe) bir karışımın anlaşılması daha zordur.
Marnen Laibow-Koser

2

Anlamanız gereken şey, iki tür nesne olmasıdır:

  • Davranışı olan nesneler . Bunlar, veri üyelerinin çoğuna / herhangi birine herkese açık erişim vermekten kaçınmalıdır. Bunlar için tanımlanan çok az sayıda erişimci yöntemi bekliyorum.

    Örnek, derlenmiş bir normal ifade olabilir: Nesne, belirli bir davranış (bir dizeyi belirli bir normal ifadeyle eşleştirmek ve (kısmi) eşleşmeleri raporlamak için) sağlamak için oluşturulur, ancak nasıl derlenmiş normal ifadenin işini yaptığı kullanıcının hiçbiri değildir iş.

    Yazdığım çoğu sınıf bu kategoridedir.

  • Gerçekten sadece veri olan nesneler . Bunlar tüm üyelerini herkese açık ilan etmelidir (veya onlar için tam erişimci setini sağlamalıdır).

    Örnek olarak sınıf verilebilir Point2D. Bu sınıfın üyeleri için kesinlikle sağlanması gereken bir değişmez yoktur ve kullanıcılar verilere sadece myPoint.xve üzerinden erişebilmelidir.myPoint.y .

    Şahsen, bu tür sınıfları fazla kullanmıyorum, ama sanırım bir yerde böyle bir sınıf kullanmayan daha büyük bir kod parçası yok.

Nesne yönelimi konusunda yetkin olmak, bu ayrımın var olduğunu fark etmeyi ve bir sınıfın işlevini bu iki kategoriden birine sınıflandırmayı öğrenmeyi içerir.


C ++ 'da kod yazarsanız, bu ayrımı classnesnelerin ilk kategorisini ve structikincisini kullanarak açık yapabilirsiniz . Tabii ki, ikisi eşdeğerdir, ancak bu class, tüm üyelerin varsayılan olarak özel olduğu anlamına gelirken struct, tüm üyeleri varsayılan olarak herkese açık olarak bildirir. Tam olarak iletişim kurmak istediğiniz bilgi türüdür.


1
Downvote için bir açıklama havalı olurdu ...
cmaster - reinstate monica

Cevap için teşekkürler. İnsanlar sebepsiz yere aşağı düştüklerinde nefret ediyorum. Cevabınızla ilgili bir sorununuz varsa, nedenini açıklayın .
Sipo
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.