Vananenud koodi haldamine

Vananenud kood: hoiatus, mida sa pidevalt ignoreerid, rikub lõpuks kõik ära

Iga tarkvaraprojekt satub lõpuks aegunud koodi, aegunuks märgitud, mittesoovitavaks või eemaldamisele määratud komponentidesse. @deprecated Java-annotatsioon DeprecationWarning Pythonis on teie IDE automaatse täitmise läbikriipsutus kõik koodibaasist pärit signaalid, mis viitavad sellele, et midagi, mida te kasutate või hooldate, on asendatud. Nende signaalide ignoreerimine akumuleerib vaikselt riski, kuni sõltuvus eemaldatakse, turvapaigaldus jätab vahele aegunud API või raamistiku uuendus lõhub kõik, mis veel tugines sellele, mis oli kolm suuremat versiooni tagasi aegunud.

Mõistmine, mida aegunud tähendab, miks see on oluline ja kuidas seda süstemaatiliselt käsitleda, on üks praktilisemaid hooldusoskusi, mida arendusmeeskond saab arendada. See juhend hõlmab kogu pilti: selged definitsioonid, võrdlus sarnaste terminitega, aegumise hoiatused eri keeltes ja struktureeritud lähenemisviis aegunud sõltuvuste haldamiseks enne, kui neist saavad tootmisintsidendid.

Lõpetage tootmises aegumiste avastamine

SMART TS XL pinnad aegunud komponendid enne, kui neist saavad intsidendid.

Rohkem infot

Mis on aegunud kood?

Vananenud kood viitab funktsioonidele, meetoditele, API-dele, teekidele või tervetele komponentidele, mis on endiselt funktsionaalsed, kuid mille kasutamist ametlikult ei soovitata. Kood töötab edasi, see kompileerub, käivitub ja annab tulemusi, kuid selle hooldajad on andnud märku, et see eemaldatakse tulevases versioonis, asendatakse parema alternatiiviga või seda lihtsalt enam ei hooldata ega uuendata. Vananenud koodi kasutamine tähendab lootmist millelegi, millest selle eest vastutavad inimesed enam ei hooli.

Aegumine on kommunikatsioonimehhanism, mitte tehniline seisund. Kui raamatukogu haldaja märgib funktsiooni aegunuks, ütleb ta: „See töötab täna veel, aga me kavatseme selle eemaldada ja te peaksite enne seda sellest loobuma.“ Aeg aegumisteate ja tegeliku eemaldamise vahel on erinev, see võib olla üks põhiversioon või viis aastat, kuid suund on alati sama. Aegumine tähendab lõpuks eemaldamist.

Vananenud vs. amortiseerunud: õigekirja segadus

Neid kahte sõna aetakse sageli segamini ja õigekirjakontrollid ei aita, sest mõlemad on päris ingliskeelsed sõnad, millel on erinev tähendus.

Aegunud (tarkvaras): märgitud kui aegunud, mittesoovitav, eemaldamisele määratud. Õige termin tarkvara kontekstides.

Amortiseerunud (raamatupidamises): aja jooksul väärtus vähenenud. Näiteks „serveri riistvara amortiseerus kolme aasta jooksul”.

Kui tehnilises dokumendis näete terminit „deprecated code” (amortiseerunud kood), tähendab see peaaegu alati „deprecated code” (aegunud kood) ja autor on kasutanud raamatupidamisterminit, pidades silmas tarkvaraterminit. See viga on piisavalt levinud, et see ilmub selle artikli Search Console'i ​​andmetes. Tarkvara puhul kasutage alati terminit „deprecated kood”.

Vananenud vs. vananenud vs. pärand vs. surnud kood

Need terminid on omavahel seotud, kuid kirjeldavad koodi erinevaid olekuid. Nende segi ajamine viib ebatäpsete vestlusteni ja valede prioriseerimisotsusteni.

TerminMida see tähendabKas see on eemaldatud?Kas seda hooldatakse?Riskitase
HukkaAmetlikult mittesoovitav, märgitud edaspidiseks eemaldamiseksEi, ikka veel kohalEi, hooldus peatatudKeskmise suurusega, aja jooksul kasvav
VananenudEnam mitte asjakohane ega kohaldatav; asendatudMõnikordEiKeskmisel kõrgusel
PärandVana kood, mis ikka veel töötab ja võib olla ikka veel tootmisesEi, ikka veel aktiivneharvaMuutuv, sõltub muutuse määrast
Surnud koodTäitmise ajal ei helistatud ega jõutud kunagi kätteEi, ikka veel allikasPole kohaldatav, ei käivitu kunagiMadal-keskmine, migratsiooni-/auditirisk
Vananenud koodKood, mida pole pikka aega muudetud, aga mis pole ametlikult aegunudEiEbaselgeKeskmise suurusega, võib oletusi varjata

Vananenud vs. aegunudAegunud on ametlik nimetus, keegi on selle selgesõnaliselt märkinud @deprecated või väljastanud aegumisteate. Vananenud on leebem kirjeldus – kood võib küll küll töötada, aga tänapäevaste alternatiivide korral pole sellel enam mõistlikku kasutust. Kogu aegunud kood on lõpuks aegunud, aga mitte kogu aegunud kood pole ametlikult aegunud.

Vananenud vs. eemaldatud : Vananenud kood on koodibaasis endiselt olemas. Eemaldatud kood on kadunud. Vananemisperiood on kahe oleku vaheline aken ehk aeg, mille jooksul peate migreerima enne, kui teie kood lakkab töötamast.

Vananenud vs. pärand : Pärandkood on vana tootmiskood, mida sageli ikka veel aktiivselt kasutatakse ja hooldatakse ning mis on kirjutatud varasemal tehnoloogilisel ajastul. Vananenud kood on spetsiaalselt eemaldamiseks märgitud. Igapäevaseid tehinguid töötlevad pärand-COBOL-programmid ei ole aegunud, need on pärand, kuid neid hooldatakse aktiivselt. COBOL API funktsioon, mille teekitootja on vananenuks märkinud, on aegunud.

Vananenud vs. dekomisjoneerimine : Vananenud on tehniline signaal koodibaasis või teegis. Dekomisjoneerimine on operatiivne otsus, teenuse sulgemine, infrastruktuuri eemaldamine, toote toe lõpetamine. Vananenud API võib töötada aastaid; dekomisjoneeritud API lülitatakse välja kindlal kuupäeval.

Kuidas aegunud keel välja näeb: hoiatused eri keeltes

Aegunud hoiatused esinevad erineval kujul olenevalt keelest ja tööriistadest. Nende kohene äratundmine on esimene samm nendega tegelemiseks.

Python: aegumise hoiatus

püüton

import warnings

# Marking a function as deprecated
def old_function():
    warnings.warn(
        "old_function is deprecated, use new_function instead",
        DeprecationWarning,
        stacklevel=2
    )
    # original implementation

def new_function():
    # improved implementation
    pass

Python kuvab käitusajal aegumise hoiatusi. Levinud kompilaatori teade:

DeprecationWarning: old_function is deprecated, use new_function instead

Või kolmandate osapoolte pakettide puhul:

DeprecationWarning: pkg_resources is deprecated as an API.
Use importlib.resources or importlib.metadata instead.

Java: @Deprecated annotatsioon

Java

public class LegacyProcessor {

    @Deprecated
    public void processData(String input) {
        // old implementation
    }

    // Replacement method
    public void processDataV2(String input, ProcessOptions options) {
        // new implementation
    }
}

Java kompilaator toodab:

Note: SomeFile.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

JavaScript/TypeScript: JSDoc @deprecated

JavaScript

/**
 * @deprecated Use fetchUserById() instead.
 * This function will be removed in version 4.0.
 */
function getUser(id) {
    // old implementation
}

// Modern replacement
async function fetchUserById(id) {
    // new implementation
}

masinakiri

class ApiClient {
    /** @deprecated Use post() with typed options instead */
    sendRequest(url: string): Promise<any> {
        // deprecated implementation
    }
}

IDE-de kuvamine getUser läbikriipsutatud kõikjal, kus seda nimetatakse, ja TypeScripti @typescript-eslint/no-deprecated reegel märgistab selle CI-s.

C++: [[aegunud]] atribuut

cpp

// C++14 and later
[[deprecated("Use processV2() instead")]]
void process(int value) {
    // old implementation
}

void processV2(int value, ProcessFlags flags = ProcessFlags::Default) {
    // new implementation
}

Koostajad toodavad:

warning: 'process' is deprecated: Use processV2() instead [-Wdeprecated-declarations]

Swift: @available koos aegunud versiooniga

kiire

@available(*, deprecated, renamed: "fetchUser(withID:)")
func getUser(id: String) -> User {
    // old implementation
}

func fetchUser(withID id: String) -> User {
    // replacement
}

Kotlin/Java: @Deprecated koos ReplaceWith-iga

kotlin

@Deprecated(
    message = "Use processItems() instead",
    replaceWith = ReplaceWith("processItems(items)"),
    level = DeprecationLevel.WARNING
)
fun handleItems(items: List<Item>) {
    // deprecated
}

fun processItems(items: List<Item>) {
    // replacement
}

Miks aegunud kood põhjustab tegelikke probleeme

Vananenud kood ei ole pelgalt korrashoiuprobleem. See loob konkreetseid ja süvendavaid riske neljas dimensioonis:

Turvahaavatavused. Vananenud API-d ja teegid ei saa enam turvaparandusi. Vananenud teek, millel on parandamata CVE, kujutab endast püsivat haavatavust ja hooldajad on selle parandamise lõpetanud, kuna tahavad, et kõik saidilt lahkuksid. Organisatsioonid, mis käitavad vanadustatud komponente, käitavad teadaolevalt haavatavat koodi omal valikul.

Sõltuvuse katkemine uuenduste ajal. Aeglustumise teade on olemas just seetõttu, et eemaldamine on tulemas. Kui saabub peamine versiooniuuendus ja eemaldab aegunud API, lakkavad kõik sellele veel tuginevad süsteemid samaaegselt töötamast, kõige halvemal võimalikul hetkel, uuenduse ajal, mis pidi olema rutiinne.

Suurem hoolduse keerukus. Aegunud kood nõuab arendajatelt kahe mentaalse mudeli samaaegset hoidmist: mida vana kood teeb ja mida uus vaste teeb. Iga uus meeskonnaliige peab õppima, milliseid koodibaasi osi vältida ja miks. See kahesuunaline keerukus kuhjub iga täiendava aegunud komponendiga.

Tehniline võla liitmine. Iga aegunud sõltuvus on tehnilise võla ühik. Erinevalt teistest võlgadest on aegunud koodivõlal tähtaeg ja see muutub olekust „hoiatus“ olekuks „katkine“ hetkel, kui aegunud komponent tegelikult eemaldatakse.

Kuidas tarkvaraprojektis aegunud sõltuvustega toime tulla

1. samm: inventuurige kõik aegunud tooted

Aegunud komponentide ükshaaval avastamise asemel tehke süstemaatiline skannimine. Enamik tööriistu pakub võimalusi kogu inventuuri leidmiseks:

sisse lööma

# Python: find all DeprecationWarning instances
python -W error::DeprecationWarning -m pytest

# JavaScript/Node.js: run with deprecation tracing
node --trace-deprecation app.js

# Java: compile with full deprecation details
javac -Xlint:deprecation *.java

# npm: find deprecated packages
npm outdated
npm audit

2. samm: liigita riski järgi

Kõik aegumised ei vaja kohest tegutsemist. Liigitage igaüks neist:

PrioriteetKriteeriumidtegevus
KriitilineIganenud turvakriitiline teek; teadaolev CVE; eemaldatakse järgmises põhiversioonisMigreeri kohe
KõrgePraeguses põhiversioonis aegunud; aktiivsed hoiatused konfiguratsioonikeskkonnasAjakava praegusele või järgmisele sprindile
KeskmineAegunud, kuid endiselt toetatud 2+ põhiversiooni puhul; turvariski poleLisa ajakavaga ootel olevasse nimekirja
MadalSisemises koodis aegunud märkus madala muutmissagedusegaJälgimine, aadress seotud refaktoreerimise ajal

3. samm: enne migreerimist leidke kõik kasutusviisid

Enne aegunud komponendi muutmist tehke kindlaks kõik kohad, kus seda kasutatakse. Selle muutmine ilma täieliku kaardita võib kaasa tuua märkamatult lakkamatud kasutusviisid:

püüton

# Using grep for basic search
grep -r "old_function" src/

# Using ast-grep for code-aware search (TypeScript/JS)
ast-grep --pattern 'getUser($ID)' --lang ts

# Using ripgrep with file type filtering
rg "deprecated_method" --type java

Suurte koodibaaside puhul loovad automatiseeritud staatilise analüüsi tööriistad täieliku ristviidete kaardi täpsemalt kui käsitsi grep, eriti kaudse kasutamise korral dünaamilise lähetamise või pärimise kaudu.

4. samm: süstemaatiline migreerimine

Asendage aegunud kasutusviisid ükshaaval, valideerides igaüht enne järgmise juurde liikumist:

püüton

# Before: deprecated
import imp
module = imp.load_source('mymodule', '/path/to/mymodule.py')

# After: replacement
import importlib.util
spec = importlib.util.spec_from_file_location('mymodule', '/path/to/mymodule.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

JavaScript

// Before: deprecated event property
document.addEventListener('keydown', (event) => {
    const key = event.keyCode;  // deprecated
});

// After: modern replacement
document.addEventListener('keydown', (event) => {
    const key = event.key;   // current standard
});

5. samm: lisage CI/CD-le aegumisväravad

Takistada uute aegunud kasutusviiside sisenemist koodibaasi pärast puhastamist:

yaml

# .github/workflows/deprecation-check.yml
- name: Check for deprecated API usage (Java)
  run: javac -Xlint:deprecation -Werror src/**/*.java

- name: Check for deprecated packages (Node)
  run: npm audit --audit-level=moderate

- name: ESLint no-deprecated rule (TypeScript)
  run: npx eslint --rule '{"@typescript-eslint/no-deprecated": "error"}' src/

Aegunud poliitika kehtestamine

Organisatsioonid, mis käsitlevad aegumist hästi, käsitlevad seda poliitikaküsimusena, mitte ainult tehnilise küsimusena. Aegumist käsitlev poliitika määratleb:

Kes saab aeglustada? Üks arendaja ei tohiks laialdaselt kasutatavat sisemist API-t ühepoolselt aeglustada ilma meeskonnatöö läbivaatamata. Aeglustamise otsused peaksid hõlmama tarbivate komponentide omanikke.

Kui kaua aegumisperiood kestab. Mõistlik vaikeväärtus: üks põhiversiooni teatistsükkel enne eemaldamist. Avalike API-de puhul kaks põhiversiooni. Sisemiste API-de puhul üks väljalasketsükkel.

Kuidas aegumisest teavitatakse. Koodimärkused, muudatuste logi kirjed ja teadaolevate tarbijate otsene teavitamine. Ainult koodikommentaaris olev aegumise teade jääb märkamata.

Mida tähendab „eemaldatud“? Kas kood on kustutatud? Kas see on teisaldatud eraldi valikulisse paketti? Kas see on peidetud funktsioonilipu taha? Määratlege lõppseisund selgelt.

Kuidas migratsiooniteed dokumenteeritakse. Iga aegumise märkus peaks sisaldama viidet asendusele. @deprecated Use fetchUserById() instead on kasulikum kui @deprecated.

Kas aegunud kood ikka veel töötab?

Jah, kuni see enam ei tööta. Vananenud kood töötab normaalselt kuni versioonini, kust see tegelikult eemaldatakse. See on vanadusest mõjutatud koodi kõige ohtlikum omadus: see loob vale turvatunde. Süsteemid, mis on aastaid töötanud vanadusest mõjutatud API-del, võivad tunduda stabiilsed, samas kui äkilise rikke oht kasvab iga väljalasketsükliga.

Vastus küsimusele „kas aegunud koodi käitamine on ohutu?“ on järgmine: see sõltub sellest, kui lähedal on eemaldamiskuupäev ja milline on aegunud komponendi turvaseisund. Aktiivselt hooldatava teegi väiksemas versioonis aegunud funktsioon, millel puuduvad teadaolevad CVE-d, kujutab endast väikest otsest riski. Vananenud autentimisteegil, millel on parandamata haavatavus ja teada antud eluea lõppkuupäev, on suur otsene risk.

Kuidas SMART TS XL Tuvastab ettevõtte süsteemides aegunud koodi

Ühe keele projektis on aegunud koodi leidmine õige kompilaatori lipu või lint-reegli käivitamise küsimus. Ettevõtte keskkonnas, mis hõlmab COBOLi, JCL-i, Java't, Pythoni ja kaasaegseid teenuseid, tuleb iga keele aegunud komponendid leida samaaegselt ning nendevahelised seosed on sama olulised kui aegumised ise.

SMART TS XL'S staatilise koodi analüüs skannib kõiki keskkonnas olevaid keeli ja tuvastab samaaegselt kogu koodibaasis aegunud annotatsioonid, aegunud API kasutusviisid ja surnud koodimustrid. Kui COBOL-i koodiraamat märgitakse aegunuks, SMART TS XL identifitseerib iga programmi, mis seda sisaldab. Kui Java API meetod on aegunud, jälgib see iga kutse saiti igas portfelli teenuses.

Mõjuanalüüsi võimalus viib selle sammu edasi: enne mis tahes aegunud komponendi eemaldamist genereerib see täieliku ulatuse sellest , mida see eemaldamine mõjutab – milliseid programme, milliseid töövooge, milliseid allavooluteenuseid – igas keeles. See teisendab riskantse küsimuse „mis katki läheb?“ struktureeritud ja loetletud loendiks kõigest, mis tuleb enne eemaldamise jätkamist valideerida.

Ettevõtte otsinguvõimalus muudab inventuuri päringutega kontrollitavaks: leia sekunditega iga konkreetse aegunud funktsiooni kasutus, iga viide aegunud koodiraamatule, iga kutse aegunud API-le miljonite koodiridade kaudu mitmes keeles. Vananenud moderniseerimisprogrammide puhul, kus aegunud komponentide inventuur on migratsiooni ulatuse määramise lähtepunkt, asendab see otsinguvõimalus nädalatepikkuse käsitsi auditeerimise sihipärase päringuga.