Is there a resource that can help me learn how to design applications in Go? I understand the syntax, but would like to know good design practices.

blov · · 523 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Coming from a mainly Java/object oriented background, I&#39;d like to know good design for Go. Can someone give me a guide or show me where to find one?</p> <p>Some things that confuse me:</p> <ul> <li>Do different files in the same package have any boundaries on what they can see in other files? Is splitting files up just for readability? Or would it be equal to having one massive file.</li> <li>Should I stop thinking &#34;Object orientedly&#34;?</li> <li>When should I split things up into different packages?</li> <li>Is there any form of inheritance?</li> </ul> <hr/>**评论:**<br/><br/>PippiPong: <pre><p>The go standard libraries is gem after gem of idiomatic mostly well designed code. One of my favorite things about go, the std is very approachable and readable.</p></pre>FootbaII: <pre><p>This sounds good. Which 3/4 stating points from the std libraries would you recommend?</p></pre>heptara: <pre><p>It would be nice to see the architecture for a large concurrent application (e.g. a game server). What in the standard library would be close?</p></pre>the_jester: <pre><p>The resource you are looking for is GitHub; you can readily find large, popular, well maintained projects there and see exactly how they are made. To get you started, <a href="https://github.com/docker/docker">Docker</a> is considered a great example of high-quality go code.</p> <p>To answer your questions more specifically:</p> <ul> <li>Visibility is logical, not file-based. If you have x.go and y.go both in package &#39;foo&#39;, they can reference each other. See <a href="https://golang.org/doc/code.html">this</a> for good practices.</li> <li>Absolutely not. Go is very object-oriented. It is however <em>composition</em> oriented, not <em>inheritance</em> oriented. This is a big deal. Find and read about composing in Go until the distinction makes sense to you.</li> <li>Whenever you find the package is doing more than &#34;one thing&#34;, or similarly when you find it hard to name the package a single word that makes sense.</li> <li>Go uses <a href="https://github.com/luciotato/golang-notes/blob/master/OOP.md">composition and interfaces</a> instead of inheritance.</li> </ul> <p>For example, if you have a &#34;Person&#34; type with some methods, rather than having &#34;Attendee&#34; and &#34;Guest&#34; types that inherit from Person, you would have &#34;Attendee&#34; and &#34;Guest&#34; both <em>embed</em> Person, and thus gain access to all Person&#39;s methods.</p></pre>big_dick_bridges: <pre><p>Awesome will look at those. Thanks for the helpful response!</p></pre>upboatact: <pre><p>and use <a href="https://github.com/alecthomas/gometalinter" rel="nofollow">https://github.com/alecthomas/gometalinter</a></p></pre>anxiousalpaca: <pre><p>TIL Docker was written in Go</p></pre>honestlytrying: <pre><p>Yeah, I&#39;m just now getting started with Docker and Go and I was a bit surprised to read that myself. Pretty cool though.</p></pre>bkeroack: <pre><blockquote> <p>For example, if you have a &#34;Person&#34; type with some methods, rather than having &#34;Attendee&#34; and &#34;Guest&#34; types that inherit from Person, you would have &#34;Attendee&#34; and &#34;Guest&#34; both embed Person, and thus gain access to all Person&#39;s methods.</p> </blockquote> <p>Maybe, but I&#39;d use caution with examples like this since it could be interpreted as endorsing Java-style idioms shoe-horned into Go.</p> <p>My approach would be to start with a &#34;Person&#34; interface (implements Eat(), Sleep(), Speak()) which Attendee and Guest satisfy. Then if methods have sufficient code in common, abstract them out to independent types (&#34;Eater&#34;, &#34;Sleeper&#34;) which can be embedded into &#34;Attendee&#34; and &#34;Guest&#34;.</p> <p>In other words, the embedding is <em>behavioral</em> rather than by <em>identity</em> as in Java-style inheritance.</p></pre>the_jester: <pre><p>Good point - upvoted. However, let the Java escapees walk before telling them to run. . .</p></pre>danhardman: <pre><p>Adding onto this if you want to look at patterns for web development, take a look at <a href="https://github.com/ilgooz/stack" rel="nofollow">https://github.com/ilgooz/stack</a> which is great for starting off building a RESTful API in Go</p></pre>earthboundkid: <pre><p>Minor note: if you have files a.go and b.go in package C, they can see each other&#39;s internals (lowercase named variables and struct members) but <em>not</em> each other&#39;s imports. Imports are local to a file. </p></pre>drvd: <pre><p>Mostly paraphrasing whet the_jester mentioned:</p> <ul> <li><p>Files in the same package (basically &#39;in the same folder&#39;) constitute <strong>one</strong> package. Go as a language attributes no meaning to source code files, only to packages. (Technically one may have kinda two packages in one folder, one for the actual package and one for the test, but this is uncommon).</p></li> <li><p>if you come from Javaland: Yes, stop thinking &#34;Object orientedly&#34; as the Java version of object orientation is useless, painful and completely unnecessary in Go. With Go you can have sensible and usable designs, no need to force it into Java-style OO.</p></li> <li><p>Things which are conceptually related belong into one package. If a package alone does not provide usable stuff (but requires other packages to be useful) than the package is too small. Take a look at the stdlibrary to get an idea.</p></li> <li><p>No, there is absolutely no notion of inheritance. Never, never ever think of inheritance if you program in Go. Never. Not even if someone comes up with embedding to &#34;model&#34; inheritance or &#34;do something alike&#34;. Don&#39;t. There isn&#39;t. You will get burnt if you do. So don&#39;t. Especially as there is no need for inheritance.</p></li> </ul></pre>weberc2: <pre><p>It&#39;s sad that &#34;Java-style OO&#34; is a thing given that Java supports &#34;Go-style OO&#34; (composition and interface polymorphism) just as readily as it supports inheritance. The Java folks just went all-in with inheritance before the rest of the world realized that inheritance is never the right tool for the job, and now it&#39;s baked into their standard library and the overwhelming majority of third-party libraries.</p> <blockquote> <p>No, there is absolutely no notion of inheritance. Never, never ever think of inheritance <del>if you program in Go</del>. Never. Not even if someone comes up with embedding to &#34;model&#34; inheritance or &#34;do something alike&#34;. Don&#39;t. There isn&#39;t. You will get burnt if you do. So don&#39;t. Especially as there is no need for inheritance.</p> </blockquote> <p>FTFY</p></pre>geodel: <pre><p>FWIW after learning Go I wrote a tool in Java which is Go like in spirit and proving to be very useful in my day work. Though it is very crude by Java &#39;design patterns&#39; standard, I have never been happier about any of my Java code than this one.</p></pre>rr1pp3rr: <pre><p>This is just a tip that I noticed now that I&#39;ve been using Go professionally and personally for a couple of years, but I never see anyone talk about the language in this way.</p> <p>In addition to being object oriented and fairly low level with great concurrency support, Go is also at heart a stream-processing language.</p> <p>You&#39;ll notice this if you spend enough time poking around the stdlib. Most functions that work on byte data are written from the standpoint of a stream implementation.</p> <p>So, while its perfectly fine to, say, have a method that&#39;s like &#34;saveToFile&#34;, you might want to design your libraries in such a way that the saving mechanism is backed by a stream writer that simply takes a file as an io.Writer.</p> <p>This makes for a much more homogenous and efficient design, as these streams can be processed in chunks. This is important if you&#39;re working with a lot of data as you don&#39;t have to load it all into memory at once.</p> <p>Hope this helps with one little piece of the pie.</p></pre>bmurphy1976: <pre><p>Get your head fully wrapped around zero length channels. That&#39;s the key to unlocking the proper use of goroutines.</p></pre>thepciet: <pre><p>Use packages for code independent of your application (your &#39;package main&#39; code that glues everything). For example I would include specific HTTP handlers in main.</p> <p>Use interfaces to say &#34;this code can work with types implementing these behaviors or information.&#34; I think interfaces can implement a superset of inheritance: one piece of code can apply to many types.</p> <p>Those standard object oriented patterns may lead to trouble in Go. I&#39;d just suggest keeping an open mind and make a bunch of stuff.</p></pre>weberc2: <pre><blockquote> <p>Should I stop thinking &#34;Object orientedly&#34;? Is there any form of inheritance?</p> </blockquote> <p>No, you should not stop thinking &#34;object orientedly&#34;; however, you should completely forget about inheritance (in every programming language). Inheritance was a mistake from the start, and it requires all sorts of hokey hacks to make it solve problems that composition + interface polymorphism solve naturally (for example, late-bound <code>this</code>, <code>protected</code> members, and subtype polymorphism). Moreover, anywhere you use inheritance, you could easily use composition and interfaces. All of this applies in any language that supports interfaces and composition (like Java); however, Go supports composition and interface polymorphism by default, and if you omit the name of the inner object, the compiler will allow you to delegate to the inner class automatically:</p> <pre><code>type HasMethod struct {} func (hm HasMethod) Do() { ... } type UsesMethod struct { HasMethod // anonymous struct member } // this is valid even though there is no explicit `Do()` declared on // `UsesMethod` UsesMethod{HasMethod{}}.Do() </code></pre> <blockquote> <p>When should I split things up into different packages</p> </blockquote> <p>Split whenever you think you have something worth reusing. Different people have different ideas about what is worth reusing; I prefer more fine-grained packages to fewer large packages, for example.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

523 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传