Принсипҳои SOLID: чӣ тавр кодамонро тозатар ва нигоҳдориашро осонтар кунем?
Агар бо барномасозии объектгаро кор карда бошӣ, эҳтимол ба коде дучор шудаӣ, ки тағйир додани як қисми хурдаш боиси вайрон шудани се қисми дигар мешавад! 😐
Масалан, як класс дорӣ, ки ҳам почтаи электронӣ мефиристад, ҳам маълумотро дар пойгоҳи додаҳо нигоҳ медорад, ҳам лог менависад ва ҳам ҳисобот месозад.
Баъд касе меояду мегӯяд:
«Фақат низоми фиристодани почтаи электрониро тағйир деҳ».
Ва ту ба худ мегӯӣ:
«Фақат?! 😂»
Маҳз ҳамин ҷо принсипҳои SOLID ба кумак меоянд.
SOLID маҷмӯи панҷ принсипи муҳими тарҳрезии нармафзор аст, ки кумак мекунанд кодамон:
- нигоҳдориаш осонтар бошад;
- осонтар тағйир дода шавад;
- санҷиданаш осонтар бошад;
- вобастагиҳои камтар дошта бошад;
- дар лоиҳаҳои калон камтар ба дарди сар табдил ёбад. 😄
Биё, онҳоро як-як баррасӣ кунем.
S — Single Responsibility Principle — Принсипи масъулияти ягона
Принсипи аввал мегӯяд:
Ҳар класс бояд танҳо як масъулият дошта бошад ва танҳо бо як сабаб тағйир ёбад.
Фарз кун, классе дорем, ки барои идоракунии корбар масъул аст:
class User {
createUser(user) {
// Нигоҳ доштани корбар дар пойгоҳи додаҳо
}
sendEmail(user) {
// Фиристодани почтаи электронӣ
}
generateReport(user) {
// Сохтани ҳисобот
}
}
Дар назари аввал шояд мушкиле набинем.
Аммо ин класс ҳоло чанд масъулияти гуногун дорад:
User
├── Идоракунии корбар
├── Фиристодани почтаи электронӣ
└── Сохтани ҳисобот
Ҳоло агар низоми почтаи электронӣ тағйир ёбад, бояд класси User-ро тағйир диҳем.
Агар низоми ҳисоботсозӣ тағйир ёбад, боз бояд ҳамин классро тағйир диҳем.
Агар пойгоҳи додаҳо иваз шавад, боз ҳам...
Яъне як класс метавонад бо чанд сабаби гуногун тағйир ёбад.
Роҳи беҳтар кадом аст?
Масъулиятҳоро аз ҳам ҷудо кунем:
class UserService {
createUser(user) {
// Нигоҳ доштани корбар
}
}
class EmailService {
sendEmail(user) {
// Фиристодани почтаи электронӣ
}
}
class ReportService {
generateReport(user) {
// Сохтани ҳисобот
}
}
Ҳоло ҳар класс як кори мушаххасро иҷро мекунад:
UserService
↓
Идоракунии корбар
EmailService
↓
Фиристодани почтаи электронӣ
ReportService
↓
Сохтани ҳисобот
Ин ҳамон принсипи масъулияти ягона аст.
O — Open/Closed Principle — Принсипи кушода/пӯшида
Принсипи дуюм мегӯяд:
Классҳо бояд барои васеъ кардани имкониятҳо кушода ва барои тағйир додани коди мавҷуда пӯшида бошанд.
Дар аввал ин ҷумла каме аҷиб менамояд. 😐
Ин чӣ маъно дорад?
Яъне вақте мехоҳем имконияти наве илова кунем, беҳтар аст маҷбур набошем коди пешинаро пайваста тағйир диҳем.
Фарз кун, низоми пардохт дорем:
class Payment {
pay(type) {
if (type === "card") {
// Пардохт бо корт
}
if (type === "paypal") {
// Пардохт бо PayPal
}
}
}
Ҳоло фардо мехоҳем пардохтро тавассути инҳо ҳам илова кунем:
- Bitcoin
- Apple Pay
- Google Pay
Пас боз ба ҳамин класс бармегардем ва як қатор if илова мекунем:
if (type === "bitcoin") {
// ...
}
if (type === "applepay") {
// ...
}
Ҳар дафъа, ки имконияти нав илова мекунем, коди пешинаро тағйир медиҳем.
Яке аз роҳҳои беҳтар ин аст, ки рафторҳои гуногунро аз ҳам ҷудо кунем:
class CardPayment {
pay() {
console.log("Пардохт бо корт");
}
}
class PaypalPayment {
pay() {
console.log("Пардохт бо PayPal");
}
}
class BitcoinPayment {
pay() {
console.log("Пардохт бо Bitcoin");
}
}
Ҳоло агар усули нави пардохт илова кунем, лозим нест классҳои пешинаро тағйир диҳем.
Танҳо як класси нав илова мекунем:
class ApplePayPayment {
pay() {
console.log("Пардохт бо Apple Pay");
}
}
Яъне низом барои васеъ кардани имкониятҳо кушода аст, вале то ҳадди имкон ба тағйир додани коди пешина ниёз надорад.
L — Liskov Substitution Principle — Принсипи ҷойгузинии Лисков
Принсипи сеюм аз ҳамон принсипҳоест, ки номаш каме тарсонанда аст! 😂
Принсипи ҷойгузинии Лисков мегӯяд:
Ҳар ҷое, ки аз класси волидайн истифода мекунем, бояд тавонем аз класси фарзанд ҳам истифода кунем, бе он ки рафтори барнома вайрон шавад.
Мисоли машҳур барои ин мавзуъ паранда ва пингвин аст.
Фарз кун:
class Bird {
fly() {
console.log("Дар ҳоли парвоз...");
}
}
Ҳоло менависем:
class Penguin extends Bird {
}
Мушкил дар чист?
Пингвин паранда аст, аммо парвоз карда наметавонад.
Пас агар ин корро кунем:
const bird = new Penguin();
bird.fly();
Ба мушкил дучор мешавем.
Зеро қарордоди класси Bird мегӯяд:
«Ҳар паранда бояд қобилияти fly() дошта бошад».
Аммо Penguin наметавонад ин шартро риоя кунад.
Роҳи беҳтар ин аст, ки тарҳро ислоҳ кунем:
class Bird {
}
class FlyingBird extends Bird {
fly() {
console.log("Дар ҳоли парвоз...");
}
}
class Penguin extends Bird {
}
Ҳоло сохтор чунин мешавад:
Bird
├── FlyingBird
│ ├── Eagle
│ └── Sparrow
│
└── Penguin
Дигар пингвин маҷбур нест методе дошта бошад, ки амали онро иҷро карда наметавонад.
Пас принсипи Лисков мегӯяд:
Меросбарӣ набояд боиси он шавад, ки класси фарзанд қарордоди класси волидайнро вайрон кунад.
I — Interface Segregation Principle — Принсипи ҷудокунии интерфейсҳо
Принсипи чорум мегӯяд:
Классҳо набояд маҷбур шаванд интерфейсҳоеро амалӣ кунанд, ки ба онҳо ниёз надоранд.
Фарз кун, чунин интерфейс дорем:
interface Worker {
work();
eat();
sleep();
}
Ҳоло як робот дорем:
class Robot implements Worker {
work() {
// Кор кардан
}
eat() {
// 😐 Робот хӯрок намехӯрад-ку!
}
sleep() {
// 😐 Робот хоб ҳам намекунад!
}
}
Ин тарҳ чандон хуб нест.
Зеро Robot маҷбур шудааст методҳоеро амалӣ кунад, ки умуман ба онҳо эҳтиёҷ надорад.
Беҳтар аст интерфейси калонро ба интерфейсҳои хурдтар ҷудо кунем:
interface Workable {
work();
}
interface Eatable {
eat();
}
interface Sleepable {
sleep();
}
Ҳоло инсон метавонад ҳамаи онҳоро амалӣ кунад:
class Human implements Workable, Eatable, Sleepable {
}
Вале робот танҳо интерфейси заруриро:
class Robot implements Workable {
}
Ин маҳз маънои ҷудокунии интерфейсҳост.
Яъне:
Интерфейсҳои калон ва серметодро ба қарордодҳои хурдтару махсус ҷудо кунем.
D — Dependency Inversion Principle — Принсипи чаппакунии вобастагӣ
Ва ба принсипи охирин мерасем: чаппакунии вобастагӣ.
Ин принсип мегӯяд:
Классҳои сатҳи боло набояд бевосита ба ҷузъиёти сатҳи поён вобаста бошанд; ҳар ду бояд ба абстраксия вобаста бошанд.
Фарз кун, чунин хидмат дорем:
class MySQLDatabase {
save(data) {
console.log("Нигоҳдорӣ дар MySQL");
}
}
class UserService {
constructor() {
this.database = new MySQLDatabase();
}
saveUser(user) {
this.database.save(user);
}
}
Дар ин ҷо UserService бевосита ба MySQLDatabase вобаста шудааст.
Яъне агар фардо қарор диҳем, ки MySQL-ро бо MongoDB иваз кунем, бояд UserService-ро тағйир диҳем.
Беҳтар аст вобастагиро аз берун ба он диҳем:
class UserService {
constructor(database) {
this.database = database;
}
saveUser(user) {
this.database.save(user);
}
}
Ҳоло метавонем ҳар пойгоҳи додаҳоеро, ки қарордоди заруриро риоя мекунад, ба он диҳем:
const mysql = new MySQLDatabase();
const userService = new UserService(mysql);
Ё:
const mongo = new MongoDatabase();
const userService = new UserService(mongo);
Дар натиҷа, барои UserService дигар муҳим нест, ки маълумот маҳз дар куҷо нигоҳ дошта мешавад.
Он танҳо медонад:
Database
↓
save()
Яъне вобастагии мо ба абстраксия аст, на ба як тарзи мушаххаси амалисозӣ.
Пас SOLID дар як нигоҳ чӣ маъно дорад?
Агар ҳамаи инро хеле кӯтоҳ баён кунем:
- S → Як класс, як масъулият.
- O → Барои васеъ кардани имкониятҳо кушода, барои тағйир додани коди мавҷуда пӯшида.
- L → Класси фарзанд бояд ҷойгузини класси волидайн шуда тавонад.
- I → Интерфейсҳои хурд ва махсус.
- D → Вобастагӣ ба абстраксия, на ба амалисозии мушаххас.
Аммо як нуктаи муҳим ҳаст.
SOLID қонуни қатъиву тағйирнопазири барномасозӣ нест.
Қарор нест ҳар ҷое як класс дидӣ, зуд панҷ интерфейс ва даҳ класс созӣ! 😂
Ҳадафи SOLID ин аст, ки ҳангоми калон шудани лоиҳа ва тағйир ёфтани талабот қисмҳои кодамон ба ҳам камтар вобаста бошанд ва тағйир додани як қисм тамоми низомро вайрон накунад.
Дар асл метавон гуфт:
SOLID бештар аз он ки дар бораи камтар навиштани код бошад, дар бораи навиштани кодест, ки тағйир доданаш дарди сари камтар дорад.
Мақолаҳои маъмул
Ҳар роҳе, ки интихоб мекунӣ
Ҳаёт мисли як ҳавопаймоест, ки ту худат пилот ҳастӣ, на мусофир. Танҳо ту қодирӣ самти ҳаракатро интихоб кунӣ, баландӣ ва суръатро муайян намоӣ. Агар раҳнамоиро ба дигарон супорӣ, хавфи гум кардани роҳи ҳақиқии худ вуҷуд дорад. Дар ҳар як қарор, дар ҳар
Насиҳати Падар
Падарам ҳар вақт, ки вориди утоқам мешуд ва медид, ки чароғи хона ё дастгоҳи шамолдиҳӣ рӯшан асту ман аз утоқам берунам, мегуфт: - Барои чи чароғ ва дигар асбобҳои барқиро хомӯш намекунӣ ва барқро беҳуда сарф менамоӣ? Вақте, ки вориди ҳамом мешуд ва
Ростгӯи камоли инсонист.
Ростиро набувад ҳеҷ заволе ба миён. Сарв агар хушк шавад боз асо мегардад. Ростию ростгӯӣ ва росткорӣ фазилатҳои хуби инсонианд. Агар инсон дорои ин хислатҳои бузург бошад, дар ягон давру замон обрую эътибор ва бузургию соҳибиззатии хешро аз даст
МУҚАДАСОТИ МО
Дар Конститутсияи (Сарқонуни) Ҷумҳурии Тоҷикистон махсус қайд гирифтааст, ки «Рамзҳои давлатии Тоҷикистон Парчам, Нишон ва Суруди Миллӣ аст». Барои ҳар як тоҷикистонӣ Ватан, миллат, забони тоҷикӣ, Парчам, Нишони давлатӣ, Суруди миллӣ муқаддасанд. Мо ба

Барномасозӣ
Олами Афсонаҳо
Ахбор
Дунё