πŸ’¬ Π’ ΠΊΠ°ΠΊΠΈΡ… случаях слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйсы Π² Go?



πŸ€” Π­Ρ‚ΠΎ довольно ΠΎΠ±ΡˆΠΈΡ€Π½Π°Ρ ΠΈ слоТная Ρ‚Π΅ΠΌΠ°, Π½ΠΎ Ссли ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ ΠΊΡ€Π°Ρ‚ΠΊΠΎ, Ρ‚ΠΎ интСрфСйсы Π² Go слСдуСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… сцСнариях:



1️⃣ ΠžΠ±Ρ‰Π΅Π΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ β€” использованиС интСрфСйсов, ΠΊΠΎΠ³Π΄Π° нСсколько Ρ‚ΠΈΠΏΠΎΠ² Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ ΠΎΠ±Ρ‰Π΅Π΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅. Π’ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ это ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²Π½ΡƒΡ‚Ρ€ΡŒ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ интСрфСйса.



Π’ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ². НапримСр, сортировка ΠΊΠ°ΠΊΠΎΠΈΜ†-Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΎΠΆΠ΅Π½Π° Π½Π° Ρ‚Ρ€ΠΈ дСйствия:



✹ ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ количСствС элСмСнтов Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ.

✹ Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎ Ρ‚ΠΎΠΌ, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π»ΠΈ ΠΎΠ΄ΠΈΠ½ элСмСнт Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ ΠΏΠ΅Ρ€Π΅Π΄ Π΄Ρ€ΡƒΠ³ΠΈΠΌ.

✹ ΠŸΠ΅Ρ€Π΅ΡΡ‚Π°Π½ΠΎΠ²ΠΊΠ° Π΄Π²ΡƒΡ… элСмСнтов.



2️⃣ Π‘Π½ΠΈΠΆΠ΅Π½ΠΈΠ΅ связанности (decoupling) β€” ΠΎΡ‚Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° ΠΎΡ‚ Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. Если ΠΌΡ‹ полагаСмся Π½Π° Π°Π±ΡΡ‚Ρ€Π°ΠΊΡ†ΠΈΡŽ вмСсто ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΈΜ† Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, сама рСализация ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΌΠ΅Π½Π΅Π½Π° Π½Π° Π΄Ρ€ΡƒΠ³ΡƒΡŽ Π±Π΅Π· нСобходимости ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΊΠΎΠ΄. Π­Ρ‚ΠΎ ΠΈ Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ подстановки Лисков. Одно ΠΈΠ· прСимущСств сниТСния связанности ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚ΡŒΡΡ ΠΊ ΡŽΠ½ΠΈΡ‚-тСстам.



3️⃣ ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ повСдСния. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΈΜ† ΠΏΠ°ΠΊΠ΅Ρ‚ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с динамичСской ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠ΅ΠΈΜ†. ΠœΡ‹ создаСм ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΈΜ† ΠΊΠΎΠ½Ρ‚Π΅ΠΈΜ†Π½Π΅Ρ€ для ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈΜ† int с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ структуры IntConfig, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΈΜ† ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π΄Π²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°: Get ΠΈ Set. Π’ΠΎΡ‚ ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΈΜ† ΠΊΠΎΠ΄:



type IntConfig struct {

// ...

}

func (c *IntConfig) Get() int {

// ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ

}

func (c *IntConfig) Set(value int) {

// ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ

}





✹ Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ IntConfig, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΈΜ† содСрТит Π² сСбС ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ ΠΏΠΎΡ€ΠΎΠ³ΠΎΠ²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Но Π² нашСм ΠΊΠΎΠ΄Π΅ нас интСрСсуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ значСния этой ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, ΠΈ ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅. Как ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сСмантичСски эта конфигурация Π±Ρ‹Π»Π° доступна Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния, Ссли ΠΌΡ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ?



✹ CΠΎΠ·Π΄Π°Π² Π°Π±ΡΡ‚Ρ€Π°ΠΊΡ†ΠΈΡŽ, которая ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ значСния ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ:



type intConfigGetter interface {

Get() int

}





Π’ΠΎΠ³Π΄Π° Π² ΠΊΠΎΠ΄Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ intConfigGetter вмСсто ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΈΜ† Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:





type Foo struct {

threshold intConfigGetter

}



func NewFoo(threshold intConfigGetter) Foo {

return Foo{threshold: threshold}

}



func (f Foo) Bar() {

threshold := f.threshold.Get()

// ...

}





✹ Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π³Π΅Ρ‚Ρ‚Π΅Ρ€ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ внСдряСтся Π² Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΈΜ† ΠΌΠ΅Ρ‚ΠΎΠ΄ NewFoo. Он Π½Π΅ влияСт Π½Π° потрСбитСля этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ структуру IntConfig ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ intConfigGetter. Π—Π°Ρ‚Π΅ΠΌ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ Bar ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ, Π½ΠΎ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π΅. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйсы, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ±Π»ΡŽΡΡ‚ΠΈ сСмантику.