{"id":18702,"date":"2017-09-18T13:24:18","date_gmt":"2017-09-18T10:24:18","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=18702"},"modified":"2017-09-26T11:13:04","modified_gmt":"2017-09-26T08:13:04","slug":"three-productive-go-patterns-put-radar","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/","title":{"rendered":"Three Productive Go Patterns to Put on Your Radar"},"content":{"rendered":"<p><span style=\"font-size: 20px;\">Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. <a href=\"https:\/\/www.appdynamics.com\/lp\/guided-tour-application-performance-management\/?utm_source=javacodegeeks&#038;utm_medium=sponsorship&#038;utm_campaign=sponsored%20post%20jcg&#038;utm_content=three%20productive%20go%20patterns%20to%20put%20on%20your%20radar%20blog&#038;utm_term=three%20productive%20go%20patterns%20to%20put%20on%20your%20radar%20blog%20jcg%20sponsorship&#038;utm_budget=digital\">Take the AppDynamics APM Guided Tour!<\/a><\/span><\/p>\n<p>By most definitions, with just 26 keywords, a terse spec, and a commitment to orthogonal features,\u00a0<a href=\"https:\/\/golang.org\/\">Go<\/a><a href=\"https:\/\/golang.org\/\" target=\"_blank\" rel=\"noopener\">\u00a0is a simple language<\/a>. Go programmers are expected to use the basic building blocks offered by the language to compose more complex abstractions.<\/p>\n<p>Over time, best-in-class solutions to frequently encountered problems tend to be discovered, shared, and replicated. These design patterns draw heritage from other languages, but often look and feel distinct in Go. I\u2019d like to cast a spotlight on three patterns I use over and over again.<\/p>\n<h2><strong>The Dependency Injection<\/strong> Pattern<\/h2>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-001.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-68911\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-001.jpg\" alt=\"\" width=\"860\" height=\"1214\" \/><\/a><\/p>\n<p>Dependency injection (DI) is actually an umbrella term that can mean vastly different things depending on context. The core idea is this: Give or inject dependencies to a component, rather than have the component take dependencies from the environment. Beyond that, things can get a little complicated. Some people use DI to refer to dependency injection frameworks, typically a package or object into which you register dependencies and later inject them into components that use them, usually by some key schema. But this style of DI isn\u2019t a good match for Go, primarily because Go lacks the dynamic typing required to serve a literate API. Most DI frameworks in Go resort to stringly typed keys (meaning variables are often typed as strings), and rely on reflection to reify the dependencies to concrete types or interfaces, which is always a red flag.<\/p>\n<p>Instead, a more basic version of DI is particularly well-suited to Go programs. The inspiration comes from functional programming, specifically, the idea of closure scoping. And it\u2019s nothing special, really: Just provide all the dependencies to a component as line items in the component\u2019s constructor.<\/p>\n<pre class=\"brush:js\">\r\n\/\/ NewHandler constructs and returns a useable request handler.\r\nfunc NewHandler(\r\n\r\n\tdb *sql.DB,\r\n\trequestDuration *metrics.Histogram,\r\n\tlogger *log.Logger,\r\n\r\n\t) *Handler {\r\n\r\n\treturn &amp;Handler{\r\n\t\tdb:     db,\r\n\t\tdur:    requestDuration,\r\n\t\tlogger: logger,\r\n\t}\r\n\r\n}\r\n<\/pre>\n<p>The clear consequence of this pattern is that constructors begin to get very long, especially as business capability grows. That\u2019s a cost. But there\u2019s also a notable benefit. Namely, there\u2019s great virtue in making dependencies explicit at the callsite, especially to future readers and maintainers of your code. It\u2019s immediately obvious that the Handler takes and uses a database, a histogram, and a logger. There\u2019s no need to hunt down dependency relationships far from the site of construction.<\/p>\n<p>The writer pays a cost of keystrokes, but the reader receives the benefit of comprehension. Outside of hobby projects, we know that code is read far more often than it is written. It\u2019s reasonable, then, to optimize for the benefit of reader\u2014even if it comes at some expense to the writer. But we have some tricks up our sleeve to make long constructors for large components more tractable.<\/p>\n<p>One approach is to use a tightly scoped config struct, containing only those dependencies used by the specific component. It\u2019s typical to omit individual fields when building a struct, so constructors should detect nils, when appropriate, and provide sane default alternatives.<\/p>\n<pre class=\"brush:js\">\r\n\/\/ NewHandler constructs and returns a useable request handler.\r\nfunc NewHandler(c HandlerConfig) *Handler {\r\n\r\n\tif c.RequestDuration == nil {\r\n\t\tc.RequestDuration = metrics.NewNopHistogram()\r\n\t}\r\n\r\n\tif c.Logger == nil {\r\n\t\tc.Logger = log.NewNopLogger()\r\n\t}\r\n\r\n\treturn &amp;Handler{\r\n\t\tdb:     c.DB,\r\n\t\tdur:    c.RequestDuration,\r\n\t\tlogger: c.Logger,\r\n\t}\r\n\r\n}\r\n\r\n\/\/ HandlerConfig captures the dependencies used by the Handler.\r\n\r\ntype HandlerConfig struct {\r\n\r\n\t\/\/ DB is the backing SQL data store. Required.\r\n\r\n\tDB *sql.DB\r\n\r\n\t\/\/ RequestDuration will receive observations in seconds.\r\n\r\n\t\/\/ Optional; if nil, a no-op histogram will be used.\r\n\r\n\tRequestDuration *metrics.Histogram\r\n\r\n\t\/\/ Logger is used to log warnings unsuitable for clients.\r\n\r\n\t\/\/ Optional; if nil, a no-op logger will be used.\r\n\r\n\tLogger *log.Logger\r\n\r\n}<\/pre>\n<p>If a component has a few required dependencies and many optional dependencies, the functional options idiom may be a good fit.<\/p>\n<pre class=\"brush:js\">\r\n\/\/ NewHandler constructs and returns a useable request handler.\r\n\r\nfunc NewHandler(db *sql.DB, options ...HandlerOption) *Handler {\r\n\r\n\th := &amp;Handler{\r\n\r\n\tdb:     c.DB,\r\n\r\n\tdur:    metrics.NewNopHistogram(),\r\n\r\n\tlogger: log.NewNopLogger(),\r\n\r\n\t}\r\n\r\n\tfor _, option := range options {\r\n\r\n\toption(h)\r\n\r\n\t}\r\n\r\n\treturn h\r\n\r\n}\r\n\r\n\/\/ HandlerOption sets an option on the Handler.\r\n\r\ntype HandlerOption func(*Handler)\r\n\r\n\/\/ WithRequestDuration injects a histogram to receive observations in seconds.\r\n\r\n\/\/ By default, a no-op histogram will be used.\r\n\r\nfunc WithRequestDuration(dur *metrics.Histogram) HandlerOption {\r\n\treturn func(h *Handler) { h.dur = dur }\r\n}\r\n\r\n\/\/ WithLogger injects a logger to log warnings unsuitable for clients.\r\n\r\n\/\/ By default, a no-op logger will be used.\r\n\r\nfunc WithLogger(logger *log.Logger) HandlerOption {\r\n\r\n\treturn func(h *Handler) { h.logger = logger }\r\n\r\n}\r\n<\/pre>\n<p>By using this simplified DI pattern, we\u2019ve made the dependency graph explicit and avoided hiding dependencies in global state. It\u2019s also worth using a simplified definition of dependency\u2014that is, nothing more than something that a component uses to do its work. By this definition, loggers and metrics are clearly dependencies. So by extension, they should be treated identically to other dependencies. This can seem a bit awkward at first, especially when we\u2019re used to thinking of e.g. loggers as incidental or ubiquitous. But by lifting them up to the regular DI mechanism, we do more than establish a consistent language for expressing needs-a relationships. We\u2019ve made our components more testable by isolating them from the shared global environment. Good design patterns tend to have this effect\u2014not only improving the thing they\u2019re designed to improve, but also having positive knock-on effects throughout the program.<\/p>\n<h2><strong>The Client-Side<\/strong> Interface<strong> Pattern<\/strong><\/h2>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-002.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-68913\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-002.jpg\" alt=\"\" width=\"860\" height=\"1064\" \/><\/a><\/p>\n<p>Concretely, interfaces are nothing more than a collection of methods that types can choose to implement. But semantically, interfaces are much more. They define behavioral contracts between components in a system. Understanding interfaces as contracts helps us decide where and how to define them. And just as\u00a0<a href=\"https:\/\/thoughtworks.github.io\/pacto\/patterns\/cdc\/\" target=\"_blank\" rel=\"noopener\">contract testing<\/a>\u00a0in microservice architectures teaches us that the right place to write a contract is often with the consumer.<\/p>\n<p>Consider a package with a type. Go programmers frequently model that type and its constructor like the following.<\/p>\n<pre class=\"brush:js\">\r\npackage foo\r\n\r\n\/\/ widget is an unexported concrete type.\r\n\r\ntype widget struct{ \/* ... *\/ }\r\n\r\n\r\nfunc (w *widget) Bop(int) int                     { \/* ... *\/ }\r\n\r\nfunc (w *widget) Twist(string) ([]float64, error) { \/* ... *\/ }\r\n\r\nfunc (w *widget) Pull() (string, error)           { \/* ... *\/ }\r\n\r\n\r\n\r\n\/\/ Widget is an exported interface.\r\n\r\ntype Widget interface {\r\n\r\n\tBop(int) int\r\n\r\n\tTwist(string) ([]float64, error)\r\n\r\n\tPull() (string, error)\r\n\r\n}\r\n\r\n\r\n\/\/ NewWidget constructor returns the interface.\r\nfunc NewWidget() Widget { \/* ... *\/ }\r\n<\/pre>\n<p>In our contract model of interfaces, this establishes the Widget contract alongside the type that implements it. But how can we predict which methods consumers actually want to use? Especially as the type grows functionality and our interface grows methods, we lose utility. <a href=\"https:\/\/go-proverbs.github.io\/\" target=\"_blank\" rel=\"noopener\">The bigger the interface, the weaker the abstraction<\/a>.<\/p>\n<p>Instead, consider having your constructors return concrete types and letting package consumers define their own interfaces as required. For example, consider a client that only needs to Bop a Widget.<\/p>\n<pre class=\"brush:js\">\r\n\r\nfunc main() {\r\n\r\n\tw := foo.NewWidget() \/\/ returns a concrete *foo.Widget\r\n\r\n\tprocess(w)           \/\/ takes a bopper, which *foo.Widget satisfies\r\n\r\n}\r\n\r\n\/\/ bopper models part of foo.Widget.\r\ntype bopper interface {\r\n\tBop(int) int\r\n}\r\n\r\n\r\nfunc process(b bopper) {\r\n\tprintln(b.Bop(123))\r\n}\r\n<\/pre>\n<p>The returned type is concrete, so all of its methods are available to the caller. The caller is free to narrow its scope of interest by capturing the interesting methods of Widget in an interface and using that interface locally. In so doing the caller defines a contract between itself and package foo: NewWidget should always produce something that I can Bop. And even better, that contract is enforced by the compiler. If NewWidget ever stops being Boppable, I\u2019ll see errors at build time.<\/p>\n<p>More icing on the cake: Testing the process function is now a lot easier, as we don\u2019t need to construct a real Widget. We just need to pass it something that can be Bopped\u2014probably a fake or mock struct, with predictable behavior. And this all aligns with the\u00a0<a href=\"https:\/\/github.com\/golang\/go\/wiki\/CodeReviewComments\" target=\"_blank\" rel=\"noopener\">Code Review Comments<\/a>\u00a0guidelines around\u00a0<a href=\"https:\/\/github.com\/golang\/go\/wiki\/CodeReviewComments#interfaces\" target=\"_blank\" rel=\"noopener\">interfaces<\/a>, which state that:<\/p>\n<p><em>Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values. The implementing package should return concrete (usually pointer or struct) types: that way, new methods can be added to implementations without requiring extensive refactoring.<\/em><\/p>\n<p>Sometimes there is a case for defining interfaces near to concrete types. For example, in the standard library,\u00a0<a href=\"https:\/\/golang.org\/pkg\/hash\" target=\"_blank\" rel=\"noopener\">package hash<\/a>\u00a0defines a\u00a0<a href=\"https:\/\/golang.org\/pkg\/hash\/#Hash\" target=\"_blank\" rel=\"noopener\">Hash interface<\/a>, which types in subsidiary packages implement. Although the interface is defined in the producer, the semantics are the same: a tightly scoped contract that the package commits to supporting. If your contract is similarly tightly scoped and satisfied by different types with different implementations, then it may make sense to include it alongside those implementations as a signal of intent to your consumers.<\/p>\n<h2><strong>The Actor<\/strong> Pattern<\/h2>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-003.jpg\"><img decoding=\"async\" class=\"aligncenter wp-image-68915\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-003.jpg\" alt=\"\" width=\"860\" height=\"1311\" \/><\/a><\/p>\n<p>Like dependency injection, the idea of the actor pattern can mean wildly different things to different people. But at the core, it\u2019s not much more than an autonomous component that receives input and probably produces output. In Go, we learned pretty early on that a great way to model an actor is as an infinitely looping function selecting on a block of channels. The goroutine acts as a synchronization point for state mutations in the actor, in effect making the loop body single threaded\u2014a huge win for clarity and comprehensibility. We typically name this function `run` or `loop` and define it as a method on a struct type that holds the channels.<\/p>\n<pre class=\"brush:js\">\r\ntype Actor struct {\r\n\r\neventc   chan Event\r\n\r\n\trequestc chan reqRes\r\n\r\n\tquitc    chan struct{}\r\n\r\n}\r\n\r\nfunc (a *Actor) loop() {\r\n\r\n\tfor {\r\n\r\n\t\tselect {\r\n\r\n\t\t\tcase e := &lt;-eventc:\r\n\r\n\t\t\ta.consumeEvent(e)\r\n\r\n\t\t\tcase r := &lt;-requestc:\r\n\r\n\t\t\tres, err := a.handleRequest(r.req)\r\n\r\n\t\t\tr.resc &lt;- resErr{res, err}\r\n\r\n\t\t\tcase &lt;-quitc:\r\n\r\n\t\t\treturn\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n<\/pre>\n<p>Finally, we push onto those channels in our exported methods, forming our public API, which is naturally goroutine-safe.<\/p>\n<pre class=\"brush:js\">\r\nfunc (a *Actor) SendEvent(e Event) {\r\n\r\n\ta.eventc &lt;- e\r\n\r\n}\r\n\r\nfunc (a *Actor) MakeRequest(r *Request) (*Response, error) {\r\n\r\n\tresc := make(chan resErr)\r\n\r\n\ta.requestc &lt;- reqRes{req: r, resc: resc}\r\n\r\n\tres := &lt;-resc\r\n\r\n\treturn res.res, res.err\r\n\r\n}\r\n\r\n\r\nfunc (a *Actor) Stop() {\r\n\r\n\tclose(a.quitc)\r\n\r\n}\r\n\r\n\r\ntype reqRes struct {\r\n\r\n\treq  *Request\r\n\r\n\tresc chan resErr\r\n\r\n}\r\n\r\n\r\ntype resErr struct {\r\n\r\n\tres *Response\r\n\r\n\terr error\r\n\r\n}\r\n<\/pre>\n<p>This works great in a lot of circumstances. But it does require us to define a unique channel per distinct public API method. It also makes things a little tricky when we need to return information to the caller. In this example, we use an intermediating `reqRes` type, with a response channel, but there are other possibilities.<\/p>\n<p>There is an interesting alternative. Rather than having one channel per method, we use a single channel of unadorned functions. In the loop method, we simply execute every function that arrives; the exported methods define their functionality inline.<\/p>\n<pre class=\"brush:js\">\r\ntype Actor struct {\r\n\r\nactionc chan func()\r\n\r\n\tquitc   chan struct{}\r\n\r\n}\r\n\r\n\r\nfunc (a *Actor) loop() {\r\n\r\n\tfor {\r\n\r\n\t\tselect {\r\n\r\n\t\t\tcase f := &lt;-actionc:\r\n\r\n\t\t\tf()\r\n\r\n\t\t\tcase &lt;-quitc:\r\n\r\n\t\t\treturn\r\n\r\n\t\t}\r\n\r\n\t}\r\n\r\n}\r\n\r\n\r\nfunc (a *Actor) SendEvent(e Event) {\r\n\r\n\ta.actionc &lt;- func() {\r\n\r\n\t\ta.consumeEvent(e)\r\n\r\n\t}\r\n\r\n}\r\n\r\nfunc (a *Actor) HandleRequest(r *Request) (res *Response, err error) {\r\n\r\n\tdone := make(chan struct{})\r\n\r\n\ta.actionc &lt;- func() {\r\n\r\n\t\tdefer close(done) \/\/ outer func shouldn't return before values are set\r\n\r\n\t\tres, err = a.handleRequest(r)\r\n\r\n\t}\r\n\r\n\t&lt;-done\r\n\r\n}\r\n<\/pre>\n<p>This style carries several advantages:<\/p>\n<ol>\n<li>There are fewer mechanical bits in the actor.<\/li>\n<li>We have much more freedom in the public API methods to return values to callers.<\/li>\n<li>Business logic is defined in the corresponding public API method, rather than hidden in an unexported loop method.<\/li>\n<\/ol>\n<h3><strong>Your Patterns<\/strong><\/h3>\n<p>The dependency injection, client-side interface, and actor patterns can improve your productivity, offer you more freedom, and optimize your programming. Rather than default to basic solutions, get creative and try out one or all of these three distinct Go patterns.<\/p>\n<p><span style=\"font-size: 20px;\">Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. <a href=\"https:\/\/www.appdynamics.com\/lp\/guided-tour-application-performance-management\/?utm_source=javacodegeeks&#038;utm_medium=sponsorship&#038;utm_campaign=sponsored%20post%20jcg&#038;utm_content=three%20productive%20go%20patterns%20to%20put%20on%20your%20radar%20blog&#038;utm_term=three%20productive%20go%20patterns%20to%20put%20on%20your%20radar%20blog%20jcg%20sponsorship&#038;utm_budget=digital\">Take the AppDynamics APM Guided Tour!<\/a><\/span><\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-embed.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-68916\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/09\/three-productive-go-patterns-to-put-on-your-radar-embed.jpg\" alt=\"\" width=\"327\" height=\"1600\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By most definitions, with just 26 keywords, a terse spec, and a commitment to orthogonal features,\u00a0Go\u00a0is a simple language. Go programmers are expected to use the basic building blocks offered by the language to &hellip;<\/p>\n","protected":false},"author":210,"featured_media":927,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-18702","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Three Productive Go Patterns to Put on Your Radar - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Three Productive Go Patterns to Put on Your Radar - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-09-18T10:24:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-09-26T08:13:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Appdynamics\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Appdynamics\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\"},\"author\":{\"name\":\"Appdynamics\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/8aea501dc1eafa1e3adaebe457e79b95\"},\"headline\":\"Three Productive Go Patterns to Put on Your Radar\",\"datePublished\":\"2017-09-18T10:24:18+00:00\",\"dateModified\":\"2017-09-26T08:13:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\"},\"wordCount\":1461,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\",\"name\":\"Three Productive Go Patterns to Put on Your Radar - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"datePublished\":\"2017-09-18T10:24:18+00:00\",\"dateModified\":\"2017-09-26T08:13:04+00:00\",\"description\":\"Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Three Productive Go Patterns to Put on Your Radar\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/8aea501dc1eafa1e3adaebe457e79b95\",\"name\":\"Appdynamics\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/54ee8ceba6da02df562bf9cd4c36a6b537c64d9752d8482878bdfc9813078bc2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/54ee8ceba6da02df562bf9cd4c36a6b537c64d9752d8482878bdfc9813078bc2?s=96&d=mm&r=g\",\"caption\":\"Appdynamics\"},\"description\":\"AppDynamics delivers real-time access to every aspect of your business and operational performance, so you can anticipate problems, resolve them automatically, and make smarter, more certain business decisions. Application Intelligence provides the business and operational insights into application performance, user experience and business impact of your software applications.\",\"sameAs\":[\"http:\/\/www.appdynamics.com\/\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/appdynamics\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Three Productive Go Patterns to Put on Your Radar - Web Code Geeks - 2026","description":"Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/","og_locale":"en_US","og_type":"article","og_title":"Three Productive Go Patterns to Put on Your Radar - Web Code Geeks - 2026","og_description":"Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-09-18T10:24:18+00:00","article_modified_time":"2017-09-26T08:13:04+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","type":"image\/jpeg"}],"author":"Appdynamics","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Appdynamics","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/"},"author":{"name":"Appdynamics","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/8aea501dc1eafa1e3adaebe457e79b95"},"headline":"Three Productive Go Patterns to Put on Your Radar","datePublished":"2017-09-18T10:24:18+00:00","dateModified":"2017-09-26T08:13:04+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/"},"wordCount":1461,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/","name":"Three Productive Go Patterns to Put on Your Radar - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","datePublished":"2017-09-18T10:24:18+00:00","dateModified":"2017-09-26T08:13:04+00:00","description":"Discover faster, more efficient performance monitoring with an enterprise APM product learning from your apps. Take the AppDynamics APM Guided Tour! By","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/three-productive-go-patterns-put-radar\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"Three Productive Go Patterns to Put on Your Radar"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/8aea501dc1eafa1e3adaebe457e79b95","name":"Appdynamics","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/54ee8ceba6da02df562bf9cd4c36a6b537c64d9752d8482878bdfc9813078bc2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/54ee8ceba6da02df562bf9cd4c36a6b537c64d9752d8482878bdfc9813078bc2?s=96&d=mm&r=g","caption":"Appdynamics"},"description":"AppDynamics delivers real-time access to every aspect of your business and operational performance, so you can anticipate problems, resolve them automatically, and make smarter, more certain business decisions. Application Intelligence provides the business and operational insights into application performance, user experience and business impact of your software applications.","sameAs":["http:\/\/www.appdynamics.com\/"],"url":"https:\/\/www.webcodegeeks.com\/author\/appdynamics\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/18702","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/210"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=18702"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/18702\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/927"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=18702"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=18702"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=18702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}