Access runtime config instance created in main func from another file, WITHOUT use of global var

xuanbao · · 720 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have a runtime config instance that I need in other parts of the app, but it can only be created in main(). Ideally I would like to avoid using global variables.</p> <pre><code>// main.go type RuntimeConfig struct { db *DatabaseInstance app_name string ... etc ... } func main() { dbInstance = ConnectToDB(...args) // returns *DatabaseInstance runtimeConfig := *Config{ dbInstance, &#34;My app&#34;, ... etc ... } } // elsewhere.go func SomeUtilityFuncThatNeedsRuntime(i int) int { runtime := GetRuntime() // imaginary, magical runtime getter db := runtime.DatabaseInstance appName := runtime.appName db.Save(appName, db, ...) return i + 1 } </code></pre> <p>Currently it&#39;s impossible to create anonymous util functions that could really benefit from having access to certain config variables. If the variables were basic types (like a string or int), I would probably just hard-code them in. However, a field like <code>dbInstance</code> requires a specific instance of a connected database.</p> <hr/>**评论:**<br/><br/>runyoucleverboyrun: <pre><p>Unless I&#39;m vastly misunderstanding, any function in your program eventually traces back to main, why not just pass the config instance to whatever functions need it? Maybe make those functions method on that config type.</p></pre>JackOhBlades: <pre><p>When you use global functions like that it obscures the function. The function should take in everything it depends on as a parameter. </p> <p>From my point of view: Configuration should be used only in the main package to create the initial objects and setup in the program. Configuration should not leak out of the main package. &#39;Configuration&#39; is not part of the domain of your software and should not be spread through different parts thereof. </p> <p>If you need a database connection, don&#39;t worry about where it came from, force it to be a parameter (or a field in a struct) so that you make the dependency explicit. </p> <p>If you keep applying that logic, it will bubble the initialisation of the connection up to the main package or a place that makes sense.</p> <p>If you do abuse global functions, make no mistake, just because it&#39;s not a parameter doesn&#39;t make it not a dependency. </p> <p>PS. If your app is tiny this will likely not matter. As it grows having explicit dependencies will help you reason about each unit of your program. </p> <p>The alternative is being forced to try reason about a single function in terms of 5 other functions because they all use the same global reference. This style turns into spaghetti one string of pasta at a time. </p></pre>neoasterisk: <pre><p>You could turn <code>SomeUtilityFuncThatNeedsRuntime</code> to a method of <code>RuntimeConfig</code>. That way it can easily have access to db. You can also go one step further and rename <code>RuntimeConfig</code> to <code>App</code> or something similar as it seems that it captures better what you are trying to do. Besides the struct already contains an <code>app_name</code> field (which frankly should be renamed to <code>appName</code> or potentially just <code>name</code>).</p></pre>jammerlt: <pre><p>Dependency injection. Use it.</p></pre>

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

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