<p>Hi everybody! </p>
<p>I'm look for some feedback on a code I wrote as a practice. I'm trying to understand interfaces, embedding structs more by writing up the Gang of Four design patterns in Go. </p>
<p>This is my first one. I thought I'd put this here after I wrote all of them up, but I decided feedback would be massivly awesome as early as possible rather then later.</p>
<p>So, without further ado, here is the code => <a href="https://github.com/Skarlso/goprojects/blob/master/designpatterns/creational/abstractfactory/abstract.go" rel="nofollow">AbstractFactory in Go By Skarlso</a></p>
<p>And thank you very much for any kind of help!
Endless Thanks!</p>
<hr/>**评论:**<br/><br/>gngeorgiev: <pre><p>I don't know what the others would say but this seems waaay too complicated and over-abstracted. Go is designed to be a simple language where you do not get lost in infinite levels of inheritance etc. </p></pre>brokedown: <pre><p>This is probably the toughest part for me, getting those concepts out of my head and writing Go code that works like Go code should work. I've spent way more time than I should trying to work out a good way to share data in a way that's concurrently safe, when the Go answer <a href="https://blog.golang.org/share-memory-by-communicating" rel="nofollow">(and they tell you this, over and over, you just have to listen and accept it)</a> is to share through communication rather than sharing memory. Old habits die hard, and these habits are very very old.</p></pre>skarlso: <pre><p>I'm writing this stuff up to try and exercise Embedding and the usage of pointers and Interfaces really. </p>
<p>I do know, that it's hard to think in Go rather. :) I've been a Java / Ruby / Python guy for over 10 years now. Never wrote anything in C or in any system language. I like python and it's approach to things, but still, Go is very different. And I've been doing go for little over 3 months, maybe 4. :)</p></pre>brokedown: <pre><p>I've been using pointers and interfaces as infrequently as possible. They're both powerful constructs, but then so is (void *).</p>
<p>Where Go really comes into its own for me is concurrency. Channels aren't perfect, but they're by far my favorite method for moving data between threads.</p></pre>skarlso: <pre><p>Interesting point! I actually enjoy coding with interfaces and embedded structs. I have to first get comfortable with channels. :) I know how they are supposed to work, but when I see them used they never actually work how I think they would. :D And sometimes the syntax is just like => What the hell did I just read? Though, I want to get better with them, because I like how much power they have.</p></pre>brokedown: <pre><p>If you think about traditional OO, it's really about keeping your data and the functions that operate on them together. As soon as you add "concurrently" to that statement, channels turn it on its ear.</p>
<p>A simple example is if you have some shared state in the form of a slice. You can use a bunch of pointers and eventually add in mutexes for safe handling, but that get really complex really quickly.</p>
<p>Alternatively, you can fire off a goroutine that receives a struct {command, data, response channel} through a channel, that owns and operates on that data, and you can freely pass around that channel wherever it needs to go with the knowledge that it will always be handled safely.</p></pre>skarlso: <pre><p>That sounds pretty damn awesome man. I'm almost at the point in effective go where concurency comes along. I eagerly await that chapter. :)</p></pre>Ainar-G: <pre><p>One pattern that you should learn as quickly as possible is that you should put your runnable code to play.golang.org. Your code is <a href="http://play.golang.org/p/7IRDl3rmrH" rel="nofollow">http://play.golang.org/p/7IRDl3rmrH</a>. Now to the code:</p>
<ul>
<li><p><a href="https://golang.org/doc/effective_go.html#Getters" rel="nofollow">Getters don't start with <code>Get</code></a>.</p></li>
<li><p><code>CreateFile(fileName string) (bool, error)</code> - the bool is redundant. <code>nil</code> error is enough to signify success.</p></li>
<li><p>Your code mostly branches off when operations are successful (ok == true), while it's more idiomatic in Go to branch when something bad happened (ok == false) since there are usually more than one thing that can go wrong. This also prevents massive <code>if a { if b { if c { ... }}}</code> kinds of situations.</p></li>
<li><p>I don't quite get what this code is supposed to do, but I guess it's just an exercise, so it doesn't matter. This is not how we usually go in Go however.</p></li>
</ul></pre>skarlso: <pre><p>1: True. It should be called more sensible than GetX..
2: Again, true. I'll ammend it. Thanks!
3: Finger exercise. :) </p>
<p>Thank you!</p>
<p>I adjusted accordingly. Thanks for the review!! Much appreciated.</p></pre>egonelbre: <pre><p>Don't learn or write GoF Patterns -- read Alexander's "Timeless Way of Building" first... GoF missed the point with regards to patterns.</p>
<p>Otherwise, get rid of <code>Factory</code> and <code>GetFactory</code> and <code>Databases</code> and <code>FileSystems</code>, they aren't that useful.</p></pre>skarlso: <pre><p>True, they aren't. AbstractFactory is a very very interesting pattern. A simple factory most of the times is completely enough. Adding YET another abstraction above them truley is overkill. I completely agree on that point.</p>
<p>Cheers for the reference!! I put it into my toread bucket. :) </p>
<p>I'm reading effective go of course as well. Trying to learn the GO way of doing things. Also ordered The Go Programming Language book. So I'm hoping with much pratice and with the help of guys like you guys, I will eventually get better at this. :) </p>
<p>So, thanks!!</p></pre>drvd: <pre><p>Which real problem does this solve?</p>
<p>How can something like </p>
<pre><code>type Factory interface {
GetFactory() Factory
}
</code></pre>
<p>be used in a sensible way? All you can do with a Factory is get another Factory which only can be used to get a Factory...</p>
<p>An interface value which can be used in sensible ways only after type-asserting is good for <please explain here>. </p></pre>skarlso: <pre><p>Yeah, I was thinking about what to do with that because, like you said, it doesn't really add value at that point. It could just be anything. </p>
<p>I was trying to grasp the Abstract part of the pattern, which normally I actually would not do in Go EVER. :) </p>
<p>But, like I said, it's trying to be a finger exercise. However, thanks for pointing it out!!</p></pre>Fwippy: <pre><p>I wouldn't call <code>database := GetDatabase("mongo")</code> - I'd skip straight to <code>database := mongo.New()</code>. Then you just have to make sure that both <code>mongo.DB</code> and <code>zfs.DB</code> implement <code>Database</code>, and you're golden.</p>
<p>Of course, I'm sure that wouldn't satisfy the AbstractFactory pattern, but my point is, do it the simple way.</p></pre>skarlso: <pre><p>I agree with you a 100%!</p>
<p>But like you said, it would be an abstract factory, just a factory. :-) </p></pre>lambdaburrito: <pre><p>Mate, this is a really bad exercise to learn Go because these design patterns are work arounds a limited type system. I recall that one of the Go or Haskell language designers correctly pointed this out. It's great that you are learning another language but don't try to code these OO design patterns. I would recommend to develop a game because then you get a great opportunity to use interfaces, channels, structs, learn all the go tools and how to ship a product with Go.</p></pre>skarlso: <pre><p>Uuu, that's actually a very good advice right there. </p>
<p>I begun coding up a Web based rpg. But I know very little about the Web ecosystem, though it doesn't seem to be very complicated. It would save state through cookies and hashes. Sort of like cookie clicker. But I also though about some kind of a test based game. I'm terrible at graphics. </p>
<p>Thanks man! I shall take this advice to heart! </p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传