Idea about Servicer/Storager init logic

The original Idea is Service/Storage Config Support · Issue #723 · beyondstorage/go-storage · GitHub

Here is a more detailed opinion.

We can introduce the following interfaces:

type Schema struct {
	StorageConfigFactory NewStorageConfigFunc
	ServiceConfigFactory NewServiceConfigFunc

type ConfigUnmarshalFunc func(c Configer) error

type Configer interface {
	FromString(conn string) error
	FromPairs(ps ...types.Pair) error
	FromMap(m map[string]interface{}) error
	FromUnmarshal(fn ConfigUnmarshalFunc) error

type NewServiceConfigFunc func() ServiceConfiger
type NewStorageConfigFunc func() StorageConfiger

type ServiceConfiger interface {

	NewServicer() (types.Servicer, error)

type StorageConfiger interface {

	NewStorager() (types.Storager, error)

definitions can generate the whole Configer implemetations for services. And service only need to implement NewServicer and NewStorager.

After this change, we can have unified export functions like:

NewStorager(ps ...Pairs) (Storager, error) // Keep the name not changed
NewStoragerFromString(conn string) (Storager, error) // the connection string support
NewStoragerFromMap(m map[string]interface{}) (Storager, error) // Load config from a map.
NewStoragerFromUnmarshal(fn ConfigUnmarshalFunc) (Storager, error) // Load config from json/toml unmarshal directly

All application could use go-storage more easily!