--SRP (principe de responsabilité unique) --OCP (principe ouvert / fermé) --LSP (principe de remplacement de Riskov) --ISP (Principe de séparation d'interface) --DIP (principe d'inversion de dépendance)
C'est un acronyme pour.
La raison d'appliquer SOLID est
――Résistant au changement --Facile à comprendre
Peut être mentionné. Dans ce qui suit, je vais aborder l'explication de chaque principe et le code.
Le principe selon lequel il ne devrait pas y avoir de raisons multiples lors du changement d'un module, d'une classe, d'une fonction, etc. La raison est d'éviter que les événements suivants ne se produisent
Une interface a plusieurs responsabilités pour gérer les employés, stocker les données des employés.
type EmployeeWorkManage interface {
calculatePay()
reportHours()
saveEmployee()
}
Créez des interfaces distinctes pour gérer les employés et stocker les données des employés afin que chacun ait une responsabilité.
type EmployeeWorkManage interface {
calculatePay()
reportHours()
}
type EmployeeDataManage interface {
saveEmployee()
}
Le principe selon lequel il doit être ouvert aux extensions logicielles et fermé aux modifications De cette façon, vous pouvez faire évoluer votre système sans être affecté par les changements.
En créant une interface appelée Animal et en créant un type de chien ou une méthode de type de chat en fonction de celui-ci, la méthode d'aboiement peut être exécutée sans se soucier du type de chien ou de type de chat dans le processus principal. De plus, si vous souhaitez créer un nouvel oiseau, il vous suffit de l'ajouter en le rendant dépendant de l'interface Animal.
package main
import(
"fmt"
)
type Animal interface {
bark()
eat()
}
type Dog struct {}
type Cat struct {}
func (d Dog) bark(){
fmt.Println("Bow Wow")
}
func (d Dog) eat(){
fmt.Println("Bakubaku")
}
func (c Cat) bark(){
fmt.Println("Miaou")
}
func (c Cat) eat(){
fmt.Println("Mushamsha")
}
func main(){
dog := Dog{}
cat := Cat{}
animals := []Animal{dog, cat}
for _, animal := range animals {
animal.bark()
}
}
Objet de type S: o1 Objet de type T: o2 Le principe selon lequel S est une dérivée de T si, à un moment donné, le comportement de P ne change pas lorsqu'on utilise o1 au lieu de o2 pour le programme P défini à l'aide de T.
Puisque Go n'a pas d'héritage, il ne viole pas le principe de remplacement de Riskoff et n'est pas conscient (?)
Le principe de ne pas vous obliger à vous fier à des interfaces inutiles Regroupez uniquement les interfaces pertinentes et perdez la dépendance des méthodes inutilisées.
Si vous essayez de créer un humanoïde à partir de l'interface animale ci-dessous, vous devrez décrire la méthode de vol que vous n'utilisez pas.
type AnimalInterface interface {
fly()
run()
swim()
}
Séparez l'interface de l'interface oiseau pour les oiseaux et de l'interface humaine pour les humains. Ce faisant, vous n'avez pas à écrire de méthodes inutiles.
type BirdInterface interface {
fly()
}
type HumanInterface interface {
run()
swim()
}
type Bird struct {}
type Human struct{}
func (b Bird) fly(){
fmt.Println("Voler! !!")
}
func (h Human) run(){
fmt.Println("Je vais courir ~")
}
func (h Human) swim(){
fmt.Println("Natation ~")
}
func main(){
bird := Bird{}
human := Human{}
bird.fly()
human.run()
}
Le principe de ne pas s'appuyer sur des modules concrets fréquemment modifiés (modules dans lesquels les implémentations de fonctions sont écrites) Évitez de vous fier au caractère concret modifiable et comptez sur une interface abstraite stable. Utilisez le modèle Abstract Factory pour faire référence à l'interface abstraite.
En s'appuyant sur Abstract Factory, la dépendance sera comme indiqué sur la figure, et les données de l'utilisateur peuvent être acquises sans se soucier ni de la base de données ni du texte.
package main
import(
"fmt"
)
type User struct {
id int
name string
}
type AbstractFactory interface {
getData() User
}
type DbManage struct {}
func (db DbManage) getData() User {
return User{1, "DB TARO"}
}
type TextManage struct {}
func (text TextManage) getData() User {
return User{2, "TEXT JIRO"}
}
func getUserData(manageType string) User {
var manageFactry AbstractFactory
switch manageType {
case "DB":
manageFactry = DbManage{}
return manageFactry.getData()
case "TEXT":
manageFactry = TextManage{}
return manageFactry.getData()
default:
return User{3, "Anonyme"}
}
}
func main(){
user := getUserData("DB")
fmt.Println(user.id, user.name)
}
https://labs.septeni.co.jp/entry/2017/02/21/164127 https://maroyaka.hateblo.jp/entry/2017/05/22/165355 https://qiita.com/shunp/items/646c86bb3cc149f7cff9 https://golangvedu.wordpress.com/2017/01/31/golang-design-pattern-abstract-factory-and-factory-method/
D'une manière ou d'une autre, j'ai l'impression de comprendre le principe SOLID. Si vous avez des questions ou des suggestions, nous vous serions reconnaissants de bien vouloir les écrire dans les commentaires.