Heim > Backend-Entwicklung > Golang > Verstehen Sie die Go-Flat-Projektstruktur

Verstehen Sie die Go-Flat-Projektstruktur

coldplay.xixi
Freigeben: 2020-08-13 16:56:08
nach vorne
3587 Leute haben es durchsucht
myapp/
  main.go
  server.go
  user.go
  lesson.go
  course.go
Nach dem Login kopieren

Beim Einstieg in Verstehen Sie die Go-Flat-Projektstruktur beginnt fast jeder mit einer flachen Bewerbungsstruktur. Jedes Programm der Verstehen Sie die Go-Flat-Projektstruktur-Tour, die meisten Übungen in Verstehen Sie die Go-Flat-Projektstrukturphercises und viele andere frühe Verstehen Sie die Go-Flat-Projektstruktur-Programme sind nicht in Pakete unterteilt. Stattdessen erstellen wir einfach ein paar .go-Dateien und packen den gesamten Code in dasselbe (normalerweise main) Paket. Verstehen Sie die Go-Flat-Projektstruktur

Das hört sich zunächst schrecklich an. Wird der Code schnell unhandlich? Wie kann man Geschäftslogik vom UI-Rendering-Code trennen? Wie finde ich die richtige Quelldatei? Schließlich verwenden wir Pakete vor allem deshalb, um Anliegen zu trennen und gleichzeitig die schnelle Navigation zu den richtigen Quelldateien zu erleichtern.

Verstehen Sie die Go-Flat-ProjektstrukturVerwandte Lernempfehlungen: Verstehen Sie die Go-Flat-Projektstruktur-Sprachtutorial

Nutzen Sie flache Strukturen effektiv

Bei der Verwendung flacher Strukturen sollten Sie dennoch versuchen, sich an die Best Practices für die Codierung zu halten. Sie müssen verschiedene .go-Dateien verwenden, um verschiedene Teile Ihrer Anwendung zu trennen: .go文件放置在一个软件包中。

myapp /
  main.go#阅读配置并在此处启动您的应用
  server.go#总体HTTP处理逻辑在这里
  user_handler.go#用户http处理程序逻辑在这里
  user_store.go#用户数据库逻辑在这里
  # 等等...
Nach dem Login kopieren

进入Verstehen Sie die Go-Flat-Projektstruktur时,几乎每个人都从一个平面应用程序结构开始。 Verstehen Sie die Go-Flat-Projektstruktur tour中的每个程序,Verstehen Sie die Go-Flat-Projektstrukturphercises中的大多数练习以及许多其他早期的Verstehen Sie die Go-Flat-Projektstruktur程序都没有被分解成任何包装。取而代之的是,我们只创建几个.go文件,然后将所有代码放入相同的(通常是main)包中。

起初,这听起来很糟糕。代码会很快变得笨拙吗?如何将业务逻辑与UI渲染代码分开?我如何找到正确的源文件?毕竟,我们使用软件包的很大一部分原因是要分离关注点,同时使更容易快速地导航到正确的源文件。

相关学习推荐:Verstehen Sie die Go-Flat-Projektstruktur语言教程

有效使用平面结构

使用平面结构时,您仍应尝试遵守编码最佳实践。您将需要使用不同的.go文件分隔应用程序的不同部分:

type Server struct {
  apiClient *someapi.Client
  router *some.Router
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  s.router.ServeHTTP(w, r)
}
Nach dem Login kopieren

全局变量仍然可能成为问题,因此您应考虑将类型与方法配合使用,以使它们脱离代码:

//警告:此示例非常人为设计,甚至可能无法编译。

type Config struct {
  SomeAPIKey     string
  Port           string
  EnableTheThing bool
}

func main() {
  var config Config
  config.SomeAPIKey = os.Getenv("SOMEAPI_KEY")
  config.Port = os.Getenv("MYAPP_PORT")
  if config.Port == "" {
    config.Port = "3000"
  }
  config.EnableTheThing = true

  if err := run(config); err != nil {
    log.Fatal(err)
  }
}

func run(config Config) error {
  server := myapp.Server{
    APIClient: someapi.NewClient(config.SomeAPIKey),
  }
  return http.ListenAndServe(":" + config.Port, server)
}
Nach dem Login kopieren

而且您的main()函数可能仍应在设置应用程序之外删除大多数逻辑:

myapp/
  cmd/
    web/
      # package main
      main.go
    cli/
      # package main
      main.go
  # package myapp
  server.go
  user_handler.go
  user_store.go
  ...
Nach dem Login kopieren

实际上,您实际上可以将基本上是平面结构的代码全部使用在一个软件包中,并在单独的main软件包中定义命令。这将允许您使用常见的cmd子目录模式:

输入JsonCourse struct {
  ID字符串`json:“ id”`
  价格结构{
    USD字符串`json:“ usd”`
  }`json:“价格”`
}
Nach dem Login kopieren
Nach dem Login kopieren

在此示例中,您的应用程序基本上仍然是平坦的,但是您拔出了main软件包是因为您有需要-例如可能需要使用同一核心应用程序来支持两个命令。

为什么要使用扁平结构?

扁平结构的主要好处不是将所有代码都保存在一个目录中,也不是那样愚蠢的东西。这种结构的核心好处是您可以不必担心如何组织事物,而可以继续解决您打算通过应用程序解决的问题。

我绝对喜欢这个应用程序结构让我回想起PHP的日子。当我第一次学习编码时,我开始使用随机PHP文件,其逻辑与各种HTML混合在一起,这真是一团糟。我并不是在建议我们以大型应用程序的方式构建-那样会很糟糕-但是我并不担心一切都应该放在哪里,而是更加关注学习如何编写代码和解决我的特定问题。无论您是要了解应用程序的需求,您的域还是一般的编码方式,使用扁平结构都可以使您更轻松地专注于学习和构建。

这是正确的,因为我们可以不再担心诸如“这种逻辑应该去哪里?”之类的问题。因为如果我们犯了一个错误,很容易解决。如果它是一个函数,我们可以将其移动到包中的任何新源文件中。如果它是错误类型的方法,我们可以创建两个新类型并将逻辑与原始类型分开。有了这些,我们就不必担心会遇到奇怪的周期性依赖问题,因为我们只有一个软件包。

考虑平面结构的另一个重要原因是,随着应用程序复杂性的提高,结构的发展变得容易得多。当您明显可以从将代码拆分到一个单独的程序包中受益时,您通常需要做的就是将一些源文件移到一个子目录中,更改其程序包,并更新任何引用以使用新的程序包前缀。例如,如果我们有SqlUser并决定从一个单独的sql包中处理所有与数据库相关的逻辑中受益,我们将更新所有引用以现在使用sql.User将类型移动到新软件包后。我发现,像MVC这样的结构在重构方面更具挑战性,尽管并非没有其他编程语言那样困难或困难。

扁平结构对于通常太快无法创建包的初学者特别有用。我真的不能说为什么会发生这种现象,但是Verstehen Sie die Go-Flat-Projektstruktur的新手喜欢创建大量的软件包,这几乎总是导致口吃(user.User

type SqlCourse struct {
  ID    int
  Price int
}
Nach dem Login kopieren
Nach dem Login kopieren

Globale Variablen können immer noch ein Problem darstellen, daher sollten Sie die Verwendung von Typen mit Methoden in Betracht ziehen, um sie aus Ihrem Code fernzuhalten :

func (sc SqlCourse) ToJson() (JsonCourse, error) {
  jsonCourse := JsonCourse{
    ID: fmt.Sprintf("crs_%v", sc.ID),
  }
  jsonCourse.Price.USD = Price: fmt.Sprintf("%d.%2d", sc.Price/100, sc.Price%100)
  return jsonCourse, nil
}
Nach dem Login kopieren
Nach dem Login kopieren
Und Ihre main()-Funktion sollte wahrscheinlich immer noch den größten Teil Ihrer Logik außerhalb der Einrichtung Ihrer Anwendung entfernen:
func (jc JsonCourse) ToSql() (SqlCourse, error) {
  var sqlCourse SqlCourse
  // JSON ID is "crs_123" and we convert to "123"
  // for SQL IDs
  id, err := strconv.Atoi(strings.TrimPrefix(jc.ID, "crs_"))
  if err != nil {
    // Note: %w is a Verstehen Sie die Go-Flat-Projektstruktur 1.13 thing that I haven't really
    // tested out, so let me know if I'm using it wrong
Nach dem Login kopieren
Nach dem Login kopieren

Tatsächlich könnten Sie den gesamten Code im Wesentlichen als flache Struktur nutzen es in einem Paket und definieren Sie Befehle in einem separaten main-Paket. Dadurch können Sie das allgemeine Unterverzeichnismuster cmd verwenden: 🎜rrreee🎜 In diesem Beispiel ist Ihre Anwendung im Grunde immer noch flach, aber Sie haben das main</code-Paket herausgezogen Sie haben einen Bedarf – beispielsweise müssen Sie möglicherweise zwei Befehle mit derselben Kernanwendung unterstützen. 🎜<h2>Warum eine flache Struktur verwenden? </h2>🎜Der Hauptvorteil einer flachen Struktur besteht darin, dass Sie nicht Ihren gesamten Code in einem Verzeichnis aufbewahren oder so etwas Dummes tun. Der Hauptvorteil dieser Struktur besteht darin, dass Sie sich keine Gedanken mehr darüber machen müssen, wie Sie die Dinge organisieren, sondern mit der Lösung des Problems fortfahren können, das Sie mit Ihrer Anwendung lösen möchten. 🎜🎜Ich finde es absolut toll, wie mich diese Anwendungsstruktur an meine PHP-Tage erinnert. Als ich zum ersten Mal das Programmieren lernte, begann ich, zufällige PHP-Dateien mit ihrer Logik und allen Arten von HTML zu verwenden, und das war ein echtes Durcheinander. Ich schlage nicht vor, dass wir es wie eine große Anwendung erstellen – das wäre schrecklich –, aber ich mache mir weniger Sorgen darüber, wo alles sein sollte, sondern konzentriere mich mehr darauf, zu lernen, wie man programmiert und mein spezifisches Problem löst. Unabhängig davon, ob Sie die Anforderungen Ihrer Anwendung, Ihrer Domäne oder des Programmierens im Allgemeinen verstehen möchten, können Sie sich mithilfe einer flachen Struktur leichter auf das Lernen und Erstellen konzentrieren. 🎜🎜Das ist richtig, denn wir können aufhören, uns über Fragen wie „Wohin soll diese Logik führen?“ Gedanken zu machen. Denn wenn wir einen Fehler machen, ist er leicht zu beheben. Wenn es sich um eine Funktion handelt, können wir sie in eine beliebige neue Quelldatei im Paket verschieben. Wenn es sich um den falschen Methodentyp handelt, können wir zwei neue Typen erstellen und die Logik vom ursprünglichen Typ trennen. Damit müssen wir uns keine Sorgen über seltsame zyklische Abhängigkeitsprobleme machen, da wir nur ein Paket haben. 🎜🎜Ein weiterer guter Grund, flache Strukturen in Betracht zu ziehen, besteht darin, dass es mit zunehmender Komplexität Ihrer Anwendung viel einfacher wird, die Struktur weiterzuentwickeln. Wenn es offensichtlich ist, dass Sie von der Aufteilung Ihres Codes in ein separates Paket profitieren könnten, müssen Sie normalerweise nur einige Quelldateien in ein Unterverzeichnis verschieben, das Paket ändern und alle Verweise aktualisieren, um das neue Programmpaketpräfix zu verwenden. Wenn wir beispielsweise <code>SqlUser hätten und beschließen würden, die gesamte datenbankbezogene Logik in einem separaten sql-Paket zu verwalten, würden wir alle Referenzen aktualisieren, um jetzt sql zu verwenden .Benutzertyp in neues Paket verschoben nach. Ich finde, dass Strukturen wie MVC schwieriger zu refaktorisieren sind, wenn auch nicht so schwierig oder schwierig wie andere Programmiersprachen. 🎜🎜Die flache Struktur ist besonders nützlich für Anfänger, die beim Erstellen von Paketen oft zu schnell sind. Ich kann nicht wirklich sagen, warum das passiert, aber Verstehen Sie die Go-Flat-Projektstruktur-Neulinge erstellen gerne Unmengen von Paketen, was fast immer zu Stottern (user.User), zyklischen Abhängigkeiten oder anderen Problemen führt. 🎜🎜🎜 Im nächsten Artikel über MVC werden wir untersuchen, wie dieses Phänomen der Erstellung zu vieler Pakete dazu führen kann, dass MVC in Verstehen Sie die Go-Flat-Projektstruktur unmöglich erscheint, obwohl dies nicht der Fall ist. 🎜🎜

通过推迟创建新程序包的决定,直到我们的应用程序增长一点并更好地了解它,发芽的Verstehen Sie die Go-Flat-Projektstrukturphers犯此错误的可能性就大大降低了。

这也是为什么很多人会鼓励开发人员避免过早将其代码分解到微服务中的原因-您通常没有足够的知识来真正知道应该和不应该将哪些内容分解为微服务以及抢先式微服务( I kinda希望能成为一句俗语)只会在将来带来更多工作。

平坦的结构并不全是阳光和彩虹

假装使用扁平结构没有任何不利之处,这对我来说是不诚实的,所以我们也应该讨论这些。

对于初学者来说,扁平的结构只能使您受益匪浅。它会工作一段时间(可能比您想象的更长),但是到某个时候,您的应用程序将变得足够复杂,您需要开始分解它。使用平面结构的好处是您可以推迟使用它,并且在分解时可能会更好地理解您的代码。缺点是,您将需要花一些时间进行重构,并且您可能(也许-但这很麻烦)发现自己已经重构为您想从任何地方开始的结构。

使用平面结构时,命名冲突有时也会很尴尬。例如,假设您想要在应用程序中使用Course类型,但是在数据库中表示课程的方式与在JSON中呈现课程的方式不同。一个快速的解决方案是创建两种类型,但是由于它们都在同一个包中,因此每种类型都需要使用不同的名称,并且可能最终以类似以下内容的形式出现:SqlCourseJsonCourse。这确实没什么大不了的,但是有点令人遗憾的是我们最终得到了零类型,简单地称为Course

将代码重构为新程序包也不总是那么简单。是的,这通常很容易,但是由于所有代码都在一个包中,因此您有时可能会遇到天生具有周期性的代码。例如,假设我们的课程是否具有在JSON响应中始终以crs_开头的ID,并且我们想以各种货币返回价格。我们可以创建一个JsonCourse来处理:

输入JsonCourse struct {
  ID字符串`json:“ id”`
  价格结构{
    USD字符串`json:“ usd”`
  }`json:“价格”`
}
Nach dem Login kopieren
Nach dem Login kopieren

同时,SqlCourse仅需要存储一个整数ID和一个以美分为单位的单一价格,我们可以使用各种货币对其进行格式化。

type SqlCourse struct {
  ID    int
  Price int
}
Nach dem Login kopieren
Nach dem Login kopieren

现在我们需要一种将SqlCourse转换为JsonCourse的方法,因此我们可以将其作为SqlCourse类型的方法:

func (sc SqlCourse) ToJson() (JsonCourse, error) {
  jsonCourse := JsonCourse{
    ID: fmt.Sprintf("crs_%v", sc.ID),
  }
  jsonCourse.Price.USD = Price: fmt.Sprintf("%d.%2d", sc.Price/100, sc.Price%100)
  return jsonCourse, nil
}
Nach dem Login kopieren
Nach dem Login kopieren

然后稍后我们可能需要一种方法来解析传入的JSON并将其转换为SQL等效项,因此我们将其添加到JsonCourse类型中作为另一种方法:

func (jc JsonCourse) ToSql() (SqlCourse, error) {
  var sqlCourse SqlCourse
  // JSON ID is "crs_123" and we convert to "123"
  // for SQL IDs
  id, err := strconv.Atoi(strings.TrimPrefix(jc.ID, "crs_"))
  if err != nil {
    // Note: %w is a Verstehen Sie die Go-Flat-Projektstruktur 1.13 thing that I haven&#39;t really
    // tested out, so let me know if I&#39;m using it wrong
Nach dem Login kopieren
Nach dem Login kopieren

相关学习推荐:编程视频

Das obige ist der detaillierte Inhalt vonVerstehen Sie die Go-Flat-Projektstruktur. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:learnku.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage