Kaliteyi iyileştirme umuduyla mini-refactor kodunu faydalı mıdır, yoksa çok fazla faydası olmadan sadece “kodu hareket ettirmek” midir?


12

Misal

Tek bir yerde "her şeyi" yapan monolitik kodla karşılaştım - veritabanından veri yükleme, HTML işaretlemesi gösterme, yönlendirici / denetleyici / eylem gibi davranma. SRP hareketli veritabanı kodunu kendi dosyasına uygulamaya başladım, işler için daha iyi adlandırma sağladım ve hepsi iyi görünüyordu, ama sonra neden bunu yaptığım konusunda şüphelerim var.

Neden refactor? Amaç ne? Yararsız mı? Avantajı nedir? Monolitik dosyayı olduğu gibi bıraktığımı, ancak sadece biraz iş yapmam gereken alanla ilgili olan daha küçük kısmı yeniden düzenlediğimi unutmayın.

Orijinal kod:

Somut bir örnek vermek gerekirse, bu kod snippet'ine rastladım - ürün özelliklerini bilinen bir ürün kimliğiyle veya kullanıcı tarafından seçilen bir sürüm kimliğiyle yükler:

if ($verid)
    $sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
    $sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */

yeniden düzenleme:

Kodun bu özel kısmındaki şeyleri değiştirmemi gerektiren bazı işler yaptığım için, depo desenini kullanacak şekilde değiştirdim ve nesne yönelimli MySQL olanaklarını kullanacak şekilde yükselttim:

//some implementation details omitted 
$this->repository = new SpecRepository($mysql);
if ($verid)
    $row1 = $this->repository->getSpecByVersion($verid);
else 
    $row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/

//added new class:
class SpecRepository extends MySqlRepository
{

    function getSpecByVersion(int $verid)
    {
        return $this->getMySql()->paramQuery("
            SELECT * FROM product_spec WHERE id = ?
        ", $verid)->getSingleArray();
    }

    function getSpecByProductId(int $productid)
    {
        return $this->getMySql()->paramQuery("
            SELECT * FROM product_spec WHERE product_id = ?
        ", $productid)->getSingleArray();
    }
}

Bunu yapmalı mıyım?

Değişikliklere baktığımızda, kod hala orada, aynı işlevselliğe sahip kod, ancak farklı dosyalarda, farklı adlarda, yerlerde, yordam yerine daha nesne yönelimli bir stil kullanıyor. Aslında, yeniden düzenlenmiş kodun aynı işlevselliğe sahip olmasına rağmen çok daha şişkin göründüğünü belirtmek komik.

Bazı cevapları "Refactor'unuzun nedenini bilmiyorsanız, yapmayın" diyerek tahmin ediyorum ve belki de katılıyorum. Nedenlerim zaman içinde kod kalitesini artırmak (ve umarım bunu SRP ve diğer ilkeleri izleyerek yapacağım).

Bu yeterince iyi nedenler mi yoksa "kodumu yeniden düzenlemede" zamanımı bu şekilde mi harcıyorum? Genel olarak yeniden düzenleme, dürüst olmak için su arıtmak gibi geliyor - zaman alıyor ve SRP'nin gittiği kadar daha "ayrılıyor" ama iyi niyetime rağmen inanılmaz iyileştirmeler yapıyormuşum gibi hissetmiyorum. Bu nedenle, kodu eskisi gibi bırakmak en iyisi ise tartışmak.

İlk etapta neden yeniden düzenleme yaptım?

Benim durumumda, yeni bir ürün grubu için yeni işlevler ekliyorum, bu yüzden benzer ürün grupları için mevcut kod yapısını izlemem ya da kendiminkini yazmam gerekiyor.


OT ama dikkate alınması gereken bir şey, Select * from ..bir anti-desen olarak kabul edilebilir. Bkz. Stackoverflow.com/q/3639861/31326
Peter M

1
@PeterM: Bir ORM yazmazsanız, bu durumda select *"en iyi uygulama" haline gelir.
Robert Harvey

Neden sorguluyorum durumda @RobertHarvey olarak size kendi ORM yazıyoruz: D
Peter M

Daha alakasız nedenlerden dolayı refactors yaptım. Teknik borcun azaltılması, faydalar maliyetlerden daha kısa sürede iyi olur. Görünüşe göre senin durumun bu. Soru şudur: Kodun hala beklendiği gibi çalıştığından emin olmak için doğru testleriniz var mı?
Laiv

1
Güvenilirlik, ilk etapta değişikliklerin nedenlerini azalttığı için, değiştirilebilirlikle ilgili olan sürdürülebilirliği değil, IMO'yu yeniden düzenlerken baskın metrik olmalıdır. Kararlılığı ve mükemmel kararlı ve güvenilir kodu geliştirir ve değiştirmek için çok az nedeni olduğundan, az bakım maliyeti gerektirir, çünkü değiştirmek için çok az nedeni vardır. Mümkün olduğunca kolay hale getirmeye çalışmak yerine, şeylerin değişme nedenlerini azaltmaya çalışın. İlkini aramak aynı zamanda ikincisini de verme eğiliminde olacaktır.

Yanıtlar:


13

Verdiğiniz somut örnekte, en azından henüz değil, yeniden düzenleme gerekli olmayabilir. Ama gelecekte daha uzun ve daha sıkıcı bir yeniden düzenlemeye yol açacak messier kodu için bir potansiyel olduğunu gördünüz, bu yüzden inisiyatif aldınız ve şimdi işleri temizlediniz.

Ayrıca burada elde ettiğiniz avantaj, kod tabanınızı bilmeyen biri olarak, en azından benim açımdan, anlaşılması daha kolay olan kod olduğunu söyleyebilirim.


Genel olarak:

Yeniden düzenleme, diğer geliştiricilerin kodunuzu anlamasını kolaylaştırır mı?

Yeniden düzenleme, kodu geliştirmeyi kolaylaştırıyor mu?

Yeniden düzenleme, kodun bakımını kolaylaştırır mı?

Yeniden düzenleme, hata ayıklamayı kolaylaştırır mı?

Eğer bunlardan herhangi birinin cevabı "evet" ise, buna değdi ve sadece "kodu dolaşmaktan daha fazlası mıydı?"

Bunların hepsine cevap "hayır" ise, belki de yeniden düzenlenmesi gerekmiyordu.

Kod tabanının son boyutu LoC açısından daha büyük olabilir (ancak bazı yeniden düzenleme işlemleri kod tabanını gereksiz kodu düzene sokarak küçültebilir), ancak başka kazançlar varsa bu bir faktör olmamalıdır.


9

Bir yekpare parça söküyorsanız, yeniden düzenleme şişirir.

Ancak, avantajı zaten buldunuz.

"Benim durumumda, yeni bir ürün serisi için yeni işlevler ekliyorum."

Bir monolite, işleri bozmadan çok kolay bir şekilde işlev ekleyemezsiniz.

Aynı kodun verileri aldığını ve biçimlendirmeyi yaptığını söylediniz. Belirli koşullarda hangi sütunları seçtiğinizi ve değiştirdiğinizi değiştirmek istediğinize kadar harika. Aniden, biçimlendirme kodunuz belirli bir durumda çalışmayı durdurur ve yeniden düzenleme yapmanız gerekir .


evet, ama ben de yeni işlevsellik için bile monolit eklemeye devam edebilirsiniz :) yani ben yeni bir if/elseblok eklemek ve SQL deyimleri eklemek için kod orijinal stilini takip ediyorum, ve sonra ben aynı monolith dosyaya yeni HTML biçimlendirme koymak istiyorum. Ve sütunları değiştirmek için ben SQL satırları konut sorumlu if / else blok bulur ve bu dosyayı bozmadan sütunlarda değişiklik yapmak için bu SQL düzenlemek.
Dennis

Refactored yaklaşım ile, muhtemelen ilk ben değiştirmek için ayrı depo dosyasına gitmek gerektiğini görmek için monolit if / else bloğuna gitmek istiyorum. Veya son zamanlarda o monolit üzerinde çalışsaydım, bunun yerine monoliti atlayarak doğrudan depo dosyasına gitmeyi bilirdim. Ya da kod tabanımı belirli bir SQL için araştırırsam, arama beni yeni depo dosyasına koyar
Dennis

2

Bu proje ile aylarca hatta yıllarca çalışmam gerektiğini bilsem yeniden düzenleme yapmayı düşünüyorum. Burada ve orada bir değişiklik yapmak zorunda kalırsam, kendimi kodları hareket ettirme isteğine karşı koyarım.

Yeniden düzenleme yapmanın tercih edilen yolu, bazı otomatik testlere sahip bir temel kodum olduğunda. Yine de, işlerin daha önce olduğu gibi çalıştığından emin olmak için değiştirdiğim şeylere çok dikkat etmeliyim. Çalışmanız gereken alandan başka alanlarda böcek teslim ederseniz çok yakında güveninizi kaybedersiniz.

Aşağıdaki nedenlerden dolayı yeniden düzenlemeye değer veriyorum:

  • Kodu daha iyi anlıyorum
  • Ben tek bir yerde bir hata varsa ben kod kopya yapıştırılmış her yerde avlamak zorunda değilsiniz çoğaltılan kodu kaldırmak
  • İyi tanımlanmış rolleri olan sınıflar yaratıyorum. Örneğin, bir HTML sayfasını, XML beslemesini veya arka plan işini nemlendirmek için aynı veri havuzunu yeniden kullanabilirim. Veritabanı erişim kodu yalnızca HTML sınıfında yaşıyorsa, bu mümkün olmazdı
  • Değişkenleri, yöntemleri, sınıfları, modülleri, klasörleri geçerli gerçeklikle eşleşmezlerse yeniden adlandırırım; I commentdeğişken isimleri, yöntem isimleri üzerinden kod
  • Birim testleri ve yeniden düzenleme arasında bir kombinasyonla karmaşık hataları çözerim
  • Tüm modülleri, paketleri değiştirme esnekliğine sahibim. Mevcut ORM güncelliğini yitirmiş, buggy veya bakımsızsa, projenin her tarafına yayılmamışsa değiştirmek daha kolaydır.
  • Müşteri için tekliflerle sonuçlanan yeni yetenekler veya iyileştirmeler keşfediyorum.
  • Yeniden kullanılabilir bileşenler oluşturdum. Bu, en büyük avantajlardan biriydi, çünkü o projede yapılan iş başka bir müşteri / proje için tekrar kullanılabilirdi.
  • Sıklıkla en aptal, kodlanmış, tuhaf bir çözümle başlıyorum ve daha sonra öğrendikten sonra tekrar gözden geçiriyorum. Bu sonraki an bugün veya belki birkaç gün sonra olabilir. Çözüme çok fazla zaman harcamak istemiyorum architect. Bu, yazarken gelir - kodu ileri ve geri yeniden yazmak.

Mükemmel bir dünyada yeniden düzenleme işlemleri birim testleri, entegrasyon testleri vb. İle doğrulanmalıdır. Hiçbiri yoksa, eklemeyi deneyin. Ayrıca bazı IDE çok yardımcı olabilir. Genellikle paraya mal olan bir eklenti kullanırım. Refactorings ile çok az zaman harcamak ve bu konuda çok verimli olmak istiyorum.

Ben de hataları tanıttım. Bazı KG'ların neden sorduğunu görebiliyorum. are you guys doing refactoring? because everything stopped working!Bu, ekibin kucaklaması gereken risk ve hep bu konuda şeffaf olmalıyız.

Yıllar boyunca sürekli yeniden düzenlemenin verimliliğimi artırdığını buldum. Yeni özellikler eklemek çok daha kolaydı. Ayrıca, büyük yeniden yapılanmalar, kod tabanı ürünün evrimine uyarlanmadığında sık sık yeniden yazma gerektirmedi. Ayrıca eğlenceli.


Bu, aşağı oylamaya çok yakın - 'Bilgisayar programcısı'nda' ben 'yok. 'Ben' ile sen beni 'ben' (aşağı oy) ya da şimdi ve gelecekte kod üzerinde çalışan geliştiriciler mi demek istiyorsun?
mattnz

Ben de fark ettim, ama anlatmaya başladım. Ayrıca uzun yıllar solo geliştirici olarak çalıştım ve bu cevabı yazdığımda çoğunlukla bu deneyimlerden tekrarladım. Ben olsa Iile değiştirebilirsiniz to.
Adrian Iftode

1

Sanırım kendinize sormanız gereken soru çok fazla değil "Bir fayda var mı?" ama "Bu iş için kim ödeyecek?"

Günlerin sonuna kadar algılanan faydalar hakkında hepimiz tartışabiliriz, ancak bu faydalara inanan ve onlara değişiklikler için ödeyecek kadar değer veren bir müşteriniz yoksa, bunları yapmamalısınız.

Bir yerde bir dev ekibinde kod görmek ve 'daha iyi' yapmak için yeniden düzenleme yapmak istediğinizde çok kolay. Ancak ürün zaten çalıştığında 'daha iyi kod'a değer vermek gerçekten zor.

'Yeni özelliklerin daha hızlı geliştirilmesi' gibi şeyler bunu azaltmaz çünkü bunlar sadece düşük maliyetlerdir. Satış oluşturmanız gerekiyor.


1

Bence yeniden düzenleme iyi bir yatırım.

Aksi takdirde, yakında teknik borçlar alacaksınız (çözülmemiş sorunlar, yalnızca belirli koşullar altında çalışan kötü kodlar vb.). Yazılım borçları sürdürülemez hale gelene kadar teknik borçlar yakında büyüyecek.

Ancak yeniden düzenleme işini yapmak için testlere de yatırım yapmanız gerekir. Otomatik testler oluşturmalısınız, ideal olarak birim testlerine ve entegrasyon testlerine sahip olmalısınız. Bu, mevcut kodu kırmanızı önler.

Patronunuzu veya iş arkadaşlarınızı ikna etmeniz gerekiyorsa, çevik yöntemler (örn. SCRUM) ve test odaklı geliştirme hakkında bazı kitaplar okumalısınız.

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.