🤖
インターフェース分離の原則
インターフェース分離の原則について
SOLIDの5原則の1つであるインターフェース分離の原則について、調べた/実装した内容を記載します。
1. インターフェース分離の原則とは
SOLIDの5原則の1つとなります。
※SOLIDの原則については以下となります。
S:単一責任の原則(Single Responsibility)
O:オープン・クローズドの原則(Open-Closed)
L:リスコフの置換原則(Liskov Substitution)
I:インターフェイス分離の原則(Interface Segregation)←ここ
D:依存性逆転の原則(Dependency Inversion)
2. インターフェース分離とは
インターフェースは呼び出された先の関数で、利用しない関数が無いように設計するということです。
もし利用しているインターフェースに、その関数では利用しない関数が設定されていたら、バグを作りこむ可能性が出てきます。
3. インターフェースを分離する意味
インターフェースを分離するためのメリットは以下となります。
1) 柔軟性の向上
利用したい関数のみ実装出来るようになり、余計な関数が入り込みません。
また、拡張したい時は、対象のインターフェースに定義するだけで、利用可能になります。
そのため、利用可能な関数を制御、拡張することが可能になるため、柔軟性が向上します。
2) 保守性の向上
インターフェースがシンプルになり、余計な関数が定義されていません。
そのため、各インターフェースの責任が明確になり、将来的な拡張や変更が容易にとなります。
3) 再利用性の向上
各関数は、必要な機能のみ実装すればよく、他の機能に影響されることがないため、他の機能でも再利用することが可能となります。
4. 実装
実際にインターフェース分離の原則を元に実装した内容は以下の通りとなります。
package main
import (
controller "InterfaceSegregation/controller/usermst"
"InterfaceSegregation/infrastructure/repositories"
usecase "InterfaceSegregation/usecase/usermst"
"fmt"
)
func main() {
// DI(Repositoryコンストラクタの生成)
repo := repositories.NewSearchUsermstRepository()
// DI(Usecaseコンストラクタの生成⇨Repositoryを引数に渡す)
usermstusecase := usecase.NewSearchUsermstUsecase(repo)
// DI(Controllerコンストラクタの生成⇨Usecaseを引数に渡す)
c := controller.NewUsermstController(usermstusecase)
fmt.Println(c.SarchAllUsermst())
fmt.Println(c.SearchByUsercd())
}
package usermst
import "InterfaceSegregation/usecase/usermst"
type SearchUsermstController struct {
SearchUsermst usermst.ISearchUsermstInteractor
}
// SearchUsermstControllerのコンストラクタ
func NewUsermstController(s usermst.ISearchUsermstInteractor) SearchUsermstController {
return SearchUsermstController{
SearchUsermst: s,
}
}
// usermstの全件検索処理
func (s *SearchUsermstController) SarchAllUsermst() string {
return s.SearchUsermst.SarchAllUsermst()
}
// usermstのユーザーコード検索処理
func (s *SearchUsermstController) SearchByUsercd() string {
return s.SearchUsermst.SearchUsercd("usercd")
}
package usermst
import "InterfaceSegregation/domain/repositories"
type ISearchUsermstInteractor interface {
SarchAllUsermst() string
SearchUsercd(usercd string) string
}
type SearchUsermstInteractor struct {
repositories.ISearchUsermstRepository
}
// SearchUsermstInteractorのコンストラクタ
func NewSearchUsermstUsecase(searchusermst repositories.ISearchUsermstRepository) ISearchUsermstInteractor {
return &SearchUsermstInteractor{
searchusermst,
}
}
// usermstの全件検索処理(ビジネスロジック)
func (s *SearchUsermstInteractor) SarchAllUsermst() string {
return s.AllSearchUsermst()
}
// usermstのユーザーコード検索処理(ビジネスロジック)
func (s *SearchUsermstInteractor) SearchUsercd(usercd string) string {
return s.SearchByUsercd(usercd)
}
package repositories
// 検索用のインターフェース
// 検索処理を行う場合にのみ必要な関数を定義する。
// 検索処理を行うためだけのインターフェースのため、登録、更新、削除処理は含まない。
type ISearchUsermstRepository interface {
AllSearchUsermst() string
CountByUsercd(usercd string) int
SearchByUsercd(usercd string) string
}
// Insert用のインターフェース
// Insert処理を行う場合にのみ必要な関数を定義する。
// Insertを行う前に、対象データが存在するかどうか確認するためにCountByUsercd関数を定義する。
type IInsertUsermstRepository interface {
CountByUsercd(usercd string) int
InsertUsermst() bool
}
// Update用のインターフェース
// Update処理を行う場合にのみ必要な関数を定義する。
// Updateを行う前に、対象データが存在するかどうか確認するためにCountByUsercd関数を定義する。
// Update処理を実行する前に、対象データが他のユーザに更新されていないかなどを確認するために、SearchByUsercd関数を定義する。
type IUpdateUsermstRepository interface {
CountByUsercd(usercd string) int
SearchByUsercd() string
UpdateUsermst() bool
}
// Delete用のインターフェース
// Delete処理を行う場合にのみ必要な関数を定義する。
// Deleteを行う前に、対象データが存在するかどうか確認するためにCountByUsercd関数を定義する。
// Delete処理を実行する前に、対象データが他のユーザに更新されていないかなどを確認するために、SearchByUsercd関数を定義する。
type IDeleteUsermstRepository interface {
CountByUsercd(usercd string) int
SearchByUsercd() string
DeleteUsermst() bool
}
package repositories
import "InterfaceSegregation/domain/repositories"
type UsermstRepository struct{}
// SearchUsermstRepositoryのコンストラクタ
func NewSearchUsermstRepository() repositories.ISearchUsermstRepository {
return &UsermstRepository{}
}
// usermstの全件検索処理
func (searchall *UsermstRepository) AllSearchUsermst() string {
return "AllSearchUsermst"
}
// usermstのユーザーコード検索処理
func (searchbyusercd *UsermstRepository) SearchByUsercd(userced string) string {
return userced
}
// usermstのユーザーコード件数取得処理
func (countbyusercd *UsermstRepository) CountByUsercd(usercd string) int {
return 1
}
// usermstのユーザーコード登録処理
func (insertusermst *UsermstRepository) InsertUsermst() bool {
return true
}
// usermstのユーザーコード更新処理
func (updateusermst *UsermstRepository) UpdateUsermst() bool {
return true
}
// usermstのユーザーコード削除処理
func (deleteusermst *UsermstRepository) DeleteUsermst() bool {
return true
}
実行結果
$ go run main.go
$ AllSearchUsermst
$ usercd
以上が、SOLID原則のインターフェース分離の原則についての説明となります。
5. Github
本説明で利用したコードを以下のGithubにあげておきます。
6. 参考にしたサイト
Discussion