Bir yöntem imzasını değiştirdim ve şimdi 25.000'den fazla hatam var. Şimdi ne var?


166

Son zamanlarda çok büyük bir uygulama üzerinde çalıştığım (15M loc) yeni bir işe başladım. Önceki işimde benzer şekilde büyük bir uygulamamız vardı, ancak (daha iyisi ya da daha kötüsü için) OSGi kullanıyorduk; Yeni uygulama belki birkaç .dlls ile sadece bir büyük kod tabanıdır.

Bu yüzden bu sınıfın arayüzünü değiştirmem gerekiyor, çünkü patronumun yapmamı istediği şey buydu. Başlangıçta çok genelleşmemiş bazı varsayımlarla yazdılar ve bir süredir yeniden yapılanma sorunundan kaçınıyorlardı çünkü çok sıkı bir şekilde birleşti. Arabirimi değiştirdim ve şimdi 25000 hata var. Hatalardan bazıları, "XYZPriceCalculator" gibi önemli sondaj isimlerinin bulunduğu sınıflardakırılmamalı. Ancak, tüm hatalar çözülene kadar çalışıp çalışmadığını kontrol etmek için uygulamayı başlatamıyorum. Ve birim testlerin birçoğu ya doğrudan bu arayüze referans verir ya da bu arayüze referans veren temel sınıflara bağlanır, bu yüzden bunları düzeltmek başlı başına çok büyük bir görevdir. Artı, tüm bu parçaların nasıl bir araya geldiğini gerçekten bilmiyorum, bu yüzden başlayabilsem bile, işler kırılsaydı neye benzeyeceğini bilmiyorum.

Son işimde böyle bir sorunla karşılaşmadım. Ben ne yaparım?


7
Bize hata türleri ve "bu sınıf" ın ne olduğu hakkında daha fazla bilgi vermeniz gerekecek, biz zihin okuyucu değiliz.
whatsisname,

137
"25000'in üzerinde hata" VS'de gösterilen bu numaralar çoğu zaman yanlıştır. Birkaç hata var, ancak sıklıkla kullanılan bir dll'nin kırılmasıyla, diğer yapılar da başarısız oluyor ve astronomik hata sayılarına neden oluyor. Hata listesinde değil, derleme çıktısında bulunan ilk hata iletisiyle her zaman düzeltmeye başladım.
Bernhard Hiller

13
Değiştirdiğiniz yönteme ilişkin imza öncesi ve sonrasında görmek istiyorum. BTW - 25k hataları, başa çıkacak çok fazla şey gibi görünmüyor. Sıkıcı evet, göz korkutucu, evet, yönetilemez, hayır.
jmoreno

46
Genel arayüz bir sözleşmedir. Bu tür sözleşmeleri bozmayın - yenilerini oluşturun.
Matthew

6
25000 hata! Houston, bir sorunumuz var. Değişikliği kesinlikle geri alın ve yöneticinizle konuşun, ona tamamen yeni bir arayüz oluşturmanız gerekebileceğini açıklayın.
Kod Whisperer

Yanıtlar:


349

25000 hataları temel olarak "buna dokunma" anlamına gelir. Geri değiştir. İstenen arayüze sahip yeni bir sınıf oluşturun ve sınıfın tüketicilerini yavaşça yenisine taşıyın. Dile bağlı olarak, eski sınıfı, her türlü derleyici uyarısına neden olabilecek şekilde kullanımdan kaldırılmış olarak işaretleyebilirsiniz, ancak aslında yapınızı bozmaz.

Ne yazık ki bu şeyler eski kod tabanlarında gerçekleşir. Yavaş yavaş işleri daha iyi hale getirme dışında bu konuda yapabileceğin pek bir şey yok. Yeni sınıfları oluşturduğunuzda, bunları doğru bir şekilde test ettiğinizden ve SOLID ilkelerini kullanarak oluşturduğunuzdan emin olun, böylece gelecekte değişmeleri daha kolay olur.


79
Yeni bir sınıf olması gerekmez . Dile ve koşullara bağlı olarak bir işlev, arayüz, özellik vb.
Olabilir

33
Aynı zamanda eski arayüzün yenisinin etrafındaki uygunluk sargısı ile değiştirilip değiştirilemeyeceği konusunda da yardımcı olur.
Jan Hudec

79
Bazen, 25000 hata aslında buna dokunmaya asla cüret etmediğimiz
mouviciel

13
@ theDmi: Kabul ediyorum, 1 değişiklik ve 25k hata büyük olasılıkla en fazla 2.5k değişiklik anlamına geliyor ve bunun 250 civarında olduğunu bulmak beni şaşırtmadı. Her iki durumda da çok ama çok iş var.
jmoreno

33
Bu 25000 hataların tümü tek bir değişiklikle düzeltilebilir. Devasa bir heirarşinin temel sınıfını kırarsam, türetilmiş sınıfların her biri geçersiz tabanla ilgili hatalar yayar, bu sınıfların her kullanımında var olmayan sınıfla ilgili hatalar yayılır, vb. tartışma. "HasAName" uygulama sınıfındaki geçersiz kılma şimdi çalışmıyor (hata) ve bundan miras kalan her şey şimdi hatalar üretiyor (1000 sınıfın tümü) ve her birinin bir örneğini oluşturduğum her zaman (sınıf başına 24x ortalama). Düzeltme bir satır.
Yakk

80

Refactorings ile böl ve fethet

Genellikle, yapmanız gereken değişikliği küçük adımlara bölmek yardımcı olabilir, çünkü daha küçük adımların çoğunu yazılımı hiç bozmayacak şekilde gerçekleştirebilirsiniz. Yeniden düzenleme araçları bu tür görevlerde çok yardımcı olur.

bölmek

İlk olarak, ulaşmak istediğiniz değişikliği özetleyen olası en küçük değişiklikleri (değiştirilen LoC cinsinden değil, mantıksal değişiklikler cinsinden) tanımlayın. Özellikle saf yeniden şekillendirilmiş ve aletlerle gerçekleştirilebilen basamakları izole etmeye çalışın .

Fethetmek

Sizinkine benzer karmaşık durumlar için, bir seferde küçük bir yeniden ateşleme yapmak ve ardından sorunun dinlenmesine izin vermek mantıklı gelebilir, böylece tüm sürekli entegrasyon sistemlerinin değişimi doğrulayabilmesi ve test ekibinin de bir bakışı olması mümkündür. Bu, attığınız adımları doğrular.

Belirli bir yeniden düzenlemeyi gerçekleştirmek için, değiştirmek istediğiniz yöntemin 25.000 çağrı sitesine sahip olduğunuz bir durumda kesinlikle araç desteğine ihtiyacınız vardır. Belki ara ve değiştir de çalışır, ancak böyle kritik bir durum için bundan korkardım.

Örnek

C #, örneğin, bu kullanmak mümkündür Resharper için imzayı değiştirmek bir yöntemin. Değişiklik yeterince basitse, örneğin yeni bir parametre ekleniyorsa, derleme hatası olabilecek çağrı sitelerinde hangi değerin kullanılması gerektiğini belirleyebilirsiniz.

Daha sonra derhal hatasız bir kod tabanında bulunuyorsunuz ve geçecek olan tüm birim testlerini gerçekleştirebiliyorsunuz, çünkü sadece bir yeniden düzenleme yapıldı.

Yöntemin imzası iyi göründüğünde, gidip Resharper'ın yeni tanıtılan parametreye bağımsız değişken olarak eklediği değerleri değiştirebilirsiniz. Bu artık yeniden yapılanma değildir , ancak hatasız bir kod tabanına sahipsiniz ve değiştirdiğiniz her satırdan sonra testleri çalıştırabilirsiniz.

Bazen bu işe yaramıyor

Bu, sizin gibi, çok sayıda çağrı sitenizin olduğu durumlar için çok faydalı bir yaklaşımdır. Ve şimdi çalışan bir yazılımınız var, bu nedenle imzayı biraz değiştirmek için küçük yeniden düzenleme adımları uygulamak ve ardından bir tane daha yapmak mümkün olabilir.

İmza değişikliği çok karmaşıksa ve daha küçük değişikliklere bölünemezse, ne yazık ki işe yaramaz. Ancak bu nadirdir; Daha küçük sorunlarla problemi bölme genellikle gösteriyor ise mümkün.


12
Bu. Refactor (güvenli bir şekilde) yapabilirseniz, aksi halde uygun bir göçe ihtiyacınız vardır.
sleske

3
Ve her ne olursa olsun, lütfen yerel olarak (örn.) Yöntem imzasını yerel olarak değiştirmek ve ardından ortaya çıkan hataları düzeltmek yerine IDE'nizin yerleşik refactoring araçlarını kullanın.
KlaymenDK

36

Sorunu ve profesyonel bir yazılım geliştirici olarak ihtiyaçlarınızı anlamasına yardımcı olmak için patronunuzla görevinizi netleştirin.

Bir ekibin parçasıysanız, lider geliştiriciyi arayın ve ondan tavsiye isteyin.

İyi şanslar.


15
Bu attığım ilk adım - "Ben bir gencim ve patronum bana bir şey yapmamı söyledi ve şimdi gerçekten büyük bir hata mesajı alıyorum, ama patronum bana bundan bahsetmedi." Adım 1: "Hey patron, bir şey yaptım, ama şimdi 25k hata alıyorum. Bunun olması gerekiyor mu, yoksa ..."
Pimgd

28

Dokunma ona. Hiçbir şey yapma.

Bunun yerine sandalyenize oturun ve "Heeeeelp !!!!!" diye bağırın. olabildiğince gürültülü.

Tam olarak böyle değil, kıdemli meslektaşlarınızdan herhangi birini tavsiye isteyin. 25.000 hata varsa, hataları düzeltmezseniz, hatalara neden olanı düzeltirsiniz. Üst düzey bir meslektaşım , 25.000 hata olmadan patronunuzun istediği değişikliği nasıl yapacağınızı size önerebilir. Bunu yapmanın çeşitli yolları vardır, ancak iyi olan şey sizin özel durumunuza bağlıdır.

Patron da kıdemli meslektaşlarınıza aynı değişikliği yapmasını söyledi ve "hayır" dediler. Çünkü ne olacağını biliyorlardı. Bu yüzden sana iş verildi.


2
Bu kesinlikle akılda tutulması gereken önemli bir şeydir. Yeni bir çalışan büyük ölçüde gerçekten hırslıysa, sadece 5 byte'lık hafıza avantajı elde eden veya daha sonra yeniden kodlamak ve sürdürmek için biraz daha mantıklı olan gerçekten büyük bir işi yapmak için yeterince çalışkan (saf) olabilirler.
Büyük Ördek

@TheGreatDuck: Her yerde ve her yerde yanlış kullanılan bir arayüz görmediğinizi söyleyin . Kesinlikle var.
Joshua

@Joshua, söylediklerimle bile alakası yok. Küçük hataların giderilmesi, zaman zaman en akıllıca fikir değil, 10.000'den fazla kod satırının yeniden yazılması anlamına gelir. Maalesef, yeni bir çalışan, patronlarını etkilemek ve halletmek için bu kodu yeniden yazmak için işyerinin 10 gecesini çekebilecek kadar saf olabilir. Elbette, yapılacak harika bir şey, ama bazen de yeterli. Sadece böceğin varlığını kabul etmen gerekiyor.
Büyük Ördek,

1
@Joshua btw, bu topluluğa sadece katıldım çünkü bu soru popüler sorularımı beslemeye başladı. Bunun gibi büyük ölçekli tasarım konusunda hiçbir tecrübem yok. Ben sadece bu kişinin görüşüne katılıyorum.
Büyük Ördek,

22

Yerleşik API'ler kolayca değiştirilemez. Eğer varsa gerçekten kaldırılan gibi onları değiştirmek anootate ve / veya bunları belgelemek gerekir (dili sağlar ne demekse) ve belge hangi API yerine kullanılmalıdır. Eski API daha sonra yavaş yavaş kaldırılabilir ... belki yeniden düzenleme için zaman bütçenize bağlı olarak çok yavaş.


10

Değerlendirmek

Bu değişikliğin gerekli olup olmadığını veya yeni bir yöntem ekleyip diğerine itiraz edip edemediğinizi değerlendirin .

İleri, ileriye doğru

Değişim gerekliyse; o zaman bir göç planı gereklidir.

İlk adım, yeni yöntemi tanıtmak ve eski yöntemin argümanlarını geliştirmesini sağlamaktır. Bu birkaç şey zor kodlama gerektirebilir; bu iyi.

Bu bir taahhüt noktası: tüm testlerin geçtiğini, yapıldığını, itildiğini kontrol edin.

Göç

Yoğun iş eski yöntemin tüm arayanlarını yenisine geçirmektir. Neyse ki iletici sayesinde yavaş yavaş yapılabilir.

O zaman devam et; yardımcı olmak için araçları kullanmakta tereddüt etmeyin ( seden temel olanı, diğerleri vardır).

Eski yöntemi kullanımdan kaldırılmış olarak işaretleyin (yeni yönteme geçiş ipucuyla); Bir şey unuttum mu unutmadığınızı fark etmenize yardımcı olur ve bir çalışma arkadaşı bu konuda çalışırken eski yöntemi çağırırsa yardımcı olur.

Bu bir taahhüt noktasıdır (ya da belki birkaç taahhüt noktasıdır): tüm testlerin geçtiğini, yapıldığını, itildiğini kontrol edin.

Kaldır

Bir süre geçtikten sonra (belki bir gün kadar az), sadece eski yöntemi kaldırın.


4
sedMuhtemelen kötü bir fikirdir ... Aslında dili "anlayan" ve istenmeyen ciddi değişiklikler yapmayacak bir şey daha iyidir.
wizzwizz4 20

1
@ wizzwizz4: Maalesef, C ++ dilini yeterince iyi anlayan çok az araç buldum ; Çoğu araç yeniden adlandırmak için yiyecek ve içecek gibi görünüyor ve bu kadar. Kabul edilirse, yalnızca kesin yöntem çağrılarını yeniden adlandırmak (ve herhangi bir aşırı yüklenme veya ilgisiz ama aynı şekilde adlandırılmış yöntem çağrıları) yeniden adlandırmak etkileyicidir, ancak daha karmaşık bir şey için yetersizdir. En azından, (1) argümanları karıştırmak, (2) verilen bir argümana dönüşüm uygulamak ( .c_str()örneğin, çağrı yapmak) ve yeni argümanlar sunmak için yeteneklere ihtiyacınız olacak . sedbiraz çalışır, derleyici daha sonra sorunlarını bulur.
Matthieu M.

1
sed(veya ed) bu tür bir şey için yeterli olabilir - kabul etmeden önce farkı doğru bir şekilde gözden geçirdiğiniz sürece.
Toby Speight

Bu html'nin TCRR'si, tamam mı? :)
Daniel Springer

8

Yöntem imzasında yaptığınız değişiklik yalnızca bir ad değişikliği ise, basit çözüm, söz konusu yönteme başvuruda bulunan 25.000 sınıftaki değişikliği otomatikleştirmek için araçlar kullanmaktır.

Kodu basitçe el ile düzenlediğinizi ve tüm hatalara yol açtığınızı farz ediyorum. Ayrıca Java'ya aşina olduğunuzu (OSGi'ye referansınızı görerek) bildiğinize inanıyorum, örneğin Eclipse'de (hangi programlama ortamını kullandığınızı bilmiyorum, ancak diğer ortamlarda benzer yeniden düzenleme araçları var) "Yeniden Düzenleme -> Yeniden Adlandır" seçeneğini kullanabilirsiniz. Tüm referansları güncellemek için, sizi hatasız bırakacak olan metoda güncelleyin.

Yöntem imzasında basitçe yeniden adlandırmaktan (parametre sayısını veya tür türlerini değiştirmek) başka değişiklikler yapıyorsanız, "Yeniden düzenleme -> Yöntem imzasını değiştir" i kullanabilirsiniz. Ancak, diğer cevapların önerdiği gibi daha dikkatli olmanız gerekecek. Ayrıca, değişiklik türünden bağımsız olarak, tüm bu değişiklikleri yoğun bir kod tabanında işlemek yine de oldukça zor olabilir.


2
OP özellikle OSGi'nin önceki işlerinde olduğunu söyledi, bu yüzden burada gerçekten alakalı değil.
CVn

3
@ MichaelKjörling OP önceki işlerinde bir Java programcısıysa, bu işte de bir Java programcısı olma ihtimalleri daha iyidir.
Zengin

@ MichaelKjörling Yeniden düzenleme için Eclipse kullanarak somut bir tavsiye vermek istedim çünkü OP Java ile aşina. OP aslında mevcut proje için Java kullanıyor mu, sanırım, daha az önemli, ama cevabımı netleştirmeliyim. Teşekkürler.
MikkelRJ

6

İşte benim katkım.

Son zamanlarda çok büyük bir uygulama üzerinde çalıştığım (15M kod satırı) yeni bir işe başladım.

Muhtemelen projeye ve onun "özelliklerine" aşina değilsinizdir. Tek bir kod satırı yazmadan önce, projeye aşina olmak önemlidir. Bu yüzden değişikliklerinizi geri alın ve kodu analiz ederek başlayın . (En azından etkilenen)

Mevcut çözümü anlamak, nereye girdiğinize dair daha iyi bir bakış açısı sunar. Bağlamsallaştırın çözümü ve önemi.

@Greg'in belirttiği gibi, (regresyon testleri) ile karşılaştırılacak geçerli bir referans olması için mevcut kodu test edebilmelisiniz. Çözümünüz , mevcut sonuçla aynı sonuçları üretebilecek kapasitede olmalıdır . Bu aşamada, sonuçların doğru olup olmadığını umursamıyor musunuz . İlk hedef, düzeltici değil, hataları düzeltmektir. Mevcut çözüm "2 + 2 = 42" diyorsa çözümünüz de olmalıdır. İstisnalar atmazsa, sizinkini de yapmamalısınız. Eğer null değerini döndürürse, sizinki de null değerini döndürmelidir. Ve bunun gibi. Aksi takdirde, 25k kod satırından ödün vereceksiniz.

Bu geriye dönük uyumluluk uğruna.

Neden? Çünkü şu an, başarılı bir refactor için benzersiz garantiniz.

Birim testlerinin çoğu ya bu arayüzü doğrudan referanslar ya da bu arayüzü referans alan temel sınıflara bağlıdır.

Geriye dönük uyumluluğunu garanti etmenin bir yolu acilen sizin için gereklidir. İşte burada ilk zorluk. Ünite testi için bileşeni izole edin.

Mevcut 25k kod satırının, mevcut kodun olası sonuçları varsayılarak yapıldığını unutmayın. Sözleşmenin bu bölümünü bozmazsanız, nihai çözüme giden yolun yarısı kadardır. Eğer yaparsan, iyi: güç seninle olsun

Yeni "sözleşmeyi" tasarlayıp uyguladıktan sonra, eski sözleşmeyi değiştirin. İtiraz et ya da çıkar.

Yeniden düzenleme ve hataların giderilmesi nedeniyle hataları yalnız bırakmayı önerdim. Onları bir araya getirmeye çalışırsanız her ikisinde de başarısız olabilirsiniz. Hata bulduğunuzu düşünebilirsiniz, ancak bunlar "özellikler" olabilir. Bu yüzden onları yalnız bırakın (bir dakika için).

25k kod satırı bana sadece bir göreve odaklanmamı sağlayacak kadar çok şey gösteriyor.

İlk göreviniz bittiğinde. Bu hataları / özellikleri patronunuza gösterin.

Son olarak, @Stephen'in söylediği gibi:

Yavaş yavaş işleri daha iyi hale getirme dışında bu konuda yapabileceğin pek bir şey yok. Yeni sınıfları oluşturduğunuzda, bunları doğru bir şekilde test ettiğinizden ve SOLID ilkelerini kullanarak oluşturduğunuzdan emin olun , böylece gelecekte değişmeleri daha kolay olur


5

Dene.

Diğer herkes yeniden ateşlenmeyi tavsiye ediyor, bu yüzden çok az etkisi var. Ancak bu kadar çok hatayla, 10 satırlık kodla (muhtemelen yapabilirsiniz) yeniden düzenlemeyi başarabilmiş olsanız bile, o zaman, yeniden yazmak gerekmese bile 25.000 kod akışını etkilediniz .

Bu yüzden, yapılacak bir sonraki şey, regresyon test odasının uçan renklerle geçtiğinden emin olmak. Ve eğer bir tane yoksa, o zaman bir tane yap. Monolitik projenize kapsamlı bir regresyon test paketi eklemek sıkıcı geliyor ancak sürüm adaylarının güvenini arttırmanın ve süit otomatik olarak otomatikleştirilirse daha hızlı bırakmanın güzel bir yoludur.

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.