Çift kodu kabul edebileceğimiz istisnai durumlar var mı?


57

Üç API oluşturmak zorunda olduğumuz bir yazılım projesi üzerinde çalışıyorum. Biri ev bankacılığı kanalı, biri ajans kanalı ve üçüncüsü mobil kanal için.

Ajans API'sı, tüm işlevselliklere sahip olduğu için en eksiksiz olanıdır ... daha sonra biraz daha küçük Ev API'si ve sonra mobil API.

Buradaki mimarlar ortak bir katman oluşturdu (tüm API'ler tarafından paylaşılan çapraz kanal EJB hizmetleri). Ancak daha sonra API'ler farklıdır.

Şimdilik API'ler arasında büyük bir fark yoktur. Büyük ekip ajans kanalıyla başladı ve şimdi ana kanal için uyarlıyoruz. Sadece özellikle uygulamamıza özel nesneleri zenginleştiriyoruz. Aksi takdirde, kod API'ler arasında% 95 oranında benzerdir. API'ler Spring MVC üzerine kuruludur ve sahiptir (kontrolörleri, modelleri ve bazı yardımcı programları).

Temelde kontrolörler BO'yu ChannelObject ile eşleştiriyorlar (bunu yapmak için doğru bir yer değil gibi görünüyor) ve bazı ekstra yardımcı programlar ve serileştiriciler. Hepsi şimdilik kopya. Yinelemenin sebebinin API'lerin bağımsız olmasını istediklerini söylüyorlar. “Yarın ev için ajanstan veya mobilden farklı bir davranış istiyorsak mücadele etmeyeceğiz!”

Çift kodu kabul etmemiz gereken bir durum var mı?


22
Ve eğer üç kişi yolda ilerlerse, tüm API'ler arasında tutarlı veri erişimi ve temsil edilmek istediklerine karar verirler ... peki ... "Mücadele!"
Becuzz,

26
Yinelenen kod mutlaka kötü bir şey değil. "KURU ayrıştırmanın düşmanıdır" ifadesi yeterince vurgulanamaz. Bunu söyleyerek, şu an için değil geleceği tasarlamanın gerçekten çok kötü bir şey olduğunu söyledi. Bu gelecek neredeyse asla geçmiyor. Bunun yerine, şu anda ihtiyaç duyulanlar için iyi otomatik testler tarafından kapsanan, yüksek oranda çözülmüş bir çözüm tasarlayın. Sonra, gelecekte farklı bir şeye ihtiyaç duyulursa, değiştirilmesi daha kolay olacaktır.
David Arno

2
Sanırım çoğaltma kodundan hiç pişman olmadığım iki durum (a) çoğaltılmış kodun toplamın çok küçük ve çok önemli bir parçası olmadığı ve (b) kodu zaten ölmekte olan bir sistemden kopyaladığım yer uzun ömür için tasarlanmış yeni bir sisteme. Kodları okuduktan sonra acı gözyaşı ağladığım birçok başka durum var.
Michael Kay,

14
Çalıştığım yerde, sık sık birinin bir kez (çoğu zaman) tekrar etmesi ve üçüncü kez ortaklığı soyutlaması gerektiği belirtildi. Bu, zeitgeist'i , birleşme yerine eşleşmeyi artıran erken, muhtemelen uygun olmayan soyutlama için kaldırır . Gelecekteki gereksinimler gerçekten iyi anlaşıldığında, elbette istisnalar yapılabilir.
Pieter Geerkens

3
Çift kodun kabul edilebilir olabileceği önemsiz bir durum, otomatik olarak oluşturulmuş olması durumundadır
samgak

Yanıtlar:


70

Çoğaltma yapılacak doğru şey olabilir , ancak bu nedenle değil.

"Kod tabanındaki bu üç yerin şu anda farklı olsa da farklı olmalarını isteyebiliriz" demek, büyük ölçekli kopyalamalar için iyi bir neden değildir. Bu kavram her sistem için geçerli olabilir ve herhangi bir çoğaltmayı haklı çıkarmak için kullanılabilir , ki bu açıkça makul değildir.

Çoğaltmaya yalnızca başka bir nedenden ötürü şimdi genel olarak daha maliyetli olacağı zaman tolere edilmelidir (şu an için iyi bir şey düşünemiyorum, ancak bir tane olabileceğinden emin olabilirsiniz - hemen hemen programlamadaki her şey bir takastır) yasa).

Yaptıklarınız için doğru çözüm, örneğin, şu anda çoğaltılmış olan davranışı bir Stratejiye veya davranışı sınıf olarak modelleyen ve aynı sınıfın üç örneğini kullanan başka bir kalıba çıkarma olabilir . Eğer Bu yolla, yok üç yerden birinde davranışını değiştirmek istiyorum, sadece yeni bir Strateji oluşturmak ve tek bir yerde olduğunu örneğini gerekiyor. Bu şekilde yalnızca bazı sınıflar eklemeniz ve kod tabanının geri kalanını neredeyse tamamen dokunulmadan bırakmanız gerekir.


1
İki şey aynı şekilde davranırsa, bu çoğaltmadır. Aynı nedenden dolayı aynı şekilde davranmadıkları sürece birleştirilmemeleri gerekir. Biri uygulamaların ortak bir kısmını çıkarabilir mi? Bazen henüz soyutlanmayan yapı taşları var, kim bilir.
Deduplicator

32
Örnek olarak, uygulamamızın üç bölümü tarafından kullanılan bir kod parçası vardı ve bu üçünün istisnalarını kapsayan her yerde çok sayıda küçük koşullu dallar vardı. Ancak , bu önemli biti, iki yıl boyunca herhangi bir önemli hata raporu vermeden yoğun bir şekilde kullanılıyordu. Bu nedenle, başvurunun dördüncü bir kısmı onunla bir şey yapması gerektiğine rağmen yine de biraz farklı olmasına karar verince , kusursuzca çalışan hatalı koda dokunmama ve sadece kopyalayıp, daha iyi yazılmış, esnek bir temel oluşturma kararı alındı . gelecek.
KRyan

2
Çoğaltma, birbirine bağlı kalma bakım maliyetleriyle karşılaştırıldığında, okunabilirlik maliyetleri çok artarsa ​​yapılacak doğru şeydir. Bunun bu senaryoda hiç bir şekilde geçerli olduğunu sanmıyorum ve genellikle böyle bir şey değil bir projede daha küçük ölçekte görülür. O zaman bile, durumun böyle olduğu bir duruma girmeniz çok nadirdir, sizi Şablon Yöntemi desenini veya benzerlerini küçük yerlerde kullanmaya zorlayacak bir iç içe yineleme varsa, olur. Bu genellikle gizleme koduna neden olur.
opa

Çoğaltılması yararlıdır bir örneği (ve "bu genel olarak daha pahalı olabilir oftpd çıkarılması hemen internet uygulamalarında giriş Endüstride benzetim olan"): Kullanıcı sorunları anında geri bildirim alır böylece istemcide bir birinci (belki de basitleştirilmiş) doğrulama kullanır; ve sonra istemcilere güvenilemediğinden, sunucuda aynı (veya daha fazla) doğrulamayı yaparız.
Hagen von Eitzen

3
@HagenvonEitzen Ancak bu teknoloji yığına bağlı olarak çoğaltılması gerekmiyor. Örneğin, tarayıcıda JavaScript kontrol girişine ve ardından sunucuda Java kontrolüne sahip olabilirsiniz, böylece çoğaltılmış bir işlevselliğe sahip olursunuz. Ancak sunucuda Node.js çalıştırıyorsanız, tarayıcıda ve sunucuda aynı JavaScript doğrulamasını kullanabilir ve çoğaltmayı ortadan kaldırabilirsiniz. Kodun hala birden çok yerde (güvenilir ve güvenilmeyen bir ortamda) çalışmasını istiyorsunuz , ancak kodun mutlaka kopyalanması gerekmez.
Joshua Taylor,

87

Ruby ekosisteminde tanınmış bir yazılım mühendisi ve yazarı olan Sandi Metz'in harika bir blog yazısı ve çoğaltma ile soyutlama arasındaki ilişkiden bahsettiği bir konuşma var . Aşağıdaki sonuca varıyor

çoğaltma yanlış soyutlamadan çok daha ucuzdur

Ve onunla tamamen aynı fikirdeyim. Size bu alıntıya daha fazla bağlam vereyim. Bazen doğru soyutlamayı bulmak çok zordur. Bu gibi durumlarda, çoğaltmayı azaltmak için herhangi bir soyutlamaya gidilmesi cazip gelir . Fakat daha sonra, soyutlamanızın tüm durumlar için geçerli olmadığını öğrenebilirsiniz. Bununla birlikte, her şeyi tekrar değiştirmek ve farklı bir rotaya gitmek pahalıdır (daha iyi bir açıklama için konuşmasını izleyin!).

Bu yüzden evet, benim için, çoğalmayı kabul etmenin doğru karar olduğu, özellikle ne geleceğinden emin olmadığınızda ve gereksinimlerin değişmesi muhtemel olduğunda, istisnai durumlar vardır. Görevinizden şimdi çok fazla çoğaltma olduğunu kabul ediyorum, ancak meslektaşlarınız bunun değişebileceğini ve her iki uygulamayı da birbirleriyle birleştirmeyeceğini öne sürüyorlar. Bence bu geçerli bir argüman ve genel olarak göz ardı edilemez.


23
Ah evet, genelleştirilmiş kuralları çıkaramazsanız, onları soyutlamaya çalışmak sadece başarısız olabilir. Eğer yazışmalar tesadüf ise, kısa ömürlü olabilir.
Deduplicator

5
Yerine yerleştirdikten sonra bir soyutlamayı değiştirmek pahalı olabilir, ancak yerindeyken çoğaltmadan kurtulmak daha da zor olabilir. Elbette bu dile vb. Çok bağlıdır - modern güçlü-statik tip sistemler, bazı soyutlama işlemlerinde doğru şekilde büyük çaplı değişiklikler yapmanıza yardımcı olmak için iyi bir iş yapabilir. Bununla birlikte, çoğaltılmış özellikleri senkronize tutmak bir tür sistemin size çok yardımcı olabileceği bir şey değildir (çünkü çoğaltmalar , tür sistemine göre yalnızca farklıdır). Ancak, dinamik, ördek tipli dillerde, bunun tersi bir yol olduğunu düşünüyorum; bu yüzden Ruby için mantıklı olabilir.
leftaroundabout

34

İnsanlar tasarımı hakkında “yarınsa” kelimesiyle düşünmeye başlarlarsa , bu, özellikle argümanın, ek iş ve emek içeren bir kararın gerekçelendirilmesi için kullanıldığında, özellikle de hiç kimsenin bilmeyeceği bir kimsenin bilmediği, bu benim için büyük bir uyarı işaretidir. karşılığını almaktan daha zordur ve değiştirmek veya geri almak daha zordur.

Kodun çoğaltılması, yalnızca kısa bir süre için çabayı azaltır ancak yinelenen kod satırlarının sayısıyla orantılı olarak bakım çabalarını neredeyse anında artıracaktır. Ayrıca, kod bir kez çoğaltıldığında, bu yanlış bir karar olduğu ortaya çıktığında çoğaltmanın kaldırılması zorlaşacaktır; oysa şimdi kod çoğaltılmazsa, daha sonra DRY'ye yapışırsa çoğaltmayı uygulamak kolaydır. yanlış karardı.

Daha büyük kuruluşlarda, bazen farklı ekiplerin DRY ilkesine göre bağımsızlıklarını desteklemenin yararlı olacağını söyledi. API'lerin% 95 ortak bölümünü çıkararak kopyalamanın kaldırılması, iki yeni bileşen, aksi takdirde bağımsız iki takımın birleşmesine yol açarsa, bu en akıllıca karar olmayabilir. Öte yandan, kısıtlı kaynaklarınız varsa ve her iki API'yi de koruyan tek bir ekip olacaksa, çifte çaba yaratmamanın ve gereksiz kod yinelemelerinden kaçınmanın kendi yararına olacağına eminim.

Ayrıca, "Ev" ve "Ajans" API'lerinin tamamen farklı uygulamalar tarafından özel olarak kullanılması veya bir "Ev" bağlamında kullanılabilecek API'lerin üstüne bir bileşen yazmaya çalışılması durumunda fark yaratabileceğini unutmayın. "Ajans" bağlamında olduğu gibi. Bu durum için, API'lerin ortak bölümlerinin tamamen aynı olması (yalnızca ortak bölümlerin kopyalanmaması durumunda garanti verebileceğiniz), bu tür bir bileşenin geliştirilmesini muhtemelen çok daha kolay hale getirecektir.

Öyleyse, her biri farklı bir programa ve kaynağa sahip olan her biri API'den sorumlu olan, her biri farklı bir alt ekip olacak, o zaman kodu kopyalamanın zamanı geldi, ancak "sadece durumda" değil.


3
Benim için "yarın" dan bile daha büyük uyarı işareti "Bu asla değişmeyecek".
abuzittin gillifirca

@ abuzittingillifirca: Bunun soru veya cevabımla ne ilgisi var?
Doktor Brown

1
İlk paragrafını zorluyorum.
abuzittin gillifirca

2
@ abuzittingillifirca: peki, soruyu tekrar okuyunuz: geri dönüşü zor olan çoğaltma kararını doğrulamak için "yarın eğer" argümanının gerekçelendirilmesi ile ilgilidir , bu nedenle yazılımın bazı durumlarda değiştirilmesini gerçekten zorlaştırır. Biraz sezgisel olabilir, ancak yazılımı gelecek için değişebilir kılmanın en iyi yolu geleceğe ilişkin (muhtemelen yanlış) varsayımlarda bulunmak değil, yazılımı olabildiğince küçük ve SOLID olarak tutmaktır.
Doktor Brown

13

Eşleşmeyi önlemek için çoğaltma . İki büyük sisteminiz olduğunu ve aynı kütüphaneyi kullanmaya zorladığınızı varsayalım. Her iki sistemin de yayın çevrimini birleştiriyor olabilirsiniz. Bu çok kötü olmayabilir, ancak diyelim ki bir sistem bir değişiklik getirmeli. Diğerinin değişimi analiz etmesi gerekiyor ve etkilenebilir. Bazen bir şeyleri kırabilir. Her iki taraf da değişiklikleri koordine edebilse bile, yöneticiler, testler, bağımlılıklar ve küçük özerk ekibin sona ermesi birçok toplantı olabilir.

Yani, özerklik ve bağımsızlık kazanmak için kopya kodun bedelini ödüyorsunuz.


Yani bu eşleşmeyi önlemek için bileşenler arası çoğaltmadır. Fakat yine de bileşen içi yinelemeden kaçınmak istersiniz, değil mi?
TemplateRex,

Evet, kodunuzun anlaşılmasını ve değiştirilmesini kolaylaştıracağından kopyalanan kodu en aza indirmek istersiniz. Ancak, uygulanabilir istisnalar dışında iyi cevaplar olduğunu unutmayın. Çoğaltmayı önlemek için doğru soyutlamayı bulmak zor olabilir.
Borjab,
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.