Kod Kokuları ve Yeniden Düzenleme

 

Bu bölümde açıklanan kod hataları ve yeniden düzenleme yöntemlerinden herhangi biri hakkında daha fazla bilgi edinmek veya kodunuzun hatalı olabileceği başka yolları öğrenmek istiyorsanız Martin (2009), Shvets ve Fowler ve Beck (2019) iyi kaynaklardır.

Kod kokusu, kodun yeniden düzenlenmesi gerektiğinin göstergesidir; yazılımınızın kod çürümesine uğradığının bir işaretidir. Bu gibi düşünceleriniz varsa kodunuza dikkat etmeniz gerekebilir:

  • "Bu kodu bir mülakat sırasında asla göstermem."
  • "Baştan başlayacağım ve bu kodu sıfırdan yeniden yazacağım."
  • "Bu koda her baktığımda, ne işe yaradığını yeniden bulmam gerekiyor."
  • "Bu yorumlar kodla uyuşmuyor . . ."
  • "Bu kod neden üç farklı yerde tekrarlanıyor?"
  • "Bu bileşeni değiştirmek istiyorum, ancak bu diğer yerdeki X, Y ve Z'yi bozacak ve bununla uğraşmak istemiyorum."

Ele alacağımız kod kokusu türleri (nasıl düzeltileceği dahil):

  • Kod, yorumlar hakkında kokuyor.
  • Kod, fonksiyonlar hakkında kokar.
  • Genel kod kokuları (örneğin, fonksiyonlar içindeki kod hakkında).

Kod Kokuları Neden Önemsenmeli?

Kod kokularına dikkat etmek ve düzeltmek için nedenler:

  • Kokulu kodun bakımı sizin ve başkaları için daha zor olabilir çünkü kod belirsizdir. Kodun bakımı zor olduğunda, geliştiriciler kodun etrafında çalışma veya aynı işlevi başka bir yerde yeniden oluşturma eğilimindedir.
  • Kötü kokan kod, daha kötü kokan koda yol açar. Kodunuzun dağınık olmasına izin verdiğinizde, kendinize ve başkalarına kokan kodun kabul edilebilir olduğu mesajını vermiş olursunuz. Dağınık kod aynı zamanda bize tembel kodlayıcılar olmak için bir bahane verme eğilimindedir. Bir web geliştirme örneği: CSS kullandıysanız, uygulamaya çalıştığınız stilin çalışmadığı sinir bozucu durumlarla karşılaşmış olabilirsiniz - kodun bir yerinde (örneğin, diğer CSS, HTML veya JS), stiliniz geçersiz kılınıyor. Rakip kodu veya işaretlemeyi takip etmek yerine, stili uygulanmaya zorlayan "!important" özelliğini kullanırsınız. Kod tabanı zaten dağınık, kimin umurunda? Gelecekteki benliğiniz.
  • Kötü kokan kod teknik borç oluşturur. Eğer kod çalışıyorsa, onu değiştirmek için bir neden yoktur, değil mi? Yanlış. Her özensiz kod yazdığınızda, projenizin teknik borcuna katkıda bulunmuş olursunuz. Belki şu anda işe yarayabilir, ancak özensiz yazılım büyüdükçe, başa çıkmak daha zor hale gelecektir. Bu da şirketinizin verimliliği yüksek tutmak için daha fazla geliştirici işe alması gerektiği anlamına gelebilir. Bunun yerine üretkenlik düşebilir çünkü artık eski geliştiriciler yeni geliştiricilere öğretmekte zorlanmakta ve herkes baştan savma kod yazmaya devam etmektedir (Martin, 2009). Sonuçta, yazılımın tamamen yeniden geliştirilmesi gerekebilir (ki bu her zaman sorunu çözmez). Ya da proje başarısız olabilir.

Kodunuz Berbat - Şimdi Ne Olacak?

Eğer yapabiliyorsanız (örneğin, yöneticiniz izin veriyorsa), refactoring yapmayı kesinlikle düşünün. Refactoring, kodun ne yaptığını değiştirmeden kodunuzu geliştirmenizdir. Refactoring teknik borcu ödemenin bir yoludur.

Bu bölümün geri kalanı kod kokuları ve bunların nasıl temizleneceği hakkındadır. Bu kapsamlı bir liste değildir. Bölümün sonundaki referanslarda daha fazla tavsiye bulabilirsiniz.

Yorumlar

Kod yazmayı ilk öğrendiğimizde, çoğumuz yorum yazmazdık: problem çözmek ve kod yazmak eğlencelidir; sıkıcı yorumlar için zaman yok! Sonra, daha fazla deneyim kazandık, başkalarıyla kodlamaya başladık, resmi olarak kodlama eğitimi aldık veya eski bir projeye devam etmeye çalıştık ve yorumların neden yararlı olduğunu gördük - ve sonra bazılarımız diğer uca atladı: çok fazla yorum. Fonksiyonları paragraflarca düzyazı ile açıkladık, hatta her satıra yorum yazdık. Sıkıcıdır ama yapılması gereken doğru şey budur, değil mi? Ne yazık ki (ve neyse ki), çok fazla yorum hiç yorum olmaması kadar kötü olabilir.

Çok Yorum Yapmanın Dezavantajları

Bir mülakattan önce kodunuza aşırı yorum ekleme tuzağına düşmeyin! Bazı potansiyel işverenler, kötü programlama alışkanlıklarının bir göstergesi olarak özellikle aşırı yorumlanmış kod ararlar (veya bunu görmeden edemezler).
  • Yorumlar çabuk güncelliğini yitirir. Kodu güncelledikten sonra yorumları ertelersek, bıraktıklarımız yanıltıcı olabilir (başkaları ve gelecekteki kendimiz için). Ayrıca, daha fazla yorum, bazılarının göz ardı edilme olasılığının daha yüksek olması anlamına gelir, bu da bize bazı doğru ve bazı yanlış yorumların kokuşmuş durumunu verir. Bu durumda, yorumların herhangi birine neden güvenelim ki?
  • Basit kodlar için yorum yazmak önemli yorumların dikkatini dağıtabilir. Kodun yazılması zorsa, uzunsa, benzersizse, karmaşıksa veya bir "püf noktası" varsa, yorumlar kodun kendine has özelliklerine dikkat çekmeye yardımcı olabilir.
  • Çok sayıda yorum yazmak, kodun basitleştirilmesi gerektiğini gösterebilir. İdeal olarak, yazdığınız kodun çoğu kendi kendini açıklayıcı olacaktır, bu nedenle sık sık yorum yapmaya gerek yoktur.

Kod Yorumlar Hakkında Kokuyor

Aşağıda, yorumlarla ilgili yaygın kod kokularının kısa bir listesi ve bunlar hakkında ne yapılacağı (nasıl yeniden düzenleneceği) yer almaktadır.

  • Eski Yorum (artık kodu açıklamıyor). Kaldırın veya güncelleyin.

# SMELLY
“””
Uses the TwoFish block cipher with 256 bit key size
“””
ThreeFish(512,data)
  • Yorumlanmış Kod (birileri bu koda daha sonra ihtiyaç duyacaklarını düşünmüş, ancak yorumlanmış blok artık güncelliğini yitirmiş ve engel teşkil ediyor). Kaldırın. Riskten kaçınıyorsanız, bir yedek kaydedin veya bir sürüm kontrol sistemi kullanın.
Kodu yorumlamak genellikle zayıf varsayımlarla birlikte gelir (örneğin, koda daha sonra ihtiyacınız olacak, diğerleri neden yorumladığınızı anlayacak, çevredeki kod aynı amaca sahip olmaya devam edecek vb.)

SMELLY
def updateWorldState():
 ”””
 updateTime() # might need later
 updatePlayers()
 updatePoints()
 ”””
 for p in players:
  p.updateState()

Gereksiz Yorum (herhangi bir seviyedeki bir programcı için zaten hemen belli olacak şeyleri belirtir). Kaldırın. Daha azı daha çoktur.

SMELLY
getLength() # gets the length

Uzun Yorum (birden fazla cümle, karmaşık, çok fazla ayrıntıya giriyor). Kodu daha açıklayıcı hale getirmek için basitleştirin; yorumu kısaltın veya kaldırın.

SMELLY
“””
This is the first function I made in this module, and it takes the user’s Unicode   text input, converts it to ASCII, then that creates a visualization of a typewriter typing the input. Problem is, as you might imagine, sometimes there’s no good conversion to ASCII, so some meaning is lost.
“””

Fonksiyonlar

Sadece kısa bir program yazıyorsanız, kodlama stilinin bir önemi var mı? Koda tek kullanımlık muamelesi yapmak kendi kendini gerçekleştiren bir kehanettir.

Kod yazmanın doğal bir yolu, bir fonksiyon yazmaya başlamak ve daha sonra program daha karmaşık hale geldikçe ona eklemeler yapmaya devam etmektir. Örneğin, programınızın GUI'sinde yalnızca bir başlat ve bir durdur düğmesi varsa, ekranı UI öğeleriyle doldurma işlevinin yalnızca bu iki düğmeyi çizmesi gerekir. Ardından, bir menü ve bir ayar düğmesi eklediğinizde, bu öğeleri de çizmek için işlevi güncelleyebilirsiniz. Daha sonra kullanıcı hesapları eklersiniz ve bu işlevin kullanıcının oturum açıp açmadığını, hareketsizlik düzeyini kontrol etmek, harika yeni özellikler hakkında bir açılır pencere göstermek için iyi bir yer olduğuna karar verirsiniz . . ve işlev balonlarınız. Fonksiyonun nasıl çalıştığına dair küçük ayrıntıları anlamak insana gurur bile hissettirebilir - ta ki kod bakım yapılamaz ve hatalarla dolu hale gelene kadar.

Kodun Fonksiyonlar Hakkında Kokması

Üç ila dört satırlık işlevlerden oluşan yazılımları görmek şaşırtıcıdır!

Kodun okunabilirliğini, sürdürülebilirliğini ve modülerliğini artırmak için bu yeniden düzenleme önerilerini izleyin.

  • Uzun Fonksiyon (10 satırdan fazla). Birden fazla fonksiyona bölün. Beş satır veya daha azını hedefleyin.
  • Birçok İşi Olan İşlev (adının çağrıştırdığından daha fazlasını yapmak, birbiriyle yakından ilişkili olmayan işler yapmak, birçok şey yapmak). Birden fazla fonksiyona ayrılın.

#BEFORE
 def updateGUI():
  updateTime()
  updateTimeDisplay()
  updateScores()
  updateScoreDisplay()
  refreshWindow()

#AFTER
 def updateState() :
  updateTime()
  updateScores()

 def updateGUI():
  updateTimeDisplay()
  updateScoreDisplay()
  refreshWindow()
  • Çok Parametreli Fonksiyon (dörtten fazla, bazıları üçten fazla diyor). Uygun olduğunda, parametreleri birleştiren bir nesne geçirin, parametre verilerini almak için işlev içinde çağrılar yapın, birden fazla işleve bölün veya parametre sayısını azaltmanın başka bir yolunu bulun.
Sıfır fonksiyon parametresi dörtten bile daha iyidir!

#BEFORE
initOutdoorPlace(floraList, faunaList, temperature, windSpeed, cloudiness, rockiness, birdNoises, grassLength)

#AFTER
initOutdoorPlace(world1data)

Kod

Eğer dikkat etmezseniz kod hızlı bir şekilde dağılır. Bunun bir nedeni, birçoğumuzun kodu ilk öğrendiğimizde düzgün olması için eğitilmemiş olmamızdır. Düzenli kod yazmak için sık sık durup tasarımı hakkında düşünmeniz veya düzenli olarak yeniden düzenleme konusunda kendinize karşı katı olmanız gerekebilir. Zamanla daha iyi alışkanlıklar edinebilirsiniz.

Genel Olarak Kod Kokması

  • Yinelenen Kod (birden fazla yerde aynı kod). Tek bir yerde birleştirin, ancak istenmeyen bağımlılıklar yaratmamaya dikkat edin.

#BEFORE
 def updateLevelOfAlarm(npc):
  if (npc.isWalking() && npc.isAlive() && npc.isFriendly())
   setLevelOfAlarm(0)
  else
   setLevelOfAlarm(500)
   react(npc)

 def react(npc):
  if (npc.isWalking() && npc.isAlive() && npc.isFriendly())
   keepWalking()
  else
   runAway()

#AFTER
 def react(npc):
  if (npc.isHarmless())
   setLevelOfAlarm(0)
   keepWalking()
  else
   setLevelOfAlarm(500)
   runAway()

 def setLevelOfAlarm(level):
  alarmLevel = level

 def isHarmless(npc):
  return (npc.isWalking() && npc.isAlive() && npc.isFriendly())
  • Uzun Satırlar (100 karakterden fazla). Birden fazla satıra bölerek, bir işlev çağrısına dönüştürerek, yeni değişkenler tanımlayarak vb. kısaltın.
“100 karakter” veya “beş satır” gibi eşikler keyfidir. Genel olarak kısa olan daha iyidir, ancak bu kural bile her yerde uygulanamaz. Örneğin, “sözdizimsel şeker”, genellikle programlama dilinde yerleşik olarak bulunan özlü ve zarif kod sözdizimi için kullanılan bir terimdir. Kodunuzu daha kısa hale getirebilir, ancak kimse anlayamayacaksa ne anlamı var!

#BEFORE
if (rectangle.coordinate[1][0] – rectangle.coordinate [2][0] > 500 && rectangle.coordinate[2][1] – rectangle.coordinate[3][1] > 500 && rectangle.isSquare()):

#AFTER
if (rectangle.isSquare() && rectangle.width > 500):
  • Tutarsız Konvansiyonlar (kodun farklı yerlerde farklı biçimlendirilmesi veya düzensiz bir şekilde biçimlendirilmesi). Kodun halihazırda kullandığı stil kurallarını takip edin. Yeni bir projeyse, kendi içinde tutarlı olmayı veya kullandığınız dil için kabul edilen kuralları takip etmeyi planlayın.
Başka bir kişinin koduna ekleme yaparken, farklı bir yolu tercih etseniz bile kodlama stili kurallarına uymak en iyisidir. Bununla birlikte, kod stilleri özensiz ve tutarsızsa, sorunu çözmenin kibar bir yolu olup olmadığını düşünün.

# BEFORE
if (whale.isSinging) {
activateAudioRecordingDevice();
} else {
recording_device_off_confirmation_check();
}

if (starfish.blockingCamera)
{
AirCannon.Spray(camera.coordinates);
}

# AFTER
if (Whale.isSinging) {
activateAudioRecordingDevice();
} else {
confirmRecordingDeviceOff();
}

if (Starfish.isBlockingCamera) {
AirCannon.spray(Camera.coordinates);
}
  • Belirsiz Adlandırma (işlevin, değişkenin vb. ne için olduğunu bildirmez). İsim uzun olsa bile yeniden adlandırın. Uzun isimler bazen yorumların yerini alabilir.
Kod bir kitap gibi okunsa güzel olmaz mıydı?

# BEFORE
a = 100
b = 2

# AFTER
retail_price = 100
wholesale_multiplier = 2

Özet

Kodunuzu temizlemek, yazılımınızı sürdürülebilir ve genişletilebilir hale getirmenize yardımcı olabilir ve ekip arkadaşlarınızı da daha mutlu edebilir.

  • Eski yorum mu? Kaldırın veya güncelleyin.
  • Yorumlanmış kod? Kaldırın.
  • Uzun bir yorum mu? Basitleştirin, kısaltın veya kaldırın.
  • Uzun fonksiyon (~10 satırdan fazla)? Bölün.
  • Birçok işi olan fonksiyon mu? Böl.
  • Çok parametreli fonksiyon? Bir nesne geçirin, parametre verilerini almak için çağrı yapın veya bölün.
  • Mükerrer kod mu? Birleştirin.
  • Uzun satırlar (~100 karakterden fazla)? Kısaltın, fonksiyona dönüştürün veya yeni değişkenler tanımlayın.
  • Tutarsız kurallar mı? Mevcut kuralları takip edin.
  • Belirsiz adlandırma? Yeniden adlandırın.

  • Fowler, M., & Beck, K. (2019). Refactoring: Improving the design of existing code. Addison-Wesley.
  • Martin, R. C. (2009). Clean code: A handbook of Agile Software craftsmanship. Prentice Hall.
  • Shvets, A. (n.d.). Refactoring and Design Patternshttps://refactoring.guru/

  • Burnett, M., Stumpf, S., Macbeth, J., Makri, S., Beckwith, L., Kwan, I., Peters, A., & Jernigan, W. (2016). GenderMag: A method for evaluating software’s gender inclusiveness. Interacting with Computers28(6), 760–787. https://doi.org/10.1093/iwc/iwv046
  • Burnett, M., Sarma, A., Hilderbrand, C., Steine-Hanson, Z., Mendez, C., Perdriau, C., Garcia, R., Hu, C., Letaw, L., Vellanki, A., & Garcia, H. (2021, March). Cognitive style heuristics (from the GenderMag Project). GenderMag.org. https://gendermag.org/Docs/Cognitive-Style-Heuristics-from-the-GenderMag-Project-2021-03-07-1537.pdf
  • GenderMag Project, Di, E., Noe-Guevara, G. J., Letaw, L., Alzugaray, M. J., Madsen, S., & Doddala, S. (2021, June). GenderMag facet and facet value definitions (cognitive styles). OERCommons.org. https://www.oercommons.org/courses/handout-gendermag-facet-and-facet-value-definitions-cognitive-styles
  • Hu, C., Perdriau, C., Mendez, C., Gao, C., Fallatah, A., & Burnett, M. (2021). Toward a socioeconomic-aware HCI: Five facets. arXiv preprint arXiv:2108.13477.
  • McIntosh, J., Du, X., Wu, Z., Truong, G., Ly, Q., How, R., Viswanathan, S., & Kanij, T. (2021). Evaluating age bias in e-commerce. Paper presented at the 2021 IEEE/ACM 13th International Workshop on Cooperative and Human Aspects of Software Engineering (CHASE), Madrid, Spain. https://doi.org/10.1109/chase52884.2021.00012
  • Microsoft. (n.d.). Microsoft inclusive designhttps://inclusive.microsoft.design/
  • Nielsen, J. (1994). Heuristic evaluation. In Usability inspection methods. John Wiley & Sons.
  • Nielsen, J., & Molich, R. (1990). Heuristic evaluation of user interfaces. In Proceedings of the SIGCHI Conference on Human Factors in Computing Systems Empowering People—CHI ’90. Association for Computing Machinery. https://doi.org/10.1145/97243.97281

  • Snyder, C. (2011). Paper prototyping: The fast and easy way to design and refine user interfaces. Morgan Kaufmann.



Yorumlar

Bu blogdaki popüler yayınlar

Gelişim ve Kalıtım Eleştirel Düşünme Soruları

Periodonsiyum Klinik Uygulamalar

Dentin Oluşumu