Проблема, с которой я столкнулся при разработке Window, независимого от платформы для графического программного обеспечения.Мне требуется, чтобы каждое окно реализовывало функцию Launch () и имело размер.
Мое текущее решение - это структура с именем BaseWindow, в которую встроен Size и интерфейс Window с Launch () и GetSize ().Например, OpenGLWindow будет встраивать BaseWindow и реализовывать Launch () с помощью вызовов openGL.Я чувствую, что это не правильно из-за нескольких запахов кода.А) Мне не нравится, когда меня называют GetSize ().Но если я назову его Size (), он конфликтует с полем Size встроенной структуры размера в BaseWindow.Б) Интерфейсы должны быть независимыми от реализации, но эти геттеры довольно близки к принудительной реализации.
В конце я хотел бы иметь окно одного типа для передачи и использования, не беспокоясь о реализации какой платформывкл.
// What I have
type Size struct {
Width int
Height int
}
// What I would like to be my type that I use to access these functions/members
type Window interface {
GetSize() Size
Launch() error
}
// This would have more things in the final application, but for simplicity
// I only included Size
type BaseWindow struct {
Size
}
// Example of what I want my end result to look like
type OpenGLWindow {
BaseWindow
}
func (window OpenGLWindow) Launch() {
// Do stuff
}
// Notice Window returns size of BaseWindow and uses Launch of OpenGLWindow
func SetGlobalWin(window Window) {
GlobalWin = window
CirclePositionX = window.GetSize().Width / 2
window.Launch()
}
// If using openGL, open openGL window and use that as primary window
func UseMyWindow() {
glwin := NewOpenGLWindow()
SetGlobalWin(glwin)
}
Хотя этот подход работает, он не выглядит хорошим решением по причинам, изложенным выше.У меня такое чувство, что я слишком стараюсь, чтобы Launch () действовал как виртуальная функция из oop, и мне не хватает некоторых фундаментальных шаблонов проектирования для более композиционного подхода Go.