Parandage oma Pythoni koodi hooldatavust, loetavust ja jõudlust tõhusate refaktoreerimistehnikate abil. Õppige praktilisi strateegiaid ja parimaid tavasid koodi kvaliteedi parandamiseks.
Pythoni refaktoreerimise tehnikad: põhjalik juhend koodikvaliteedi parandamiseks
Pidevalt arenevas tarkvaraarendusmaailmas on puhta, tõhusa ja arusaadava koodi säilitamine ülimalt tähtis. Python, mis on tuntud oma loetavuse poolest, võib siiski langeda koodilõhnade ja tehnilise võla ohvriks, kui seda hoolikalt ei hallata. Refaktoreerimine on olemasoleva arvutikoodi restruktureerimise protsess – faktoriseerimise muutmine – ilma selle välist käitumist muutmata. Sisuliselt on see oma koodi puhastamine ilma seda lõhkumata. See juhend uurib erinevaid Pythoni refaktoreerimise tehnikaid, pakkudes praktilisi näiteid ja parimaid tavasid teie koodi kvaliteedi tõstmiseks.
Miks Pythoni koodi refaktoreerida?
Refaktoreerimine pakub mitmeid eeliseid, sealhulgas:
- Paranenud loetavus: muudab koodi lihtsamaks mõistmiseks ja hooldamiseks.
- Vähendatud keerukus: lihtsustab keerulist loogikat, vähendades vigade tõenäosust.
- Täiustatud hooldatavus: lihtsustab koodi muutmist ja laiendamist.
- Suurenenud jõudlus: saab optimeerida koodi parema täitmise kiiruse saavutamiseks.
- Madalam tehniline võlg: takistab sellise koodi kuhjumist, mida on raske hooldada või laiendada.
- Parem disain: viib vastupidavama ja paindlikuma koodiarhitektuurini.
Refaktoreerimise ignoreerimine võib viia koodini, mida on raske mõista, muuta ja testida. See võib oluliselt pikendada arendusaega ja suurendada vigade tekkimise ohtu.
Millal refaktoreerida?
Teada, millal refaktoreerida, on ülioluline. Siin on mõned levinud stsenaariumid:
- Enne uute funktsioonide lisamist: olemasoleva koodi refaktoreerimine võib muuta uue funktsionaalsuse integreerimise lihtsamaks.
- Pärast vea parandamist: ümbritseva koodi refaktoreerimine võib takistada sarnaste vigade kordumist.
- Koodi ĂĽlevaatuste ajal: tuvastage valdkonnad, mida saab parandada, ja refaktoreerige neid.
- Kui kohtate "koodilõhnu": koodilõhnad on potentsiaalsete probleemide näitajad teie koodis.
- Regulaarselt planeeritud refaktoreerimine: lisage refaktoreerimine oma arendusprotsessi regulaarse tegevusena.
Koodilõhnade tuvastamine
Koodilõhnad on pinnapealsed näitajad, mis tavaliselt vastavad süsteemi sügavamale probleemile. Need ei viita alati probleemile, kuid sageli on vaja edasist uurimist.
Levinud Pythoni koodilõhnad:
- Dubleeritud kood: identne või väga sarnane kood, mis ilmub mitmes kohas.
- Pikk meetod/funktsioon: meetodid või funktsioonid, mis on liiga pikad ja keerulised.
- Suur klass: klassid, millel on liiga palju kohustusi.
- Pikk parameetrite loend: meetodid või funktsioonid, millel on liiga palju parameetreid.
- Andmekogumid: andmerĂĽhmad, mis ilmuvad sageli koos.
- Primitiivne kinnisidee: primitiivsete andmetĂĽĂĽpide kasutamine objektide loomise asemel.
- Switch-lausend: pikad if/elif/else lausete või switch-lausete jadad.
- Shotgun Surgery: ühe muudatuse tegemine nõuab paljude väikeste muudatuste tegemist erinevates klassides.
- Divergent Change: klassi muudetakse tavaliselt erinevatel viisidel erinevatel põhjustel.
- Feature Envy: meetod pääseb teise objekti andmetele juurde rohkem kui oma andmetele.
- Message Chains: klient palub ĂĽhel objektil taotleda teiselt objektilt, et see taotleks veel ĂĽhelt objektilt...
Pythoni refaktoreerimise tehnikad: praktiline juhend
See jaotis kirjeldab mitmeid levinud Pythoni refaktoreerimise tehnikaid koos praktiliste näidetega.
1. Meetodi/funktsiooni eraldamine
See tehnika hõlmab koodiploki võtmist meetodis või funktsioonis ja selle teisaldamist uude, eraldi meetodisse või funktsiooni. See vähendab algse meetodi keerukust ja muudab eraldatud koodi taaskasutatavaks.
Näide:
def print_invoice(customer, details):
print("***********************")
print(f"Customer: {customer}")
print("***********************")
total_amount = 0
for order in details["orders"]:
total_amount += order["amount"]
print(f"Amount is : {total_amount}")
if total_amount > 1000:
print("You earned a discount!")
Refaktoreeritud:
def print_header(customer):
print("***********************")
print(f"Customer: {customer}")
print("***********************")
def calculate_total(details):
total_amount = 0
for order in details["orders"]:
total_amount += order["amount"]
return total_amount
def print_invoice(customer, details):
print_header(customer)
total_amount = calculate_total(details)
print(f"Amount is : {total_amount}")
if total_amount > 1000:
print("You earned a discount!")
2. Klassi eraldamine
Kui klassil on liiga palju kohustusi, eraldage mõned neist uude klassi. See soodustab ühe vastutuse põhimõtet.
Näide:
class Person:
def __init__(self, name, phone_number, office_area_code, office_number):
self.name = name
self.phone_number = phone_number
self.office_area_code = office_area_code
self.office_number = office_number
def get_name(self):
return self.name
def get_phone_number(self):
return f"({self.office_area_code}) {self.office_number}"
Refaktoreeritud:
class PhoneNumber:
def __init__(self, area_code, number):
self.area_code = area_code
self.number = number
def get_phone_number(self):
return f"({self.area_code}) {self.number}"
class Person:
def __init__(self, name, phone_number):
self.name = name
self.phone_number = phone_number
def get_name(self):
return self.name
3. Meetodi/funktsiooni sisestamine
See on meetodi eraldamise vastand. Kui meetodi keha on sama selge kui selle nimi, saate meetodi sisestada, asendades meetodi väljakutsed meetodi sisuga.
Näide:
def get_rating(driver):
return more_than_five_late_deliveries(driver) ? 2 : 1
def more_than_five_late_deliveries(driver):
return driver.number_of_late_deliveries > 5
Refaktoreeritud:
def get_rating(driver):
return driver.number_of_late_deliveries > 5 ? 2 : 1
4. Ajutise muutuja asendamine päringuga
Selle asemel, et kasutada ajutist muutujat avaldise tulemuse hoidmiseks, eraldage avaldis meetodisse. See väldib koodi dubleerimist ja soodustab paremat loetavust.
Näide:
def get_price(order):
base_price = order.quantity * order.item_price
discount_factor = 0.98 if base_price > 1000 else 0.95
return base_price * discount_factor
Refaktoreeritud:
def get_price(order):
return base_price(order) * discount_factor(order)
def base_price(order):
return order.quantity * order.item_price
def discount_factor(order):
return 0.98 if base_price(order) > 1000 else 0.95
5. Parameetriobjekti tutvustamine
Kui teil on pikk loetelu parameetritest, mis sageli koos ilmuvad, kaaluge nende kapseldamiseks parameetriobjekti loomist. See vähendab parameetrite loendi pikkust ja parandab koodi korraldust.
Näide:
def calculate_total(width, height, depth, weight, shipping_method):
# Arvutusloogika
pass
Refaktoreeritud:
class ShippingDetails:
def __init__(self, width, height, depth, weight, shipping_method):
self.width = width
self.height = height
self.depth = depth
self.weight = weight
self.shipping_method = shipping_method
def calculate_total(shipping_details):
# Arvutusloogika, kasutades shipping_details atribuute
pass
6. Tingimusliku lause asendamine polĂĽmorfismiga
Kui teil on keeruline tingimuslause, mis valib käitumise objekti tüübi alusel, kaaluge polümorfismi kasutamist käitumise delegeerimiseks alamklassidele. See soodustab paremat koodi korraldust ja muudab uute tüüpide lisamise lihtsamaks.
Näide:
def calculate_bonus(employee):
if employee.employee_type == "SALES":
return employee.sales * 0.1
elif employee.employee_type == "ENGINEER":
return employee.projects_completed * 100
elif employee.employee_type == "MANAGER":
return 1000
else:
return 0
Refaktoreeritud:
class Employee:
def calculate_bonus(self):
return 0
class SalesEmployee(Employee):
def __init__(self, sales):
self.sales = sales
def calculate_bonus(self):
return self.sales * 0.1
class EngineerEmployee(Employee):
def __init__(self, projects_completed):
self.projects_completed = projects_completed
def calculate_bonus(self):
return self.projects_completed * 100
class ManagerEmployee(Employee):
def calculate_bonus(self):
return 1000
7. Tingimusliku lause dekomponeerimine
Sarnaselt meetodi eraldamisele hõlmab see keeruka tingimusliku lause jagamist väiksemateks, paremini hallatavateks meetoditeks. See parandab loetavust ja muudab tingimusliku lause loogika mõistmise lihtsamaks.
Näide:
if (platform.upper().index("MAC") > -1) and (browser.upper().index("IE") > -1) and was_initialized() and resize > MAX_RESIZE:
# Tee midagi
pass
Refaktoreeritud:
def is_mac_os():
return platform.upper().index("MAC") > -1
def is_ie_browser():
return browser.upper().index("IE") > -1
if is_mac_os() and is_ie_browser() and was_initialized() and resize > MAX_RESIZE:
# Tee midagi
pass
8. Maagilise numbri asendamine sĂĽmboolse konstandiga
Asendage literaalsed arvulised väärtused nimeliste konstantidega. See parandab loetavust ja muudab väärtuste hilisema muutmise lihtsamaks. See kehtib ka teiste literaalsete väärtuste, näiteks stringide kohta. Mõelge valuutakoodidele (nt 'USD', 'EUR', 'JPY') või olekukoodidele (nt 'ACTIVE', 'INACTIVE', 'PENDING') globaalsest vaatenurgast.
Näide:
def calculate_area(radius):
return 3.14159 * radius * radius
Refaktoreeritud:
PI = 3.14159
def calculate_area(radius):
return PI * radius * radius
9. Vahendaja eemaldamine
Kui klass delegeerib lihtsalt väljakutseid teisele klassile, kaaluge vahendaja eemaldamist ja lubage kliendil otse sihtklassi juurde pääseda.
Näide:
class Person:
def __init__(self, department):
self.department = department
def get_manager(self):
return self.department.get_manager()
class Department:
def __init__(self, manager):
self.manager = manager
def get_manager(self):
return self.manager
Refaktoreeritud:
class Person:
def __init__(self, manager):
self.manager = manager
def get_manager(self):
return self.manager
10. Kinnituse tutvustamine
Kasutage kinnitusi, et dokumenteerida eeldusi programmi oleku kohta. See võib aidata vigu varakult tuvastada ja muuta koodi vastupidavamaks.
Näide:
def calculate_discount(price, discount_percentage):
if discount_percentage < 0 or discount_percentage > 100:
raise ValueError("Soodustusprotsent peab olema vahemikus 0 kuni 100")
return price * (1 - discount_percentage / 100)
Refaktoreeritud:
def calculate_discount(price, discount_percentage):
assert 0 <= discount_percentage <= 100, "Soodustusprotsent peab olema vahemikus 0 kuni 100"
return price * (1 - discount_percentage / 100)
Pythoni refaktoreerimise tööriistad
Pythoni refaktoreerimisel võivad abiks olla mitmed tööriistad:
- Rope: refaktoreerimise teek Pythoni jaoks.
- PyCharm: populaarne Pythoni IDE sisseehitatud refaktoreerimise toega.
- VS Code koos Pythoni laiendusega: mitmekülgne redaktor, millel on laienduste kaudu refaktoreerimise võimalused.
- Sourcery: automatiseeritud refaktoreerimise tööriist.
- Bowler: Facebooki refaktoreerimise tööriist suuremahuliste koodimuudatuste jaoks.
Pythoni refaktoreerimise parimad tavad
- Kirjutage ühikuteste: veenduge, et teie kood on enne refaktoreerimist hästi testitud.
- Refaktoreerige väikeste sammudega: tehke väikeseid, inkrementaalseid muudatusi, et minimeerida vigade tekkimise ohtu.
- Testige pärast iga refaktoreerimisetappi: kontrollige, kas teie muudatused pole midagi katki teinud.
- Kasutage versioonikontrolli: tehke oma muudatusi sageli, et vajadusel hõlpsalt taastada.
- Suhelge oma meeskonnaga: teavitage oma meeskonda oma refaktoreerimisplaanidest.
- Keskenduge loetavusele: seadke prioriteediks koodi mõistmise lihtsustamine.
- Ärge refaktoreerige lihtsalt refaktoreerimise pärast: refaktoreerige siis, kui see lahendab konkreetse probleemi.
- Automatiseerige refaktoreerimine, kus võimalik: kasutage tööriistu korduvate refaktoreerimisülesannete automatiseerimiseks.
Globaalsed kaalutlused refaktoreerimisel
Rahvusvaheliste projektide või ülemaailmse vaatajaskonna jaoks töötades kaaluge refaktoreerimisel järgmisi tegureid:
- Lokaliseerimine (L10n) ja rahvusvahelistamine (I18n): veenduge, et teie kood toetaks õigesti erinevaid keeli, valuutasid ja kuupäevavorminguid. Refaktoreerige, et isoleerida lokaadipõhine loogika.
- Märgikodeering: kasutage UTF-8 kodeeringut, et toetada laia valikut märke. Refaktoreerige kood, mis eeldab konkreetset kodeeringut.
- Kultuuriline tundlikkus: olge teadlik kultuurinormidest ja vältige keele või kujutiste kasutamist, mis võivad olla solvavad. Refaktoreerimise ajal vaadake üle stringiliteraalid ja kasutajaliidese elemendid.
- Ajavööndid: käsitlege ajavööndite konversioone õigesti. Refaktoreerige kood, mis teeb oletusi kasutaja ajavööndi kohta. Kasutage teeke nagu `pytz`.
- Valuuta käsitlemine: kasutage rahaliste väärtuste käsitlemiseks sobivaid andmetüüpe ja teeke. Refaktoreerige kood, mis teostab käsitsi valuutakonversioone. Abiks on teegid nagu `babel`.
Näide: kuupäevavormingute lokaliseerimine
import datetime
def format_date(date):
return date.strftime("%m/%d/%Y") # USA kuupäevavorming
Refaktoreeritud:
import datetime
import locale
def format_date(date, locale_code):
locale.setlocale(locale.LC_TIME, locale_code)
return date.strftime("%x") # Lokaadipõhine kuupäevavorming
# Näide kasutamisest:
# format_date(datetime.date(2024, 1, 1), 'en_US.UTF-8') # Väljund: '01/01/2024'
# format_date(datetime.date(2024, 1, 1), 'de_DE.UTF-8') # Väljund: '01.01.2024'
Järeldus
Refaktoreerimine on oluline praktika kvaliteetse Pythoni koodi säilitamiseks. Tuvastades ja käsitledes koodilõhnu, rakendades sobivaid refaktoreerimistehnikaid ja järgides parimaid tavasid, saate oluliselt parandada oma koodi loetavust, hooldatavust ja jõudlust. Ärge unustage kogu refaktoreerimisprotsessi vältel seada prioriteediks testimist ja suhtlemist. Refaktoreerimise omaksvõtmine pideva protsessina viib vastupidavama ja jätkusuutlikuma tarkvaraarenduse töövooni, eriti kui arendate ülemaailmsele ja mitmekesisele vaatajaskonnale.