За выходные строю небольшую Zeit Integration. Я называю это TrelloZeitIntegration, потому что я использую Trello API в своей интеграции.

Но в любом случае. Это был первый раз, когда я программировал на Go в «реальном» проекте. Начав работу над проектом, я буквально взломал все, что находится внутри index.go файла. Файл очень быстро превратился в +300 строк кода и выглядел немного неаккуратно. Конечно, было. Этот единственный файл мог:

  • Обработка API Zeit
  • Создать представления
  • Обработка API Trello

Это, по крайней мере, для меня с фоном ООП, многовато для одного файла. Но поскольку я еще не очень хорошо разбираюсь в Go, а Go не является настоящим языком ООП, я решил спросить коллегу о возможных улучшениях моего кода.

Новый пакет

Первым его предложением было переместить материал Trello в отдельный пакет с именем trello. Я спросил, следует ли мне просто создать новый каталог с именем trello с файлом api.go в нем. Он ответил ссылкой на какой-то де-факто стандарт для макетов проектов Go.



Итак, я извлек все свои вспомогательные функции в api/trello/api.go. Поскольку этот файл выглядит немного «загроможденным» моделью structs, я также создал api/trello/models.go, куда я просто вставил свой structs.

Тогда мой api.go выглядел так:

func CreateBoard(apiKey string, ...) (Board) {}
func MoveCardToList(apiKey string, ...) (Card) {}
func AddCard(apiKey string, ...) {}

Пакет trello был в основном просто «служебным» файлом, который извлекал некоторые части кода. Но это не выглядело (и не ощущалось) как «настоящая» упаковка.

Коллега с этим согласился и предложил создать своего рода trello client. Это означает, что в моем пакете есть struct, который содержит apiKey, а затем я должен создать так называемую функцию-приемник для выполнения вызовов API. Это заканчивается примерно так:

type trelloClient struct {
  apiKey string
}
func NewClient(apiKey string) trelloClient {
  return trelloClient {
    apiKey: apiKey,
}
func (client trelloClient) CreateBoard(...) (Board) {}
func (client trelloClient) MoveCardToList(...) (Card) {}
func (client trelloClient) CreateCard(...) {}

Теперь я экспортирую только одну функцию в другие пакеты. Все остальные функции могут быть вызваны только для возвращенного trelloClient.

Извлечение просмотров

Еще меня очень обеспокоило то, что файл index.go содержал бизнес-логику и логику представления. Конечно, я пытался извлечь создание представления в функции, но в конце файл содержал много строк HTML.

Решением было использование пакета html/template. С помощью этого пакета я смог извлечь свои представления (HTML-код) в их собственные *.html файлы, в то время как пакет позаботился о замене заполнителей моей моделью struct.

Затем я получил web/template/templateutil/util.go, который в основном взял информацию с бизнес-уровня, обернул ее в structs и, наконец, загрузил с ней HTML-макет:

type trelloBoards struct { 
  ..., 
  ...,
  ...
}
func GenerateForTrelloBoards(...) {
  boards := trelloBoards { /** Create struct from params */ }
  tmpl, _ := template.ParseFiles("trelloBoards.hml")
  ...
}

Источники обучения

Мой коллега 😅. Но также это и это для html/templates. Информацию о приемниках можно найти здесь и здесь.