JavaRush /Java Blog /Random-TK /Koduňyzy has arassa etjek SOLID ýörelgeleri
Paul Soia
Dereje
Kiyv

Koduňyzy has arassa etjek SOLID ýörelgeleri

Toparda çap edildi
SOLID näme? SOLID gysgaldylyşynyň manysy: - S: leeke  jogapkärçilik ýörelgesi. - O: Açyk prinsip  . - L: Liskowyň ornuny tutmak ýörelgesi  . - I: Interfeýsi bölmek ýörelgesi  . - D: baglylyk öwrülişigi ýörelgesi  . SOLID ýörelgeleri modullary nädip düzmelidigini maslahat berýär. goýlan kerpiç. Principlesörelgeleriň maksady: - üýtgemegi öňe sürmek - aňsat düşünilýän - gaýtadan ulanyp boljak modullary dizaýn etmek. Geliň, mysallar bilen olaryň nämedigine seredeliň.
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())
        }
    }
}
Bu mysalda näme görýäris? “FirebaseAuth” konstruktorda geçýär we biz ony girmäge synanyşýarys. Jogap hökmünde ýalňyşlyk alsak, habary bir faýla ýazýarys. Indi bu koduň nämedigini göreliň. 1. S: leeke-täk jogapkärçilik ýörelgesi  : Bir synp (ýa-da funksiýa / usul) diňe bir zat üçin jogapkär bolmaly. Bir synp birnäçe meseläni çözmek üçin jogapkär bolsa, bu meseleleriň çözgüdini durmuşa geçirýän kiçi ulgamlary biri-birine baglydyr. Şeýle kiçi ulgamyň biriniň üýtgemegi beýlekisiniň üýtgemegine getirýär. Mysal üçin, loginUser funksiýasy iki zat üçin jogapkärdir - girmek we bir faýla ýalňyşlyk ýazmak. Bir jogapkärçiligiň bolmagy üçin ýalňyş ýazmagyň logikasy aýratyn synpda ýerleşdirilmelidir.
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())
        }
    }
}
Erroralňyş ýazgy logikasy aýratyn klasa geçirildi we indi loginUser usulynyň diňe bir jogapkärçiligi bar - ygtyýarnama. Erroralňyş ýazgy logikasyny üýtgetmeli bolsa, loginUser 2 funksiýasynda däl-de, FileLogger synpynda ederis. O: Açyk ýapyk  ýörelge: Programma üpjünçiligi guramalary (synplar, modullar, funksiýalar) giňeltmek üçin açyk bolmaly, ýöne üýtgetmek üçin däl. Bu nukdaýnazardan, giňeltmek üçin açyklyk, zerurlyk ýüze çyksa synpa, modula ýa-da funksiýa täze özüni alyp barmak ukybydyr we üýtgetmek ýapyklygy programma üpjünçiliginiň deslapky koduny üýtgetmegiň gadaganlygydyr. Bir seretseň, bu çylşyrymly we gapma-garşy görünýär. Itöne seretseň, prinsip gaty mantykly. OCP ýörelgesine eýermek, programma üpjünçiliginiň bar bolan kody üýtgetmek bilen däl-de, täze kod goşmak bilen üýtgedilmegi. .Agny, ilkibaşda döredilen kod “üýtgewsiz” we durnukly bolup galýar we täze funksiýa miras mirasy ýa-da abstrakt interfeýsler we polimorfizm ulanmak arkaly girizilýär. Geliň, FileLogger synpyna seredeliň. Başga bir faýla surnal ýazmaly bolsa, adyny üýtgedip bileris:
class FileLogger{
    fun logError(error: String) {
        val file = File("errors2.txt")
        file.appendText(text = error)
    }
}
Thenöne soň ähli ýazgylar täze faýla ýazylar, bu, ähtimal, bize gerek däl. Classöne synpyň özüni üýtgetmän ýazgymyzy nädip üýtgedip bileris?
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 synpyny we logError funksiýasyny açyk diýip belleýäris, täze CustomErrorFileLogger synpyny döredýäris we täze hasaba alyş amalyny ýazýarys. Netijede, synpymyz işlemegi giňeltmek üçin elýeterli, ýöne üýtgetmek üçin ýapyk. 3. L: Liskowyň ornuny tutmak ýörelgesi  . Kiçi klasslaryň superklassalarynyň ornuny tutup biljekdigi zerurdyr. Bu ýörelgäniň maksady, nesil synplaryny programmany bozmazdan alnan ene-atalar synplarynyň ýerine ulanyp bolar. Kod synpyň görnüşini barlaýan bolsa, çalyşmak ýörelgesi bozulýar. Eger mirasdüşer synpyny şeýle ýazan bolsak:
class CustomErrorFileLogger : FileLogger() {

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

}
Indi bolsa, FileLogger synpyny ammardaky CustomErrorFileLogger bilen çalyşalyň
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())
        }
    }

}
Bu ýagdaýda logError ene synpdan çagyrylar ýa-da jaňy fileLogger.logError (e.message.toString ()) -e FileLogger.customErrorLog (e.message.toString ()) 4. üýtgetmeli bolarsyňyz. :  Interfeýsi bölmek ýörelgesi Belli bir müşderi üçin döredilen ýokary ýöriteleşdirilen interfeýsleri dörediň. Müşderiler ulanmaýan interfeýslerine bagly bolmaly däldir. Çylşyrymly ýaly görünýär, ýöne aslynda gaty ýönekeý. Mysal üçin, “FileLogger” synpyny interfeýs edeliň, ýöne oňa ýene bir funksiýa goşalyň:
interface FileLogger{

    fun printLogs()

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

}
Indi ähli nesillerden, hatda ähli nesil synplarynda zerurlyk bolmasa-da, “printLogs” funksiýasyny ýerine ýetirmek talap ediler.
class CustomErrorFileLogger : FileLogger{

    override fun printLog() {

    }

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

}
indi bolsa boş funksiýalarymyz bolar, bu kod arassalygy üçin erbet. Munuň ýerine, interfeýsde deslapky bahany düzüp, funksiýany diňe zerur bolan synplarda ýok edip bileris:
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)
    }

}
Indi FileLogger interfeýsini durmuşa geçirjek sapaklar has arassa bolar. 5. D: baglylyk öwrülişigi ýörelgesi  . Garaşlylygyň obýekti anyk bir zat däl-de, abstraksiýa bolmaly. Esasy synpymyza gaýdyp geleliň:
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())
        }
    }

}
Bu ýerde eýýäm hemme zady düzüp, düzeden ýaly. Stillöne üýtgedilmeli ýene bir nokat bar. Bu “FirebaseAuth” synpyny ulanýar. Belli bir wagtda awtorizasiýany üýtgetmeli we Firebase arkaly däl-de, mysal üçin haýsydyr bir API haýyşyny ulanyp girmeli bolsa näme bolar? Soň köp zady üýtgetmeli bolarys we muny islemeýäris. Munuň üçin “InWithEmailAndPassword” (e-poçta: Setir, parol: Setir) funksiýasy bilen interfeýs dörediň:
interface Authenticator{
    fun signInWithEmailAndPassword(email: String, password: String)
}
Bu interfeýs abstraksiýamyzdyr. Indi bolsa girişiň anyk ýerine ýetirilişini edýäris
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" synpynda indi belli bir durmuşa geçirilişe baglylyk ýok, diňe abstraksiýa bagly
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())
        }
    }

}
Indi, awtorizasiýa usulyny üýtgetmek üçin modul synpynda diňe bir setiri üýtgetmeli.
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION