Best way to have a global config

agolangf · · 1066 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>What is the best way to have a global config store accessible by any functions in the same package? Reading and parsing a json config isn&#39;t the issue here. The config is usually loaded and read from the main function but if I want to have any functions to read from this config without having the main function to pass down the config. </p> <p>I&#39;ve thought of having a global variable, but not sure if its the best way. In C/C++, I usually use a singleton. In other languages like PHP, I employ the dependency injection pattern.</p> <hr/>**评论:**<br/><br/>tjholowaychuk: <pre><p>IMO what you&#39;re trying to do could easily be considered an anti-pattern. I would personally either:</p> <ul> <li>pass config to some struct and reference it via the field(s)</li> <li>pass as little as possible to each function, don&#39;t assume entire config structs etc</li> </ul> <p>Usually going with the least amount of indirection possible leads to nicer implementations, but it sort of depends on the use-case a bit – though I&#39;d certainly stay away from global config.</p> <p>I try to do all &#34;bootstrapping&#34; of config in the &#39;main&#39; package, everything else simply becomes a package as if it were going to be open-sourced and used as such, rather than strictly designed as an application or CLI. </p></pre>peterbourgon: <pre><blockquote> <p>pass as little as possible to each function, don&#39;t assume entire config structs etc</p> </blockquote> <p>+1 to this. In general, the concept of a &#34;config&#34; should be bounded to the scope of your <code>func main</code>. Each of your components should take precisely the configuration they require as parameters, either </p> <ul> <li>directly — <code>func NewFoo(a int, b string)</code>, </li> <li>through <a href="http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis">the functional options idiom</a>, or</li> <li>through a config struct — <code>func NewFoo(opts FooOptions)</code>),</li> </ul> <p>in order of preference. There are probably circumstances where a global config struct is appropriate, but they&#39;re exceptional.</p></pre>anoobisus: <pre><p>This also, you know, makes it possible to test shit in a reasonable way too</p></pre>singron: <pre><p>I like to do something like this:</p> <pre><code>var Config struct { homedir string maxRefreshes int http struct { addr string basePath string } } </code></pre> <p>You can configure these however you want, but usually I have an init() function that uses the flag package.</p> <pre><code>func init() { flag.StringVar(&amp;Config.homedir, &#34;homedir&#34;, &#34;.&#34;, &#34;directory to use for stuff&#34;) // etc. } func main() { flag.Parse() http.ListenAndServe(Config.http.addr, ...) // or whatever } </code></pre> <p>There are a couple packages that will do this kind of thing a little more easily with struct tags and reflection, but it&#39;s essentially the same thing.</p></pre>ApatheticGodzilla: <pre><p>I do something similar, using environment variables.</p></pre>gureggu: <pre><p>I pass around a <code>x/net/context.Context</code> everywhere and shove the config inside of that. </p></pre>joeshaw: <pre><p>+1 to this. I recently moved a lot of globalish things here (config, <code>database.DB</code>, statsd client, S3 client, etc.) and the functions are much cleaner as a result. Because contexts are loosely coupled, it&#39;s still easy to construct contexts with only the things you need for tests.</p></pre>lhxtx: <pre><p>I just pass around a config struct. </p></pre>lethalman: <pre><p>Not have a global config. Pass it everywhere in any function. That makes your software easier to run, to embed, to reuse and to test.</p></pre>jerf: <pre><p>I use an <a href="http://www.jerf.org/iri/post/2929" rel="nofollow">environment object</a>, which turns out to work out pretty well because as you refine your system into objects that are having methods run on them, rather than passing them &#34;everywhere&#34; you often end up just passing them to &#34;a few places&#34;, then they end up available everywhere via the sort of natural struct embedding you&#39;d be doing anyhow. It&#39;s much more convenient than it sounds at first. Still harder than global variables, but much safer and more testable.</p></pre>axaxs: <pre><p>If it&#39;s a shared, static config, just use a global.</p></pre>

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

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