JavaRush /Блоги Java /Random-TG /Принсипҳои SOLID, ки рамзи шуморо тозатар мекунанд
Paul Soia
Сатҳи
Kiyv

Принсипҳои SOLID, ки рамзи шуморо тозатар мекунанд

Дар гурӯҳ нашр шудааст
SOLID чист? Ин аст он чизе ки ихтисораи SOLID маънои онро дорад: - S:  Принсипи масъулияти ягона . - О: Принсипи кушода-пўшида  . - Л: Принсипи ивазкунии Лисков  . - I: Принсипи сегрегатсияи интерфейс  . - D: Принсипи инversionи вобастагӣ  . Принсипҳои SOLID маслиҳат медиҳанд, ки чӣ гуна тарҳрезии модулҳо, яъне. хиштхое, ки аз онхо ариза сохта мешавад. Мақсади принсипҳо тарҳрезии модулҳое мебошад, ки: - мусоидат ба тағйирот - ба осонӣ фаҳмо - такроран истифода мешаванд Пас, биёед бубинем, ки онҳо бо мисолҳо чӣ гунаанд.
class MainRepository(
    private val auth: FirebaseAuth
) {
    suspend fun loginUser(email: String, password: String) {
        try {
            auth.signInWithEmailAndPassword(email, password)
        } catch (e: Exception) {
            val file = File("errors.txt")
            file.appendText(text = e.message.toString())
        }
    }
}
Мо дар ин мисол чиро мебинем? FirebaseAuth дар созанда интиқол дода мешавад ва мо онро барои ворид шудан истифода мебарем. Агар мо дар ҷавоб хатогӣ гирем, мо паёмро ба файл менависем. Акнун биёед бубинем, ки ин code чӣ хато дорад. 1. S: Принсипи масъулияти ягона  : Синф (ё функсия/метод) бояд танҳо барои як чиз масъул бошад. Агар синф барои ҳалли якчанд масъалаҳо масъул бошад, зерсистемаҳои он, ки ҳалли ин масъалаҳоро амалӣ мекунанд, бо ҳам пайваст мешаванд. Таѓйирот дар як зерсистема боиси таѓйироти зерсистемаи дигар мегардад. Дар мисоли мо, функсияи loginUser барои ду чиз масъул аст - ворид шудан ва навиштани хато ба файл. Барои он ки як масъулият вуҷуд дошта бошад, мантиқи сабти хато бояд дар синфи алоҳида ҷойгир карда шавад.
class FileLogger{
    fun logError(error: String) {
        val file = File("errors.txt")
        file.appendText(text = error)
    }
}
class MainRepository(
    private val auth: FirebaseAuth,
    private val fileLogger: FileLogger,
) {
    suspend fun loginUser(email: String, password: String) {
        try{
            auth.signInWithEmailAndPassword(email, password)
        } catch (e: Exception) {
            fileLogger.logError(e.message.toString())
        }
    }
}
Мантиқи сабти хатогӣ ба синфи алоҳида гузаронида шуд ва ҳоло усули loginUser танҳо як масъулият дорад - иҷозат. Агар мантиқи сабти хатоҳо бояд тағир дода шавад, мо инро дар синфи FileLogger иҷро мекунем, на дар функсияи loginUser 2. O: Принсипи кушода-пӯшида  : Объектҳои нармафзор (синфҳо, модулҳо, функсияҳо) бояд барои васеъшавӣ кушода бошанд. аммо на барои тағир додан. Дар ин замина, кушодагӣ ба васеъшавӣ қобorяти илова кардани рафтори нав ба синф, модул ё функсия дар сурати зарурат ва баста будани тағирот манъи тағир додани рамзи сарчашмаи an objectҳои нармафзор мебошад. Ин дар назари аввал мураккаб ва зиддиятнок менамояд. Аммо агар шумо ба он нигоҳ кунед, принсип комилан мантиқист. Мувофиқи принсипи OCP ин аст, ки нармафзор на бо иваз кардани рамзи мавҷуда, балки бо илова кардани рамзи нав иваз карда мешавад. Яъне, codeи дар ибтидо сохташуда "бетаъхир" ва устувор боқӣ мемонад ва функсияҳои нав ё тавассути мероси амалӣ ё тавассути истифодаи интерфейсҳои абстрактӣ ва полиморфизм ҷорӣ карда мешаванд. Пас биёед ба синфи FileLogger назар кунем. Агар ба мо лозим ояд, ки сабтҳоро ба файли дигар нависем, мо метавонем номро тағир диҳем:
class FileLogger{
    fun logError(error: String) {
        val file = File("errors2.txt")
        file.appendText(text = error)
    }
}
Аммо пас аз он ҳама гузоришҳо ба файли нав навишта мешаванд, ки эҳтимолан ба мо лозим нест. Аммо чӣ гуна мо метавонем сабти худро бидуни тағир додани худи синф иваз кунем?
open class FileLogger{

    open fun logError(error: String) {
        val file = File("error.txt")
        file.appendText(text = error)
    }

}

class CustomErrorFileLogger : FileLogger() {

    override fun logError(error: String) {
        val file = File("my_custom_error_file.txt")
        file.appendText(text = error)
    }

}
Мо синфи FileLogger ва функсияи logError-ро кушода қайд мекунем, синфи нави CustomErrorFileLogger эҷод мекунем ва татбиқи нави сабти номро менависем. Дар натиҷа, синфи мо барои васеъ кардани функсия дастрас аст, аммо барои тағир додан баста аст. 3. Л: Принсипи ивазкунии Лисков  . Зарур аст, ки зерсинфҳо ҳамчун ивазкунандаи синфҳои худ хидмат кунанд. Мақсади ин принсип аз он иборат аст, ки синфҳои наслӣ метавонанд ба ҷои синфҳои волидайне, ки онҳо аз онҳо гирифта шудаанд, бидуни вайрон кардани барнома истифода шаванд. Агар маълум шавад, ки code навъи синфро тафтиш мекунад, пас принсипи ивазкунӣ вайрон карда мешавад. Агар мо синфи ворисиро чунин нависем:
class CustomErrorFileLogger : FileLogger() {

    fun customErrorLog(error: String) {
        val file = File("my_custom_error_file.txt")
        file.appendText(text = error)
    }

}
Ва акнун биёед синфи FileLogger-ро бо CustomErrorFileLogger дар анбор иваз кунем
class MainRepository(
    private val auth: FirebaseAuth,
    private val fileLogger: CustomErrorFileLogger,
) {

    suspend fun loginUser(email: String, password: String) {
        try{
            auth.signInWithEmailAndPassword(email, password)
        }catch(e: Exception) {
            fileLogger.logError(e.message.toString())
        }
    }

}
Дар ин ҳолат, logError аз синфи волидайн даъват карда мешавад, ё шумо бояд зангро ба fileLogger.logError(e.message.toString()) ба fileLogger.customErrorLog(e.message.toString()) иваз кунед 4. Ман : Принсипи ҷудокунии интерфейс. Эҷоди интерфейсҳои хеле махсусгардонидашуда барои муштарии мушаххас. Мизоҷон набояд аз интерфейсҳои истифоданашаванда вобаста бошанд. Ин мураккаб садо медиҳад, аммо ин дар асл хеле содда аст. Масалан, биёед синфи FileLoggerро интерфейс гардонем, аммо ба он як функсияи дигар илова кунед:
interface FileLogger{

    fun printLogs()

    fun logError(error: String) {
        val file = File("errors.txt")
        file.appendText(text = error)
    }

}
Акнун аз ҳамаи наслҳо талаб карда мешавад, ки функсияи printLogs -ро иҷро кунанд, ҳатто агар мо ба он дар ҳама синфҳои наслӣ ниёз надорем.
class CustomErrorFileLogger : FileLogger{

    override fun printLog() {

    }

    override fun logError(error: String) {
        val file = File("my_custom_error_file.txt")
        file.appendText(text = error)
    }

}
ва ҳоло мо вазифаҳои холӣ хоҳем дошт, ки ин барои тозагии code бад аст. Ба ҷои ин, мо метавонем дар интерфейс арзиши пешфарз созем ва он гоҳ функсияро танҳо дар ҳамон синфҳое, ки ба он лозим аст, бекор кунем:
interface FileLogger{

    fun printLogs() {
        //Howая-то дефолтная реализация
    }

    fun logError(error: String) {
        val file = File("errors.txt")
        file.appendText(text = error)
    }

}
class CustomErrorFileLogger : FileLogger{

    override fun logError(error: String) {
        val file = File("my_custom_error_file.txt")
        file.appendText(text = error)
    }

}
Акнун синфҳое, ки интерфейси FileLogger-ро амалӣ мекунанд, тозатар хоҳанд шуд. 5. D: Принсипи инversionи вобастагӣ  . Объекти вобастагӣ бояд абстраксия бошад, на чизи мушаххас. Биёед ба синфи асосии худ баргардем:
class MainRepository(
    private val auth: FirebaseAuth,
    private val fileLogger: FileLogger,
) {

    suspend fun loginUser(email: String, password: String) {
        try{
            auth.signInWithEmailAndPassword(email, password)
        } catch (e: Exception) {
            fileLogger.logError(e.message.toString())
        }
    }

}
Чунин ба назар мерасад, ки мо дар ин ҷо ҳама чизро аллакай танзим ва ислоҳ кардаем. Аммо боз як нуктаи дигаре ҳаст, ки бояд тағир дода шавад. Ин синфи FirebaseAuth-ро истифода мебарад. Чӣ мешавад, агар дар ягон лаҳза ба мо лозим ояд, ки иҷозатро тағир диҳем ва на тавассути Firebase, балки, масалан, бо истифода аз ягон намуди дархости API ворид шавем? Он гоҳ мо бояд бисёр чизҳоро тағир диҳем ва мо инро намехоҳем. Барои ин кор бо функсияи signInWithEmailAndPassword(email: String, password: String) интерфейс эҷод кунед:
interface Authenticator{
    fun signInWithEmailAndPassword(email: String, password: String)
}
Ин интерфейс абстраксияи мост. Ва ҳоло мо татбиқи мушаххаси воридшавӣ мекунем
class FirebaseAuthenticator : Authenticator{

    override fun signInWithEmailAndPassword(email: String, password: String) {
        FirebaseAuth.getInstance().signInWithEmailAndPassword(email, password)
    }

}
class CustomApiAuthenticator : Authenticator{

    override fun signInWithEmailAndPassword(email: String, password: String) {
        //другой способ логина
    }

}
Ва дар синфи 'MainRepository' ҳоло вобастагӣ аз татбиқи мушаххас вуҷуд надорад, балки танҳо аз абстраксия
class MainRepository (
    private val auth: Authenticator,
    private val fileLogger: FileLogger,
) {

    suspend fun loginUser(email: String, password: String) {
        try{
            auth.signInWithEmailAndPassword(email, password)
        }catch(e: Exception) {
            fileLogger.logError(e.message.toString())
        }
    }

}
Ва ҳоло, барои тағир додани усули иҷозатдиҳӣ, мо бояд танҳо як сатрро дар синфи модул иваз кунем.
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION