I want to replicate the following Java code in Golang in the most idiomatic way possible:
public class Handler {
private Storage storage;
private Mapper mapper;
public Handler(Storage storage, Mapper mapper) {
this.storage = storage;
this.mapper = mapper;
}
public void handleKey(String k) {
storage.put(k, mapper.map(k));
}
}
interface Storage {
public void put(String k, String v);
public String get(String k);
}
@FunctionalInterface
interface Mapper {
public String map(String a);
}
private static class InMemoryStorage implements Storage {
private Map<String, String> table;
public InMemoryStorage() {
table = new HashMap<>();
}
public void put(String k, String v) {
table.put(k, v);
}
public String get(String k) {
return table.get(k);
}
}
Handler
class only exposes the method handleKey
. The behaviour of this class is parametrized by passing different concrete Storage
and Mapper
implementations.
After reading Effective Go - Embedding, I thought this would be a good use of embedding interfaces intro structs. But I can't figure out how to avoid exposing the embedded interfaces' methods to Handler
users. I can do something like
type Handler struct {
store Storage
mapper Mapper
}
func (h Handler) Handle(k string) {
h.store.Put(k, h.mapper.Map(k))
}
type Storage interface {
Put(k string, v string)
Get(k string) string
}
type Mapper interface {
Map(k string) string
}
type inMemoryStorage {
table map[string]string
}
func NewInMemoryStorage() Storage {
return &inMemoryStore{table: make(map[string]string)}
}
but then I cannot pass concrete implementations to the Handler
(creating struct literal) because store
and mapper
are unexported. And I do not want to create factory methods for each possible combination... Any suggestions?
Aucun commentaire:
Enregistrer un commentaire