7 ms·
You're probably using Go in The Wrong Way®. It's hard to fit classical object oriented design patterns onto Go. A factory method that produces structs with dyna
by melvinmt 13y ago
You're probably using Go in The Wrong Way®. It's hard to fit classical object oriented design patterns onto Go. A factory method that produces structs with dynamic types is an example of that.
- stcredzero 13y agoAgreed. For most of what you'd use a Factory Method for, you can Duck Type your way out of the situation.
- vectorpush 13y agoI created this contrived example to illustrate the basic idea behind the pattern I want to emulate. http://play.golang.org/p/7T2s8Dn0Sr http://play.golang.org/p/7T2s8Dn0Sr Ideally, on line 57 I'd pass in some kind of "first class" type representation that the switch statement could use to branch into the correct type, rather than a zeroed (or not, Go doesn't care) struct or a string. Admittedly, this could definitely be abuse of Go semantics, so I'm also interested in how I could refactor this into a more canonical Go pattern.
- melvinmt 13y agoWell, at line 57 you already know which provider you want to use, so why not just initialize the struct from there and skip the factory method altogether. http://play.golang.org/p/vXJcMJ-j6P http://play.golang.org/p/vXJcMJ-j6P Edit: I think I see what you're trying to do with the factory method. You're trying to enforce the ServiceProvider interface on every provider struct. You don't need to do that yourself, the compiler does that work for you. On line 57, you already know what kind of struct you're dealing with so you can safely call .connect() on the provider. And if you need to pass on the provider to another method, just make sure the method only accepts structs with a ServiceProvider interface. The compiler will stop you when it's not the case.
- vectorpush 13y agoI was in a rush and didn't create the most illustrative example. you already know which provider you want to use, so why not just initialize the struct from there and skip the factory method altogether. The reason that I want ProviderFactory to generate instances is because I also want it to act as a manager for those instances. ProviderFactory can keep track of all ServiceProviders and perform various operations or broker data between instances. Here is my previous example slightly improved. http://play.golang.org/p/XoXu9x9r8f http://play.golang.org/p/XoXu9x9r8f Now, ProviderFactory injects configuration information into ServiceProvider instances based on their concrete type, before establishing a connection. A more complicated app might wrap the NewProvider function into a gorotune/callback that blocks each provider instantiation until a successful connection has been established. This is all beside the point though; all I want is something akin to a special "type" type that the compiler recognizes as a symbol for that type that the factory can use to evaluate which concrete type to produce.
- rakoo 13y agoYou're still leaning too much in types. Go is a very lightweight type system. The setter and base type basically scream for "I want to use my Java in Go". I'm not even talking about using a factory. Here's I would do it: http://play.golang.org/p/EmxCRkDNLC http://play.golang.org/p/EmxCRkDNLC
- NateDad 13y agoYour code seems incredibly backward. Why does the ProviderFactory hold the knowledge about the query interval for each provider? Shouldn't the provider hold that information? With the data structure you have, any time you add a new provider, you'd need to add a new case to that switch statement. That's like the polar opposite of separation of concerns. Let the query interval be defined on the type, not in the factory. The same for the host they connect to. Shouldn't that be defined in the type? Like make WeatherProvider.Connect() call ProviderFactory.WeatherHost() to get the host to connect to. You're doing everything inside out. What do the types even do in your example? This isn't a Go problem, it's programmer problem.
- vectorpush 13y ago