Есть структура с методом, который принимает на вход массив платежей и некий ключ, который определяет какой банк использовать.
var errIssueConvert = errors.New("cannot convert issue to needed type")
type ProviderType int
const (
BANK_A_PROVIDER issue.ProviderType = iota
BANK_B_PROVIDER
)
type issueUC struct {
cfg *config.Config
logger iLogger.ApiLogger
repository iIssue.BankARepository
}
func (u *issueUC) RunIssues(issues []any, p issue.ProviderType) error {
switch p {
case BANK_A_PROVIDER:
var bankAIssues []*models.BankAIssue
for _, iss := range issues {
toBankAIssue, ok := iss.(*models.BankAIssue)
if !ok {
return errIssueConvert
}
bankAIssues = append(bankAIssues, toBankAIssue)
}
provider := bankAUC.NewBankAProvider(u.cfg, u.logger, u.repository)
err := provider.Run(bankAIssues)
if err != nil {
return err
}
break
case BANK_A_PROVIDER:
// some logic
break
}
return nil
}
У разных банков, будут разные параметры метода Run, получается, я не могу описать структуры интерфейсом,
например:
type iProvider interface {
Run(// разные)
}
func (u *issueUC) RunIssues(issues []any, p issue.ProviderType) error {
var provider iProvider
switch p {
case BANK_A_PROVIDER:
provider = bankAUC.NewBankAProvider(u.cfg, u.logger, u.repository)
break
case BANK_A_PROVIDER:
// some logic
break
}
provider.Run(issues)
return nil
}
Первый вариант метода RunIssues мне не нравится по причинам:
- метод большой, при добавлении провайдеров будет разростаться
- выполняет много операций
- нарушает принцип открытости/закрытости, будет постоянно расширяться при добавлении новых банков и тд
Как решения, думал может правильнее было бы сделать абстр фабрику и никому ее не показывать.
Как было бы более правильно сделать, подскажите пожалуйста.