Məzmuna keç
Educora
Universitet25 dəq58 / 59

Proqram təminatı mühəndisliyi

Proqram təminatının həyat dövrünü, çevik üsulları və Scrum-ı, Git ilə versiyalara nəzarəti, test səviyyələrini, SOLID prinsiplərini və kod icmalını öyrən.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Şəlalə və çevik modelləri müqayisə etmək, Scrum rollarını və tədbirlərini izah etmək
  • Git-də budaqlarla işləmək və dəyişikliyi təhlükəsiz ləğv etmək
  • Test səviyyələrini seçmək və tsiklomatik mürəkkəbliyi hesablamaq
  • Kodda SOLID prinsiplərinin pozulmasını tanımaq

Tək başına 200 sətirlik skript yazmaq proqramlaşdırmadır; 50 nəfərlik komandanın illərlə milyonlarla sətir kodu inkişaf etdirməsi, sınaması və heç nəyi sındırmadan hər həftə yeniləməsi isə proqram təminatı mühəndisliyidir. Burada əsas çətinlik alqoritm deyil, mürəkkəblik, dəyişən tələblər və insanlar arasında ünsiyyətdir. Bu dərsdə peşəkar komandaların bu problemləri necə idarə etdiyini öyrənəcəyik.

Həyat dövrü: şəlalədən çevik üsullara

  1. 1
    Tələblər

    Sistem nə etməlidir (funksional) və necə yaxşı etməlidir (sürət, təhlükəsizlik — qeyri-funksional)?

  2. 2
    Layihələndirmə

    Arxitektura, modullar, verilənlər bazası, interfeyslər.

  3. 3
    Reallaşdırma

    Kodun yazılması, kod icmalı, versiyalara nəzarət.

  4. 4
    Testləşdirmə

    Vahid, inteqrasiya, sistem və qəbul testləri.

  5. 5
    Yerləşdirmə və dəstək

    Buraxılış, monitorinq, səhvlərin düzəldilməsi və yeni tələblər — sistemin ömrünün ən uzun hissəsi.

MeyarŞəlalə (waterfall)Çevik (agile)
mərhələlərardıcıl, bir dəfəqısa iterasiyalarda təkrarlanır
tələblərin dəyişməsibahalıgözlənilir və qəbul olunur
müştəri işləyən proqramı görürsondahər 1–4 həftədən bir
uyğun olduğu yersabit tələblər, ciddi tənzimləmə (tibb, aviasiya)qeyri-müəyyən bazar, veb və mobil məhsullar

2001-ci ildə qəbul edilmiş Çevik manifest işləyən proqramı, müştəri ilə əməkdaşlığı və dəyişikliyə hazır olmağı ön plana çəkir. Ən populyar çevik çərçivə Scrum-dır. Onun üç rolu var: Product Owner (məhsul sahibi — Product Backlog-u və prioritetləri idarə edir), Scrum Master (prosesə kömək edir, maneələri aradan qaldırır) və Developers (işi görən komanda). İş sprintlərlə — bir aya qədər sabit müddətli dövrlərlə aparılır: Sprint Planning, hər gün 15 dəqiqəlik Daily Scrum, sonda Sprint Review (nəticənin nümayişi) və Retrospective (prosesin təkmilləşdirilməsi).

Nümunə 1: sürətə görə proqnoz

Product Backlog-da 150 hekayə xalı (story point) qalıb. Son üç sprintdə komanda 16, 20 və 18 xal tamamlayıb. Sprint 2 həftədir. Buraxılışa təxminən nə qədər qalıb?

Həllini göstər
Orta sürət (velocity): (16 + 20 + 18) / 3 = 54 / 3 = 18 xal/sprint.
Sprintlərin sayı: ⌈150 / 18⌉ = ⌈8,33⌉ = 9 sprint.
Vaxt: 9 · 2 = 18 həftə (təxminən 4 ay).
Bu, vəd deyil, proqnozdur: hər sprintdən sonra yenilənir. Sürəti komandalar arasında müqayisə etmək olmaz — xallar hər komandanın öz şkalasıdır.
C = n(n − 1) / 2C = n(n − 1) / 2
burada:
  • Ckomandada cüt-cüt ünsiyyət kanallarının sayı
  • nkomanda üzvlərinin sayı

5 nəfər → 10 kanal, 10 nəfər → 45 kanal. Bu, Bruks qanununun izahıdır: gecikən layihəyə yeni insanlar əlavə etmək onu çox vaxt daha da gecikdirir. Scrum komandaları ona görə kiçik saxlanılır (adətən 10 nəfərə qədər).

Git ilə versiyalara nəzarət

Git paylanmış versiyalara nəzarət sistemidir: hər tərtibatçının kompüterində bütün tarixçə ilə tam repozitoriya var. Commit — layihənin «fotoşəkli»dir (dəyişikliklər, müəllif, vaxt, izah); commitlər zəncir əmələ gətirir və hər biri heş ilə adlanır. Budaq (branch) — commitə istinad edən hərəkətli göstəricidir: yeni funksiyanı ayrıca budaqda edib, hazır olanda pull request vasitəsilə yoxlamaya göndərir və əsas budağa birləşdirirsən (merge).

Terminal
git switch -c feature/login          # create and switch to a new branch
git add login.py
git commit -m 'Validate the login form'
git push -u origin feature/login     # then open a pull request

git switch main
git pull                             # get the reviewed and merged work
git revert 3f2a9c1                   # safely undo a bad pushed commit
Tipik iş axını. git revert səhv commiti ləğv edən yeni commit yaradır — tarixçə dəyişmir, ona görə ortaq budaqlar üçün təhlükəsizdir.

Testləşdirmə

SəviyyəNəyi yoxlayırSürət və say
Vahid (unit)bir funksiya və ya sinif, təcrid olunmuşmillisaniyələr, minlərlə
İnteqrasiyamodulların birgə işi (kod + verilənlər bazası, API)saniyələr, yüzlərlə
Sistem (end-to-end)bütün sistem istifadəçi kimidəqiqələr, onlarla
Qəbulmüştərinin tələblərinə uyğunluqburaxılışdan əvvəl
«Test piramidası»: aşağıda çoxlu sürətli vahid testləri, yuxarıda az sayda yavaş sistem testləri.
Python
def is_leap(year):
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

def buggy_is_leap(year):
    return year % 4 == 0

cases = {2024: True, 2023: False, 1900: False, 2000: True}

def run_tests(func):
    failed = [y for y, expected in cases.items() if func(y) != expected]
    return 'all passed' if not failed else 'FAILED for ' + str(failed)

print('is_leap:', run_tests(is_leap))
print('buggy_is_leap:', run_tests(buggy_is_leap))
▸ Gözlənilən nəticə
is_leap: all passed
buggy_is_leap: FAILED for [1900]
Yaxşı vahid testləri sərhəd hallarını da yoxlayır: 1900 4-ə bölünür, amma 100-ə bölünüb 400-ə bölünmədiyi üçün uzun il deyil. «Sadəlövh» versiya adi hallarda düzgün görünür və səhvi yalnız bu test tutur. Real layihələrdə eyni iş pytest və ya unittest ilə avtomatlaşdırılır və hər commitdə CI serverində işə düşür.
M = E − N + 2P (= qərarların sayı + 1)
burada:
  • MMakkeybin tsiklomatik mürəkkəbliyi: müstəqil yolların sayı
  • E, Nidarəetmə axını qrafının tilləri və düyünləri
  • Pəlaqəli komponentlərin sayı (bir funksiya üçün 1)

M — bütün budaqları əhatə etmək üçün lazım olan testlərin minimal sayının yaxşı təxminidir. M > 10 olan funksiyanı adətən kiçik hissələrə bölürlər.

Nümunə 2: tsiklomatik mürəkkəblik

is_leap funksiyası A and (B or C) qaytarır: A — «4-ə bölünür», B — «100-ə bölünmür», C — «400-ə bölünür». Onun tsiklomatik mürəkkəbliyi nədir və testlərimizdə nə üçün 4 hal var?

Həllini göstər
Qısa hesablanan hər məntiqi operator (and, or) bir qərar nöqtəsidir: 2 qərar → M = 2 + 1 = 3.
3 baza yolu: A yalan → 2023; A doğru, B doğru → 2024; A doğru, B yalan → nəticə C-nin özüdür.
Üçüncü yol C-ni qaytardığı üçün onun hər iki qiymətini yoxlayırıq: 1900 (C yalan) və 2000 (C doğru).
Deməli, M = 3 yolların əhatəsi üçün minimumdur, 4 test isə tam şərt əhatəsi verir — məhz bizim cases lüğətimiz.

SOLID və kod icmalı

PrinsipMənası
S — tək məsuliyyətsinfin dəyişməsi üçün yalnız bir səbəb olmalıdır
O — açıq/qapalıgenişlənməyə açıq, dəyişikliyə qapalı: yeni davranışı yeni kodla əlavə et
L — Liskov əvəzetməsialt sinfin obyekti baza sinfin yerində problemsiz işləməlidir
I — interfeysin ayrılmasıböyük interfeys əvəzinə bir neçə kiçik, konkret interfeys
D — asılılığın inversiyasıkonkret sinifdən yox, abstraksiyadan asılı ol
Python
from abc import ABC, abstractmethod

class Discount(ABC):
    @abstractmethod
    def apply(self, price): ...

class NoDiscount(Discount):
    def apply(self, price):
        return price

class Percent(Discount):
    def __init__(self, p):
        self.p = p
    def apply(self, price):
        return round(price * (1 - self.p / 100), 2)

class StudentCard(Discount):
    def apply(self, price):
        return max(price - 5, 0)

def checkout(price, discount: Discount):
    return discount.apply(price)

for d in [NoDiscount(), Percent(20), StudentCard()]:
    print(type(d).__name__, checkout(50, d))
▸ Gözlənilən nəticə
NoDiscount 50
Percent 40.0
StudentCard 45
checkout konkret endirimlərdən deyil, Discount abstraksiyasından asılıdır (D). Yeni endirim növü əlavə etmək üçün checkout-u dəyişmək lazım deyil — yeni sinif yazmaq kifayətdir (O). Hər alt sinif Discount gözlənilən yerdə işləyir (L).

Kod icmalı (code review) — dəyişikliyin əsas budağa düşməzdən əvvəl başqa tərtibatçı tərəfindən yoxlanmasıdır. Rəyçi düzgünlüyə, testlərə, oxunaqlılığa, təhlükəsizliyə və dizayna baxır; üslubu isə avtomatik alətlər (linter, formatlayıcı) yoxlamalıdır. İcmal səhvləri tutmaqla yanaşı, biliyi komandaya yayır: sistemin hər hissəsini ən azı iki nəfər tanıyır. Kiçik pull request-lər (bir neçə yüz sətirdən az) daha diqqətlə oxunur.

Əsas fikirlər

  • Həyat dövrü: tələblər → layihələndirmə → reallaşdırma → test → yerləşdirmə və dəstək; çevik üsullar onu qısa iterasiyalarda təkrarlayır.
  • Scrum: Product Owner, Scrum Master, Developers; bir aya qədər sprintlər və dörd tədbir.
  • Git: commit — fotoşəkil, budaq — göstərici; ortaq budaqda tarixçəni yenidən yazma, revert işlət.
  • Test piramidası: çoxlu vahid, az sistem testi; tsiklomatik mürəkkəblik M = qərarlar + 1.
  • SOLID dəyişikliyə davamlı dizayn verir; kod icmalı səhvləri tutur və biliyi yayır; komanda kanalları n(n − 1)/2 kimi artır.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
8 nəfərlik komandada neçə cüt-cüt ünsiyyət kanalı var?